Home  >  Article  >  Web Front-end  >  Use of webpack refresh parsing function

Use of webpack refresh parsing function

php中世界最好的语言
php中世界最好的语言Original
2018-06-09 11:21:071610browse

This time I will bring you the use of the webpack refresh parsing function and what are the precautions for webpack refresh parsing. The following is a practical case, let's take a look.

The front end needs to frequently modify js and styles, and needs to be constantly adjusted according to the browser's page effect; and often our development directory and the local release directory are not the same, and we need to publish them after modification; another point That is, not all effects can be seen directly by double-clicking the page. We often need to use nginx to build a site locally to observe (it is ok on our own computer before putting it into the test environment). So if you have to manually refresh the browser and manually (or click) publish, and start the site, it is indeed a lot of physical work. And these three points webpack can help us do it.

webpack-dev-serverwebpack

realizes automatic refresh through webpack-dev-server (WDS). WDS is a development server (an express) running in memory. After starting, it will detect whether the file has changed and automatically compile again.

1. Installation

npm install webpack-dev-server --save-dev

First install it to the development directory through npm. After the installation is complete, it will be found under node_modules/bin.

2.npm start

Then modify package.json: (based on the previous section)

"scripts": {
  "start": "webpack-dev-server --env development",
  "build": "webpack --env production"
 }

You can now run start through npm or npm start to start.

After starting, you can see that Project is running at http://localhost:8080. Opening the page

shows that WDS has automatically built a site for us. We modify component.js, compilation will appear in cmd, and the page will automatically refresh.

3. Start WDS directly

The official website introduces that you can start WDS directly through the following command.

webpack-dev-server --env development

But there will be a prompt that webpack-dev-server --env development is not an internal command. This kind of problem is a problem with environment variables. Just set the bin directory you developed to the environment variable, such as My directory is 'E:\Html5\node_modules\.bin', just add a semicolon at the end.

C:\Users\Administrator.9BBOFZPACSCXLG2\AppData\Roaming\npm;C:\Program Files (x86)\Microsoft VS Code\bin;E:\Html5\node_modules\.bin

4.8080 port occupation

If the default 8080 port is occupied, WDS will change it. For example, use nginx to publish one first.

server{
   listen    8080;
   location / {
      root  E:/Html5/build;
      index index.html index.htm;
    }
  }

Restart WDS:

The port is switched to 8081. You can also manually configure the port:

 devServer:{
  //...
  port: 9000
}

nodemon automatic startup

WDS monitors development files, and changes in webpack.config.js will not cause automatic startup. So we need nodemon to do this.

npm install nodemon --save-dev

First install it in the development directory, and then modify package.json:

 "scripts": {
  "start": "nodemon --watch webpack.config.js --exec \"webpack-dev-server --env development\"",
  "build": "webpack --env production"
 },

It is equivalent to letting nodemon monitor webpack.config.js and start it if it changes.

This way you can let your hands concentrate on development.

Agent

But I have a little doubt about the substitutability of the WDS site, because the nginx we deployed ourselves has some API proxies. If it is hung on the default site of WDS, it will naturally be inaccessible. In other words, can you configure a refresh path for WDS? If the file changes, refresh the specified address, or ask me to configure a proxy. Since it is an http server itself, it must also have proxy functions. After searching, it turned out to be: https://github.com/webpack/webpack-dev-server/tree/master/examples/proxy-advanced

module.exports = {
  context: __dirname,
  entry: "./app.js",
  devServer: {
    proxy: {
      "/api": {
        target: "http://jsonplaceholder.typicode.com/",
        changeOrigin: true,
        pathRewrite: {
          "^/api": ""
        },
        bypass: function(req) {
          if(req.url === "/api/nope") {
            return "/bypass.html";
          }
        }
      }
    }
  }
}

即将api这个字段替换成http://jsonplaceholder.typicode.com/,并将其从原地址中删掉,这样就可以自己实现代理了。皆大欢喜!WDS是通过http-proxy-middleware来实现代理。更多参考:http://webpack.github.io/docs/webpack-dev-server.html;https://github.com/chimurai/http-proxy-middleware#options

but,这种刷新是怎么实现的呢?因为页面上没有嵌入什么别的js,去翻原码 web-dev-server/server.js中有这么一段:

