node.js 使用 webpack-dev-server 运行节点快速服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35233291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running a node express server using webpack-dev-server
提问by ?yvind Br?then
I'm using webpack to run my react frontend successfully using the following config:
我正在使用 webpack 使用以下配置成功运行我的反应前端:
{
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']
}
}
]
}
}
I'm trying to put up a node.js express backend as well, and would like to run that through webpack as well, so that I have a single server running both the backend and frontend, and because I want to use babel to transpile my javascript.
我也在尝试建立一个 node.js express 后端,并且也想通过 webpack 运行它,这样我就有一个同时运行后端和前端的服务器,并且因为我想使用 babel 进行编译我的 JavaScript。
I made a quick testserver looking like this:
我做了一个像这样的快速测试服务器:
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');
});
If I run this with node index.jsand open my browser on localhost:3000it prints "Hello world from Express!!". So far so good. Then I tried creating a web-pack config for it:
如果我运行它node index.js并打开我的浏览器,localhost:3000它会打印“Hello world from Express!!”。到现在为止还挺好。然后我尝试为它创建一个 web-pack 配置:
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'
}
]
}
}
When I run the command webpack-dev-serverit starts up successfully (it seems). However, if I go to my browser on localhost:3000now, it just says that the webpage is not available, just as when the server is not running at all.
当我运行命令时,webpack-dev-server它成功启动(似乎)。但是,如果我现在打开浏览器localhost:3000,它只会说该网页不可用,就像服务器根本没有运行一样。
I'm very new to both node and webpack, so either I have made a small mistake somewhere, or I'm way off ;)
我对 node 和 webpack 都很陌生,所以要么我在某个地方犯了一个小错误,要么我离题了 ;)
回答by perilandmishap
Webpack-dev-server is great for client side development but it will not deploy Express api's or middleware. So in development I recommend running two separate servers: One for the client and one for your server side api's.
Webpack-dev-server 非常适合客户端开发,但它不会部署 Express api 或中间件。所以在开发过程中,我建议运行两台独立的服务器:一台用于客户端,另一台用于服务器端 api。
Nodemon npm install --save-dev nodemonis a good backend development server that will give you hot-redeploy of your api's, or you can just use express and restart when you make changes. In production the client and api will still be served by the same express server.
Nodemonnpm install --save-dev nodemon是一个很好的后端开发服务器,它可以让您热重新部署 api,或者您可以在进行更改时使用 express 并重新启动。在生产中,客户端和 api 仍将由同一个快速服务器提供服务。
Set a lifecycle event for both nodemon and webpack-dev-server in your package.jsonto make starting them easy (example: npm run dev-server).
在您的 nodemon 和 webpack-dev-server 中设置生命周期事件,package.json以便轻松启动它们(例如:)npm run dev-server。
"scripts": {
"start": "webpack --progress --colors",
"dev-server": "nodemon ./server.js localhost 8080",
"dev-client": "webpack-dev-server --port 3000",
}
Or, to run express directly from node:
或者,直接从节点运行 express:
"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');
});
Note: The api server must use a different port than webpack-dev-server.
注意:api 服务器必须使用与 webpack-dev-server 不同的端口。
And finally in your webpack-dev-config you need to use a proxy to redirect calls to your api to the new port:
最后,在您的 webpack-dev-config 中,您需要使用代理将调用重定向到您的 api 到新端口:
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
})
]
**Bonus points for having a single script to start and kill both
**拥有一个脚本来启动和终止两者的奖励积分
回答by Shawn Wang
Since webpack-dev-serveris just a tiny express server with compile on change and hot reload.
由于webpack-dev-server只是一个带有更改和热重载编译的小型快速服务器。
So, if you already got a express server for backend API, just merge the compile on change and hot reloadinto your express server.
因此,如果您已经有后端 API 的快速服务器,只需将其合并compile on change and hot reload到您的快速服务器中即可。
Then after take a look at the package.jsonof webpack-dev-server, i find the key is just
webpack-dev-middleware
再看看在后package.json的的WebPack-dev的服务器,我觉得关键是刚刚
的WebPack-DEV-中间件
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!'))
So, when you run your BE server, it will compile all the things using webpack, and watch for changes, LOL ~
所以,当你运行你的 BE 服务器时,它会使用 webpack 编译所有东西,并观察变化,哈哈~
Also, add webpack-hot-middlewarefor hot reloading function, see Hot Module Replacement
另外,添加webpack-hot-middleware以实现热重载功能,参见热模块更换
回答by booleanhunter
From your questions here and here, it appears that you are using ReactJS with ES6. I faced the exact same issue, and here is how I tackled it -
从您在此处和此处的问题来看,您似乎正在将 ReactJS 与 ES6 一起使用。我遇到了完全相同的问题,这是我解决它的方法-
Have multiple entry points for your application
为您的应用程序提供多个入口点
In particular you can put all your vendor files like JQuery, React etc into one chunk. This way, your vendor files will remain the same even when you modify your souce files. You can add this line to your webpack config
特别是,您可以将所有供应商文件(如 JQuery、React 等)放在一个块中。这样,即使您修改源文件,您的供应商文件也将保持不变。您可以将此行添加到您的 webpack 配置中
entry: {
vendors: ['react','reactDom','jquery'] //Any other libraries
}
Use the CommonsChunkPluginto have webpack determine what code/modules you use the most, and put it in a separate bundle to be used anywhere in your application.
使用CommonsChunkPlugin来让 webpack 确定您最常使用的代码/模块,并将其放在一个单独的包中,以便在您的应用程序中的任何地方使用。
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendors', 'dist/js/vendors.js', Infinity),
]
Use React Hot Loader
使用 React 热加载器
Run npm install react-hot-loader --save-dev. Make sure you have installed webpack-dev-serverfirst.
运行npm install react-hot-loader --save-dev。确保您已webpack-dev-server先安装。
Then you need to change your loaders to this -
然后你需要把你的装载机改成这个 -
loaders: [
{
test: /\.jsx?$/,
loaders: ['react-hot'],
include: path.join(__dirname, 'public')
},{
loader: 'babel',
query: {
presets: ['react', 'es2015']
},
include: path.join(__dirname, 'public')
},
]
Make sure React Hot Loader comes before Babel in the loaders array. Also make sure you have include: path.join(__dirname, 'public')to avoid processing node_modules, or you may get an error like this -
确保 React Hot Loader 在 loaders 数组中出现在 Babel 之前。还要确保您必须include: path.join(__dirname, 'public')避免处理 node_modules,否则您可能会收到这样的错误 -
Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined
Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined
Modifications to your script tags in your
index.htmlpage
对
index.html页面中脚本标签的修改
If your html has something like this -
如果你的 html 有这样的东西 -
<script src="/dist/js/vendors.js"></script>
<script src="/dist/js/app.bundle.js"></script>
Change this to point to your webpack-dev-server 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>
Run
webpack-dev-server --hot --inline,
运行
webpack-dev-server --hot --inline,
wait for the bundling to finish, then hit http://localhost:3000(your express server port) in your browser.
等待捆绑完成,然后在浏览器中点击http://localhost:3000(您的快速服务器端口)。
If you run into any errors, you could find this troubleshooting guidevery useful.
如果您遇到任何错误,您会发现此故障排除指南非常有用。
Hope this helps, and you can take a look at the webpack setup for my project here
希望这会有所帮助,您可以在此处查看我项目的 webpack 设置
回答by WilDrow
Just faced the same issue and came with another solution (found out more information about it later, but here it is).
刚刚遇到了同样的问题,并提出了另一个解决方案(稍后找到了有关它的更多信息,但在这里)。
Instead of using the webpack-dev-server, use the webpack --watchcommand so files are compiled again upon changes. Once the files are updated on the dist (or any other compiled files folder) you can set to run the nodemon on the dist folder and watch only the dist files.
不要使用 webpack-dev-server,而是使用该webpack --watch命令,以便在更改时再次编译文件。一旦文件在 dist(或任何其他编译文件文件夹)上更新,您可以设置在 dist 文件夹上运行 nodemon 并仅查看 dist 文件。
This way it is possible to have the express server running and serving the front-end as you would in a production environment (or kinda) and benefit from the fast reloads.
通过这种方式,可以像在生产环境(或某种)中一样运行快速服务器并为前端提供服务,并从快速重新加载中受益。
Here's a linkwith some solutions to combine the webpack watch and nodemon.
这是结合 webpack watch 和 nodemon 的一些解决方案的链接。
My scripts section is something like this at this moment (I'm using the run-all solution):
我的脚本部分此时是这样的(我正在使用运行所有解决方案):
"scripts": {
"serve": "npm-run-all --parallel serve:webpack serve:nodemon",
"serve:webpack": "webpack --progress --colors --watch",
"serve:nodemon": "nodemon ./dist/app.js --watch dist"
},

