Home  >  Article  >  Web Front-end  >  Webpack implements Node.js code hot replacement_node.js

Webpack implements Node.js code hot replacement_node.js

WBOY
WBOYOriginal
2016-05-16 15:35:371431browse

For the past two days, I have asked about this issue on Gitter, Twitter, and GitHub, but there has been no response for two days
It turns out that the blogger jlongster ignored me, and I didn’t know the contact information of the author of Webpack
He seemed to have seen the last message posted on Gitter, so he roughly explained it. It was so enlightening...
https://github.com/webpack/docs/issues/45#issuecomment-149793458

Here is the process in short:

Compile the server code with webpack
Use target: "node" or target: "async-node"
Enabled HMR via --hot or HotModuleReplacementPlugin
Use webpack/hot/poll or webpack/hot/signal
The first polls the fs for updates (easy to use)
The second listens for a process event to check for updates (you need a way to send the signal)
Run the bundle with node.
You can't use existing HMR loaders like react-hot-loader or style-loader because they make no sense in a server environment. Just add manuall replacement code at the correct location (i. e. accept request handler like in the example)

You can't use the webpack-dev-server. It's a server which serves assets not a runner. Just run webpack --watch and node bundle.js. I would go the webpack/hot/poll?1000 route first. It's pretty easy to use and suitable for dev environments. For production (if you want to hot update your production server) the signal approach is better suited.

The original words will not be translated. After understanding, the main thing is how to configure Webpack and how to run the script
I wrote it again. The code is only so short, and hot replacement is implemented:
https://github.com/jiyinyiyong/webpack-backend-HMR-demo
The code can be copied from jlongster’s configuration tutorial:
http://jlongster.com/Backend-Apps-with-Webpack--Part-II

webpack = require 'webpack'

module.exports =
 entry: [
  'webpack/hot/poll&#63;1000' # <-- 轮询更新内容的代码
  './src/main' # <-- 项目入口
 ]
 target: 'node' # <-- 指明编译方式为 node
 output:
  path: 'build/'
  filename: 'bundle.js' # <-- 编译结果的文件名
 module:
  loaders: [
   {test: /\.coffee/, loader: 'coffee'}
  ]
 plugins: [
  new webpack.HotModuleReplacementPlugin() # <-- 照常启动 hot mode
 ]
 resolve:
  extensions: ['.js', '', '.coffee']

If running in command line environment, please note that it is webpack instead of webpack-dev-server
Pay attention to the & running in the background just to avoid blocking. If you have two terminals, just open two

npm i
webpack --watch & # <-- watch 模式
node build/bundle.js # <-- 运行的是打包结果的代码

I wrote two test files, one is the modified code src/lib.coffee:

exports.data = 'code 5'

exports.printSelf = ->
 console.log 'doing 3'

Another entry file src/main.coffee contains code to handle module replacement:

lib = require './lib'

console.log lib.data
lib.printSelf()

counter = 0
setInterval ->
 counter += 1
 console.log counter
, 2000

if module.hot
 module.hot.accept './lib', ->
  lib = require './lib'

  console.log lib.data
  lib.printSelf()

Run the demo and you will know the effect. setInterval is not affected by substitution
In the build/ directory, each modification will generate a JSON file to record the modified content:

Copy code The code is as follows:
➤➤ l build/
0.1dadeb2eb7b01e150126.hot-update.js 0.c1d0d73de39660806d0c.hot-update.js 2849b61a15d31ffe5e08.hot-update.json 0.99ea3ea7633f6b3750e6.hot-update.js 0.ea a7b323eba37ae58997.hot-update.js 9b4a5ad617ec1dbc48a3.hot-update.json fb584971920454f9ccbe. hot-update.json
0.9abf25005c61357a0ce5.hot-update.js 0.fb584971920454f9ccbe.hot-update.js a664b5851a99ac0865ca.hot-update.json
0.9b4a5ad617ec1dbc48a3.hot-update.js 1dadeb2eb7b01e150126.hot-update.json bundle.js
0.a664b5851a99ac0865ca.hot-update.js 256267122c6d325755b0.hot-update.json c1d0d73de39660806d0c.hot-update.json

The specific file content is like this, which can be roughly considered to contain the information needed to identify updates:

&#10148;&#10148; cat build/0.c797c084381bfeac37f7.hot-update.js
exports.id = 0;
exports.modules = {

/***/ 3:
/***/ function(module, exports, __webpack_require__) {

  var counter, lib;
  lib = __webpack_require__(4);
  console.log(lib.data);
  lib.printSelf();
  counter = 0;
  setInterval(function() {
   counter += 1;
   return console.log(counter, 3);
  }, 2000);

  if (true) {
   module.hot.accept(4, function() {
    lib = __webpack_require__(4);
    console.log(lib.data);
    return lib.printSelf();
   });
  }

/***/ }
};

Other plans

I was looking for solutions on the Internet during the day, and posted a post on the forum asking about this matter. There are two main existing solutions with relatively clear explanations, which are worth learning from

One is on Baidu’s technology blog, which probably describes how to process module objects, that is, manually monitor file modifications, then clear the module cache, and remount the module
The ideas are clear and carefully considered. Although the code is a bit redundant, you can still give it a try:
http://www.jb51.net/article/73739.htm

The other one seems to be a hack on require.extensions, adding operations and events. When the module file is updated, the corresponding module is automatically updated, and an event is emitted. Through this effect, the location referenced by the module can be processed. , using new code, this should be said to be relatively crude, after all, not all codes are easy to replace
https://github.com/rlidwka/node-hotswap

Impressions

Considering that I have already hung myself on the Webpack tree, I don’t plan to study it in depth. Maybe Node.js officially optimizes lib/module.js to get good functions. However, JavaScript is not The community where the use of immutable data is popular cannot compare with Erlang, because code replacement involves the problem of status update, which is difficult to do. It is easier to restart, and restart now has three options for you to choose: node-dev supervisor nodemon

For me, the main reason is that the Cumulo solution has a huge dependence on WebSocket. Now front-end development can update the code on the server and the client automatically updates,
Through the mechanisms of Webpack and React, DOM and pure function modules are partially updated. If the development environment can also be hot-replaced, this will greatly improve development efficiency. I originally thought that hot-replacement was out of reach, but it is very possible. It’s an efficiency improvement within reach!

There may be pitfalls behind, after all, black technology... I’ll tell you when you encounter it

If you are interested, you can take a closer look at several related masterpieces written by jlongster, which are very helpful:
http://jlongster.com/archive

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn