如何让 Webpack 和 Node 协同工作?

How to make Webpack and Node work together?

我打算在前端使用 ES6 模块,所以我在 Webpack 上做了实验。但是,我很难使 ff: work

  1. 客户端有变化时热重载
  2. 当服务器端发生变化时热重载(在 webpack 之前,我使用 nodemon . 并且没有问题)
  3. 终端中丢失 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'
};