如何让 Webpack 和 Node 协同工作?
How to make Webpack and Node work together?
我打算在前端使用 ES6 模块,所以我在 Webpack 上做了实验。但是,我很难使 ff: work
- 客户端有变化时热重载
- 当服务器端发生变化时热重载(在 webpack 之前,我使用
nodemon .
并且没有问题)
- 终端中丢失 debug/console.log 信息,因为它正在打印 webpack 状态,而服务器上没有任何内容,例如我的自定义 'Server running....' 日志。
下面的设置我试图通过 npm start
运行。每次我做出任何改变,我都必须 运行 npm start
再
package.json
{
"name": "socket-io-chat",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "npm run build",
"build": "webpack -d && webpack-dev-server --hot --inline --watch && node --watch",
"build:prod": "webpack -p && webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.7.1",
"express": "*",
"socket.io": "*"
},
"devDependencies": {
"babel-core": "^6.14.0",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.14.0",
"babel-preset-stage-2": "^6.13.0",
"nodemon": "^1.10.2",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.15.1"
}
}
webpack.config.js
var path = require("path");
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var SRC_DIR = path.join(__dirname, "public");
var DIST_DIR = path.join(__dirname, "public/js/dist");
var config = {
context: __dirname,
devtool: debug ? "inline-sourcemap" : null,
entry: {
guest : path.join(SRC_DIR, "entry-guest.js"),
authenticated : path.join(SRC_DIR, "entry-authenticated.js")
},
output: {
path: DIST_DIR,
filename: "[name].js"
},
modules: {
loaders: [
{
test: /\.js?/,
include: SRC_DIR,
loader: "babel-loader",
query: {
presets: ["es2015", "stage-2"]
}
}
]
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
devServer: {
https: false,
contentBase: SRC_DIR,
stats: 'errors-only',
port: 3000
}
};
module.exports = config;
server.js
//create server
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
console.log('here');
var server = require('http').createServer(app);
//prepare socket io, make it listen to server
var io = require('socket.io').listen(server);
users = [];
connections = [];
var port = process.env.PORT || 3000;
server.listen(port);
console.log(`Server running *:${port}`);
//routing
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
//open a connection
io.sockets.on('connection', function(socket) {
connections.push(socket);
console.log('Connected: %s sockets connected:', connections.length);
//...more codes here
});
在您的 webpack 配置文件中,您可以尝试使用插件 "Hot Module Replacement"
除了已经实现的 Nodemon 之外,您还应该让客户端和服务器根据更改重新加载。
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
],
这是一个使用 HotModuleReplacement 的 webpack 配置示例。
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3001',
'webpack/hot/only-dev-server',
path.resolve(__dirname, 'client', 'index.jsx')
],
output: {
path: path.resolve(__dirname, 'public'),
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
],
resolve: {
modules: [path.resolve(__dirname, 'node_modules')],
extensions: ['*', '.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
]
},
devServer: {
port: 3001,
contentBase: path.resolve(__dirname, 'public'),
hot: true,
historyApiFallback: true
},
devtool: 'source-map'
};
我打算在前端使用 ES6 模块,所以我在 Webpack 上做了实验。但是,我很难使 ff: work
- 客户端有变化时热重载
- 当服务器端发生变化时热重载(在 webpack 之前,我使用
nodemon .
并且没有问题) - 终端中丢失 debug/console.log 信息,因为它正在打印 webpack 状态,而服务器上没有任何内容,例如我的自定义 'Server running....' 日志。
下面的设置我试图通过 npm start
运行。每次我做出任何改变,我都必须 运行 npm start
再
package.json
{
"name": "socket-io-chat",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "npm run build",
"build": "webpack -d && webpack-dev-server --hot --inline --watch && node --watch",
"build:prod": "webpack -p && webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.7.1",
"express": "*",
"socket.io": "*"
},
"devDependencies": {
"babel-core": "^6.14.0",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.14.0",
"babel-preset-stage-2": "^6.13.0",
"nodemon": "^1.10.2",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.15.1"
}
}
webpack.config.js
var path = require("path");
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var SRC_DIR = path.join(__dirname, "public");
var DIST_DIR = path.join(__dirname, "public/js/dist");
var config = {
context: __dirname,
devtool: debug ? "inline-sourcemap" : null,
entry: {
guest : path.join(SRC_DIR, "entry-guest.js"),
authenticated : path.join(SRC_DIR, "entry-authenticated.js")
},
output: {
path: DIST_DIR,
filename: "[name].js"
},
modules: {
loaders: [
{
test: /\.js?/,
include: SRC_DIR,
loader: "babel-loader",
query: {
presets: ["es2015", "stage-2"]
}
}
]
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
devServer: {
https: false,
contentBase: SRC_DIR,
stats: 'errors-only',
port: 3000
}
};
module.exports = config;
server.js
//create server
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
console.log('here');
var server = require('http').createServer(app);
//prepare socket io, make it listen to server
var io = require('socket.io').listen(server);
users = [];
connections = [];
var port = process.env.PORT || 3000;
server.listen(port);
console.log(`Server running *:${port}`);
//routing
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
//open a connection
io.sockets.on('connection', function(socket) {
connections.push(socket);
console.log('Connected: %s sockets connected:', connections.length);
//...more codes here
});
在您的 webpack 配置文件中,您可以尝试使用插件 "Hot Module Replacement"
除了已经实现的 Nodemon 之外,您还应该让客户端和服务器根据更改重新加载。
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
],
这是一个使用 HotModuleReplacement 的 webpack 配置示例。
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3001',
'webpack/hot/only-dev-server',
path.resolve(__dirname, 'client', 'index.jsx')
],
output: {
path: path.resolve(__dirname, 'public'),
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
],
resolve: {
modules: [path.resolve(__dirname, 'node_modules')],
extensions: ['*', '.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
]
},
devServer: {
port: 3001,
contentBase: path.resolve(__dirname, 'public'),
hot: true,
historyApiFallback: true
},
devtool: 'source-map'
};