Home  >  Article  >  Web Front-end  >  The use of webpack automatic refresh and parsing

The use of webpack automatic refresh and parsing

php中世界最好的语言
php中世界最好的语言Original
2018-03-16 14:29:182013browse

This time I will bring you the use of webpack automatic refresh and parsing. What are the precautions for using webpack automatic refresh and 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-server

Webpack implements 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 startup

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

 "scripts": {    "start": "webpack-dev-server --env development",    "build": "webpack --env production"
  }
Now you can start it through npm run start or npm 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 to 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, there is indeed:

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";
                    }
                }
            }
        }
    }
}
Replace the api field with http://jsonplaceholder.typicode.com/ and delete it from the original address so that you can implement the proxy yourself. Everyone is happy! WDS implements proxy through http-proxy-middleware. More references: http://webpack.github.io/docs/webpack-dev-server.html#bypass-the-proxy;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");
    }
};

View Code

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里面就可以写了。

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

推荐阅读:

H5的缓存Manifest的使用

webpack的模块热替换详解

webpack的样式加载详解

JS事件先发布后订阅的方法

The above is the detailed content of The use of webpack automatic refresh and parsing. 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
Previous article:Use of H5 cache ManifestNext article:Use of H5 cache Manifest