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