How to create a pleasing front-end development environment (d)

Original link
This article is written by my colleague, set up in conjunction with Express Webpack. The following is the text, later I will attach my interpretation

Express combined Webpack achieve HMR

Benpian file mainly about Express to achieve combined Webpack and front and rear ends of the heat development update, if you do not know webpack Recommended Reading
webpack official website documents

What

What is webpack dev server

Webpack dev server is a lightweight node.js express server, realize the real-time output webpack compiled code update. The rear end of the front end separation frequently used in the previous project development. However, this article should not talked about it.

webpack dev middleware

Webpack dev middleware is a middleware WebPack of. It is used to distribute Express in need WebPack compiled files. It can be used alone thermal overload completion code (hot reloading) function.

characteristic:

  • It does not write files on the hard disk, based entirely on memory implementation.

  • If a watch mode monitor code changes, automatically compiles Webpack, if the requested file compilation process Webpack, Webpack dev middleware request will be delayed until after the completion of the translation start again transmitting the compiled file.

webpack hot middleware

Webpack hot middleware Webpack it updated by subscribing to compile, after execution by HMR api webpack of these updates code modules pushed to the browser.

HMR

HMR That Hot Module Replacement Webpack is an important feature. It allows us to achieve our real-time update the code to the current page without refreshing the browser page by manually.

The principle HMR is application code in our development added the HMR Runtime, which is a module HMR client (browser client) for the development and communication server to receive updates. Webpack server job is the aforementioned hot middleware, it will compiled code update after json format to output to HMR Runtime will be described in more json dynamically updated by the appropriate code.

How

webpack Configuration

First introduced in webpack profile

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

module.exports = {
    context: __dirname,
    entry: [
        // 添加一个和HotMiddleWare通信的客户端             
        HotMiddleWareConfig,
        // 添加web应用入口文件 
        './client.js'
    ],
    output: {
        path: __dirname,
        publicPath: '/',
        filename: 'bundle.js'
    },
    devtool: '#source-map',
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(),
        // 在 webpack 插件中引入 webpack.HotModuleReplacementPlugin 
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
};

webpack-hot-middleware example webpack.config.js

In our development environment is configured. getEntries is to automatically obtain an entry file and add webpack hot middle configuration according to our rules.

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()
  ]
})

Express configuration

Express configuration mainly on four steps:

  • Introducing webpack profile and compilers generated webpack

  • The compiler is connected to webpack dev middleware

  • The compiler is connected to webpack hot middleware

  • The definition of 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: 引入 webpack 的配置文件和 生成 webpack 的编译器
  var webpack = require('webpack');
  var webpackConfig = require(process.env.WEBPACK_CONFIG ? process.env.WEBPACK_CONFIG : './webpack.config');
  var compiler = webpack(webpackConfig);
  // Step 2: 将编译器挂载给 webpack dev middleware
  app.use(require("webpack-dev-middleware")(compiler, {
    noInfo: true, publicPath: webpackConfig.output.publicPath
  }));

  // Step 3: 将编译器挂载给 webpack hot middleware
  app.use(require("webpack-hot-middleware")(compiler, {
    log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000
  }));
})();

// 定义 express 配置

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());
  });
}

webpack-hot-middleware example server.js

Distinguish between development and production environments

Note that the definition of middleware webpack must be related to the definition of prior express router. Another point here is just server.js development environment used in the build environment, we do not need to reuse them. Therefore, our actual use need to distinguish between development and production environments by defining the environment variable

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 (dev) is now running on port ' + port + '!');
    });
}

supervisor

In the front we have achieved more than hot update the front of the file, but we modify the server file, does not make the Node automatically restart, so we use as a supervisor to monitor file modification event to automatically restart Node service.
supervisor requires global installation

  npm install supervisor -g

After the installation is complete, we can use the command line
we write frequently used commands in the scripts package.json, after which only can be used with npm run xxx

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

node-supervisor

supervisor [options] <program>

supervisor -w server,app.js app

-w options is a configuration item, which is used to monitor changes in the specified directory or file can be used,
after separate, monitor multiple directories or files, this is the monitor of app.js server directory and the root directory will be changed to restart our Express entry file app.

My own interpretation

First, to explain his original code is difficult to explain a few points:

  • getEntries this unified approach is to load our own entrance file, in fact, the specific content of the article I mentioned earlier, is ordained, folders main.js directory is our entry file, ignoring all other reasons also said that, here again, the provisions die, simple, convenient and conducive to cooperation.

  • publicPath = var ' http://0.0.0.0:7799/dist/ '; here publicPath reasons and we usually configured Webpack of publicPath not the same, is able to recognize the absolute need Express addresses, because you project is greater than Webpack Express of.

  • routerConfig This method is a method of our own, the content of the article mentioned earlier, it is that I wrote a method used to load all the routes, so as not to repeat writing various reference. npm address

  • Note that export NODE_ENV = development, windows environment may fail, can be replaced by cross-env NODE_ENV = development

Secondly, said the reason to do so under

  • The article also mentioned earlier, our current overall front-end architecture is the use of Node do middle layer, then the problem is Node render layer will be higher than Webpack layer, and in many cases, do not necessarily use the SPA way, be compatible with the architecture, so it You need these configurations.

  • This configuration also solved a number of pain points in our development, a Node automatically re, hot update a file, combine basic you do not need to constantly manually refresh the browser, and can save the current state, which is key You can save a lot of time to improve development efficiency.

  • Of course there are pain points, for example, to more than a template file, and the file directory according to specifications, but for not rendering.

Finally, remember that this is a continuous series of articles, look at where you may not be able to configure success! ! ! !

Guess you like

Origin www.cnblogs.com/jlfw/p/12589321.html