1. 程式人生 > >【webpack】-- 自動重新整理與解析

【webpack】-- 自動重新整理與解析

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

先通過npm將其安裝到開發目錄。安裝完成之後會在node_modules/bin下找到。

2.npm啟動

然後修改package.json:(基於上一節)

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

現在就可以通過npm run start 或者 npm start來啟動了。

啟動之後,可以看到Project is running at http://localhost:8080 上面。開啟頁面

說明WDS已經幫我們自動建了一個站點.我們修改component.js ,cmd中會出現編譯,頁面會自動重新整理。

3.直接啟動

官網介紹可以直接通過下面的命令啟動WDS。

webpack-dev-server --env development

但會出現webpack-dev-server --env development 不是內部命令的提示,這種問題都是環境變數的問題,將你開發的bin目錄設定到環境變數中即可,比如我的目錄是‘E:\Html5\node_modules\.bin’,就加上分號寫在後面。

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

4.8080端口占用

如果預設的8080端口占用,WDS會換一個。比如用nginx先發佈一個。

複製程式碼
   server{
      listen       8080;
      location / {
           root   E:/Html5/build;
           index  index.html index.htm;
        }
    }
複製程式碼

再啟動WDS:

埠切到了8081。也可以手動配置埠:

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

nodemon 自動啟動

 WDS是監視開發檔案的,webpack.config.js改變不會引起自動啟動。所以我們需要nodemon去做這件事情。

npm install nodemon --save-dev

先安裝在開發目錄,然後修改package.json:

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

等於讓nodemon去監視webpack.config.js,變化了就去啟動它。

這樣就你可以讓你的雙手專心的開發了。

代理

不過有一點疑問,就是WDS這個站點的替代性,因為我們自己部署的nginx有一些api的代理。如果掛在WDS的這個預設站點上自然是無法訪問的。換句話說可否給WDS配置一個重新整理路徑。如果檔案改變去重新整理指定的地址,或者讓我去配個代理。既然它本身是一個http伺服器,肯定也有代理的功能。搜了下果然有: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";
                    }
                }
            }
        }
    }
}
複製程式碼

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 物件。

 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裡面就可以寫了。

小結:效率提高的一方面是將一些機械的重複性流程或動作自動化起來。WDS和nodemon就是兩個為你幹活的小弟。