This document mainly discusses the combination of Webpack and Express to achieve the front and back end hot update development, if you are not familiar with Webpack recommended reading

Webpack official website documentation

What

What is WebPack Dev Server

Webpack Dev Server is a lightweight Node.js Express server that outputs updates to Webpack compiled code in real time. It is often used in front-end project development where the front and back ends are separated. But I don’t think this article will cover it.

webpack dev middleware

Webpack Dev Middleware is a middleware component of Webpack. It is used to distribute files in Express that need to be compiled with WebPack. It alone can do hot reloading of code.

Features:

  • No files are written to the hard disk, completely memory based implementation.
  • If you use Watch mode to listen for code changes, Webpack will compile automatically, and if a file is requested during a Webpack build, Webpack Dev Middleware will delay the request until the compile is complete and then start sending the compiled file.

webpack hot middleware

Webpack Hot Middleware subscribes to Webpack build updates and then pushes updates of these code blocks to the browser by executing Webpack’s HMR API.

HMR

HMR (Hot Module Replacement) is an important feature of Webpack. It allows us to apply our updated code to the current page in real time without having to manually refresh the browser page.

The realization principle of HMR is that HMR Runtime is added to the application code in our development. It is the module that HMR client (browser client) uses to communicate with the development server and receive updates. Webpack Hot Middleware (Webpack hot Middleware) is used to dynamically update code after it has been compiled by sending it to the HMR Runtime in JSON format.

How

Webpack configuration

Let’s start with the WebPack configuration file

var webpack = require('webpack');
var HotMiddleWareConfig = 'webpack-hot-middleware/client? path=/__webpack_hmr&timeout=20000'

module.exports = {
  context: __dirname,
  entry: [
  	 // Add a client that communicates with HotMiddleWare
    HotMiddleWareConfig,
    // Add the Web application entry file
    './client.js'].output: {
    path: __dirname,
    publicPath: '/'.filename: 'bundle.js'
  },
  devtool: '#source-map'.plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    / / in webpack plug-in introduce webpack. HotModuleReplacementPlugin
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
};
Copy the code

webpack-hot-middleware example webpack.config.js

This is how it is configured in our development environment. GetEntries automatically obtains the entry file according to our rules and adds the Webpack Hot Middle configuration.

var webpack = require('webpack');
var path = require('path')
var merge = require('webpack-merge')
var baseConfig = require('./webpack.base')
var getEntries = require('./getEntries')

var publicPath = 'http://0.0.0.0:7799/dist/';
var hotMiddlewareScript = 'webpack-hot-middleware/client? reload=true';

var assetsInsert = require('./assetsInsert')

module.exports = merge(baseConfig, {
  entry: getEntries(hotMiddlewareScript),
  devtool: '#eval-source-map'.output: {
    filename: './[name].[hash].js'.path: path.resolve('./public/dist'),
    publicPath: publicPath
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'}}),new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new assetsInsert()
  ]
})
Copy the code

Configuration in Express

There are four main steps to configuring Express:

  • Introduces webPack configuration files and compilers that generate WebPack
  • Connect the compiler to Webpack Dev Middleware
  • Connect the compiler to Webpack Hot Middleware
  • Defining express Configuration
var http = require('http');

var express = require('express');

var app = express();

app.use(require('morgan') ('short'));

/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// This is the real meat of the example
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
(function() {
  // Step 1: Import the webPack configuration file and the compiler that generates webPack
  var webpack = require('webpack');
  var webpackConfig = require(process.env.WEBPACK_CONFIG ? process.env.WEBPACK_CONFIG : './webpack.config');
  var compiler = webpack(webpackConfig);
  // Step 2: Mount the compiler to Webpack Dev Middleware
  app.use(require("webpack-dev-middleware")(compiler, {
    noInfo: true.publicPath: webpackConfig.output.publicPath
  }));

  // Step 3: Mount the compiler to Webpack Hot Middleware
  app.use(require("webpack-hot-middleware")(compiler, {
    log: console.log, path: '/__webpack_hmr'.heartbeat: 10 * 1000})); }) ();// Define the Express configuration

app.get("/".function(req, res) {
  res.sendFile(__dirname + '/index.html');
});
app.get("/multientry".function(req, res) {
  res.sendFile(__dirname + '/index-multientry.html');
});

if (require.main === module) {
  var server = http.createServer(app);
  server.listen(process.env.PORT || 1616.function() {
    console.log("Listening on %j", server.address());
  });
}
Copy the code

webpack-hot-middleware example server.js

Distinguish between development and production environments

It is important to define the webPack-related middleware before defining the Express Router. The other thing is that server.js is only used in the development environment, so we don’t need to use them in the build environment. So in our actual use, we need to define environment variables to distinguish between development and production environments

var NODE_ENV = process.env.NODE_ENV || 'production';
var isDev = NODE_ENV === 'development';

if (isDev) {
    var webpack = require('webpack'),
        webpackDevMiddleware = require('webpack-dev-middleware'),
        webpackHotMiddleware = require('webpack-hot-middleware'),
        webpackDevConfig = require('./build/webpack.config.js');

    var compiler = webpack(webpackDevConfig);

    app.use(webpackDevMiddleware(compiler, {
        publicPath: webpackDevConfig.output.publicPath,
        noInfo: true.stats: {
            colors: true}})); app.use(webpackHotMiddleware(compiler)); routerConfig(app, {dirPath: __dirname + '/server/routes/'.map: {
            'index': '/'.'api': '/api/*'.'proxy': '/proxy/*'}});var reload = require('reload');
    var http = require('http');

    var server = http.createServer(app);
    reload(server, app);

    app.use(express.static(path.join(__dirname, 'public')));

    server.listen(port, function(){
        console.log('App (dev) is now running on port ' + port + '! ');
    });
} else {
    routerConfig(app, {
        dirPath: __dirname + '/server/routes/'.map: {
            'index': '/'.'api': '/api/*'.'proxy': '/proxy/*'}}); app.use(express.static(path.join(__dirname,'public')));
    
    app.listen(port, function () {
        console.log('App (Production) is now running on port ' + port + '! ');
    });
}

Copy the code

supervisor

Above, we realize hot update of the front-end file. However, when we modify the server file, the Node will not automatically restart. Therefore, we use the Supervisor as the monitoring file modification event to automatically restart the Node service.

The Supervisor needs to be installed globally

npm install supervisor -g
Copy the code

Once installed, we can use it from the command line

We write common commands in package.json scripts and then just use NPM run XXX

"scripts": {
    "dev": "export NODE_ENV=development && supervisor -w server,app.js app"."build": "node build/build.js"."start": "node app"
  },
Copy the code

node-supervisor

supervisor [options] <program>

supervisor -w server,app.js app
Copy the code

-w is an options configuration item that listens for changes to specified directories or files. It can be used to separate and listen for multiple directories or files. This is app.js that listens for changes to the server directory and root directory.

audio