open development dev node.js express webpack webpack-dev-server

node.js - development - Ejecutar un servidor express de nodo usando webpack-dev-server



webpack-dev-server npm (3)

Estoy usando webpack para ejecutar mi interfaz de reacción con éxito usando la siguiente configuración:

{ name: ''client'', entry: ''./scripts/main.js'', output: { path: __dirname, filename: ''bundle.js'' }, module: { loaders: [ { test: /.jsx?$/, loader: ''babel-loader'', exclude: /node_modules/, query:{ presets: [''es2015'', ''react'', ''stage-2''] } } ] } }

Estoy tratando de instalar un backend express de node.js también, y me gustaría ejecutarlo también a través de webpack, de modo que tenga un solo servidor que ejecute tanto el backend como el frontend, y porque quiero usar babel para transpilar mi javascript

Hice un servidor de prueba rápido con este aspecto:

var express = require(''express''); console.log(''test''); var app = express(); app.get(''/'', function(req, res){ res.send("Hello world from Express!!"); }); app.listen(3000, function(){ console.log(''Example app listening on port 3000''); });

Si ejecuto esto con el node index.js y abro mi navegador en localhost:3000 , imprime "¡Hola mundo desde Express!". Hasta ahora tan bueno. Luego intenté crear una configuración de paquete web para ello:

var fs = require(''fs''); var nodeModules = {}; fs.readdirSync(''node_modules'') .filter(function(x) { return [''.bin''].indexOf(x) === -1; }) .forEach(function(mod) { nodeModules[mod] = ''commonjs '' + mod; }); module.exports = [ { name: ''server'', target: ''node'', entry: ''./index.js'', output: { path: __dirname, filename: ''bundle.js'' }, externals: nodeModules, module: { loaders: [ { test: //.js$/, loaders: [ ''babel-loader'' ] }, { test: //.json$/, loader: ''json-loader'' } ] } }

Cuando ejecuto el comando webpack-dev-server se inicia con éxito (parece). Sin embargo, si voy a mi navegador en localhost:3000 ahora, solo dice que la página web no está disponible, como cuando el servidor no se está ejecutando en absoluto.

Soy muy nuevo tanto en el nodo como en el paquete web, por lo que cometí un pequeño error en alguna parte o estoy muy lejos;)


Dado que webpack-dev-server es solo un pequeño servidor express con compilación en cambio y recarga en caliente.

Entonces, si ya tiene un servidor express para la API de back-end, simplemente combine la compile on change and hot reload a compile on change and hot reload en compile on change and hot reload en su servidor express.

Luego, después de echar un vistazo al package.json de webpack-dev-server , encuentro que la clave es solo webpack-dev-middleware

const express = require(''express''); //your original BE server const app = express(); const webpack = require(''webpack''); const middleware = require(''webpack-dev-middleware''); //webpack hot reloading middleware const compiler = webpack({ .. webpack options .. }); //move your `devServer` config from `webpack.config.js` app.use(middleware(compiler, { // webpack-dev-middleware options })); app.listen(3000, () => console.log(''Example app listening on port 3000!''))

Entonces, cuando ejecutas tu servidor BE, compilará todas las cosas usando el paquete web y observará los cambios, LOL ~

Además, agregue webpack-hot-middleware para la función de recarga en caliente, vea Reemplazo de módulo caliente


De sus preguntas aquí y here , parece que está usando ReactJS con ES6. Me enfrenté exactamente al mismo problema, y ​​así es como lo aborde:

  1. Tener múltiples puntos de entrada para su aplicación

En particular, puede poner todos sus archivos de proveedor como JQuery, React, etc. en un solo fragmento. De esta manera, los archivos de su proveedor permanecerán iguales incluso cuando modifique sus archivos de origen. Puede agregar esta línea a la configuración de su paquete web

entry: { vendors: [''react'',''reactDom'',''jquery''] //Any other libraries }

Use CommonsChunkPlugin para que el paquete web determine qué código / módulos usa más y colóquelo en un paquete separado para usar en cualquier parte de su aplicación.

plugins: [ new webpack.optimize.CommonsChunkPlugin(''vendors'', ''dist/js/vendors.js'', Infinity), ]

  1. Utilice React Hot Loader

Ejecute npm install react-hot-loader --save-dev . Asegúrese de haber instalado webpack-dev-server .

Entonces necesita cambiar sus cargadores a esto:

loaders: [ { test: //.jsx?$/, loaders: [''react-hot''], include: path.join(__dirname, ''public'') },{ loader: ''babel'', query: { presets: [''react'', ''es2015''] }, include: path.join(__dirname, ''public'') }, ]

Asegúrese de que React Hot Loader aparezca antes que Babel en la matriz de cargadores. También asegúrese de include: path.join(__dirname, ''public'') para evitar el procesamiento de node_modules, o puede obtener un error como este:

Uncaught TypeError: Cannot read property ''NODE_ENV'' of undefined

  1. Modificaciones a sus etiquetas de script en su página index.html

Si tu html tiene algo como esto:

<script src="/dist/js/vendors.js"></script> <script src="/dist/js/app.bundle.js"></script>

Cambie esto para apuntar a su proxy webpack-dev-server -

<script src="http://localhost:8080/dist/js/vendors.js"></script> <script src="http://localhost:8080/dist/js/app.bundle.js"></script>

  1. Ejecute webpack-dev-server --hot --inline ,

espere a que termine la agrupación, luego presione http: // localhost: 3000 (el puerto de su servidor express) en su navegador.

Si encuentra algún error, puede encontrar esta guía de solución de problemas muy útil.

Espero que esto ayude, y puedes echar un vistazo a la configuración del paquete web para mi proyecto here


Webpack-dev-server es ideal para el desarrollo del lado del cliente, pero no implementará la API o el middleware de Express. Entonces, en desarrollo, recomiendo ejecutar dos servidores separados: uno para el cliente y otro para la API del lado del servidor.

Nodemon npm install --save-dev nodemon es un buen servidor de desarrollo de back-end que le dará una nueva npm install --save-dev nodemon caliente de su API, o puede usar express y reiniciar cuando realice cambios. En producción, el cliente y la API seguirán siendo atendidos por el mismo servidor express.

Establezca un evento de ciclo de vida tanto para nodemon como para webpack-dev-server en su package.json para facilitar el inicio (ejemplo: npm run dev-server ).

"scripts": { "start": "webpack --progress --colors", "dev-server": "nodemon ./server.js localhost 8080", "dev-client": "webpack-dev-server --port 3000", }

O, para ejecutar express directamente desde el nodo:

"scripts": { "start": "webpack --progress --colors", "dev-server": "node dev-server.js", "dev-client": "webpack-dev-server --port 3000", }

// dev-server.js const express = require(''express''); const app = express(); // Import routes require(''./_routes'')(app); // <-- or whatever you do to include your API endpoints and middleware app.set(''port'', 8080); app.listen(app.get(''port''), function() { console.log(''Node App Started''); });

Nota: El servidor api debe usar un puerto diferente que webpack-dev-server.

Y, finalmente, en su webpack-dev-config necesita usar un proxy para redirigir las llamadas a su API al nuevo puerto:

devServer: { historyApiFallback: true, hot: true, inline: true, host: ''localhost'', // Defaults to `localhost` port: 3000, // Defaults to 8080 proxy: { ''^/api/*'': { target: ''http://localhost:8080/api/'', secure: false } } }, // and separately, in your plugins section plugins: [ new webpack.HotModuleReplacementPlugin({ multiStep: true }) ]

** Puntos de bonificación por tener un solo script para iniciar y matar a ambos