Server.prototype._watch = function(path) {
  const watcher = chokidar.watch(path).on("change", function() {
    this.sockWrite(this.sockets, "content-changed");
  }.bind(this))
  this.contentBaseWatchers.push(watcher);
}

用chokidar来监视文件变化,server的内部维护的有一个socket集合:

Server.prototype.sockWrite = function(sockets, type, data) {
  sockets.forEach(function(sock) {
    sock.write(JSON.stringify({
      type: type,
      data: data
    }));
  });
}

sock是一个sockjs对象。https://github.com/sockjs/sockjs-client,从http://localhost:8080/webpack-dev-server/页面来看,sockjs是用来通信记录日志的。

var onSocketMsg = {
  hot: function() {
    hot = true;
    log("info", "[WDS] Hot Module Replacement enabled.");
  },
  invalid: function() {
    log("info", "[WDS] App updated. Recompiling...");
    sendMsg("Invalid");
  },
  hash: function(hash) {
    currentHash = hash;
  },
...
}

我们在看app.js,其中有一个OnSocketMsg 对象。

var onSocketMsg = {
  hot: function() {
    hot = true;
    log("info", "[WDS] Hot Module Replacement enabled.");
  },
  invalid: function() {
    log("info", "[WDS] App updated. Recompiling...");
    sendMsg("Invalid");
  },
  hash: function(hash) {
    currentHash = hash;
  },
  "still-ok": function() {
    log("info", "[WDS] Nothing changed.")
    if(useWarningOverlay || useErrorOverlay) overlay.clear();
    sendMsg("StillOk");
  },
  "log-level": function(level) {
    logLevel = level;
  },
  "overlay": function(overlay) {
    if(typeof document !== "undefined") {
      if(typeof(overlay) === "boolean") {
        useWarningOverlay = overlay;
        useErrorOverlay = overlay;
      } else if(overlay) {
        useWarningOverlay = overlay.warnings;
        useErrorOverlay = overlay.errors;
      }
    }
  },
  ok: function() {
    sendMsg("Ok");
    if(useWarningOverlay || useErrorOverlay) overlay.clear();
    if(initial) return initial = false;
    reloadApp();
  },
  "content-changed": function() {
    log("info", "[WDS] Content base changed. Reloading...")
    self.location.reload();
  },
  warnings: function(warnings) {
    log("info", "[WDS] Warnings while compiling.");
    var strippedWarnings = warnings.map(function(warning) {
      return stripAnsi(warning);
    });
    sendMsg("Warnings", strippedWarnings);
    for(var i = 0; i < strippedWarnings.length; i++)
      console.warn(strippedWarnings[i]);
    if(useWarningOverlay) overlay.showMessage(warnings);
    if(initial) return initial = false;
    reloadApp();
  },
  errors: function(errors) {
    log("info", "[WDS] Errors while compiling. Reload prevented.");
    var strippedErrors = errors.map(function(error) {
      return stripAnsi(error);
    });
    sendMsg("Errors", strippedErrors);
    for(var i = 0; i < strippedErrors.length; i++)
      console.error(strippedErrors[i]);
    if(useErrorOverlay) overlay.showMessage(errors);
  },
  close: function() {
    log("error", "[WDS] Disconnected!");
    sendMsg("Close");
  }
};

ok的时候触发一个reloadApp

function reloadApp() {
  if(hot) {
    log("info", "[WDS] App hot update...");
    var hotEmitter = __webpack_require__("./node_modules/webpack/hot/emitter.js");
    hotEmitter.emit("webpackHotUpdate", currentHash);
    if(typeof self !== "undefined") {
      // broadcast update to window
      self.postMessage("webpackHotUpdate" + currentHash, "*");
    }
  } else {
    log("info", "[WDS] App updated. Reloading...");
    self.location.reload();
  }
}

也就是说WDS先检测文件是否变化,然后通过sockjs通知到客户端,这样就实现了刷新。之前WebSocket的第三方只用过socket.io,看起来sockjs也蛮好用的。不必外带一个js,在主js里面就可以写了。

小结:效率提高的一方面是将一些机械的重复性流程或动作自动化起来。WDS和nodemon就是两个为你干活的小弟。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Mac内安装nodejs、npm与cnpm

使用select组件案例详解

The above is the detailed content of Use of webpack refresh parsing function. For more information, please follow other related articles on the PHP Chinese website!

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