国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

淺談webpack 自動(dòng)刷新與解析

2024-05-06 16:43:39
字體:
供稿:網(wǎng)友

前端需要頻繁的修改js和樣式,且需要根據(jù)瀏覽器的頁面效果不斷的做調(diào)整;而且往往我們的開發(fā)目錄和本地發(fā)布目錄不是同一個(gè),修改之后需要發(fā)布一下;另外一點(diǎn)就是并不是所有的效果都可以直接雙擊頁面就能看到,我們常常需要在本地用nginx建一個(gè)站點(diǎn)來觀察(自己電腦上ok了才放到測試環(huán)境去)。所以如果要用手工刷新瀏覽器和手動(dòng)(或點(diǎn)擊)發(fā)布,還要啟動(dòng)站點(diǎn),確實(shí)是個(gè)不小的體力活。而這三點(diǎn)webpack可以幫我們做到。

webpack-dev-serverwebpack

是通過webpack-dev-server(WDS)來實(shí)現(xiàn)自動(dòng)刷新。WDS是一個(gè)運(yùn)行在內(nèi)存中的開發(fā)服務(wù)器(一個(gè)express)。啟動(dòng)之后,它會(huì)檢測文件是否發(fā)生改變并再自動(dòng)編譯一次。

1.安裝

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

先通過npm將其安裝到開發(fā)目錄。安裝完成之后會(huì)在node_modules/bin下找到。

2.npm啟動(dòng)

然后修改package.json:(基于上一節(jié))

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

現(xiàn)在就可以通過npm run start 或者 npm start來啟動(dòng)了。

webpack,自動(dòng)刷新

啟動(dòng)之后,可以看到Project is running at http://localhost:8080 上面。打開頁面

webpack,自動(dòng)刷新

說明WDS已經(jīng)幫我們自動(dòng)建了一個(gè)站點(diǎn).我們修改component.js ,cmd中會(huì)出現(xiàn)編譯,頁面會(huì)自動(dòng)刷新。

webpack,自動(dòng)刷新

3.直接啟動(dòng)

官網(wǎng)介紹可以直接通過下面的命令啟動(dòng)WDS。

webpack-dev-server --env development

但會(huì)出現(xiàn)webpack-dev-server --env development 不是內(nèi)部命令的提示,這種問題都是環(huán)境變量的問題,將你開發(fā)的bin目錄設(shè)置到環(huán)境變量中即可,比如我的目錄是‘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

webpack,自動(dòng)刷新

4.8080端口占用

如果默認(rèn)的8080端口占用,WDS會(huì)換一個(gè)。比如用nginx先發(fā)布一個(gè)。

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

再啟動(dòng)WDS:

webpack,自動(dòng)刷新

端口切到了8081。也可以手動(dòng)配置端口:

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

nodemon 自動(dòng)啟動(dòng)

WDS是監(jiān)視開發(fā)文件的,webpack.config.js改變不會(huì)引起自動(dòng)啟動(dòng)。所以我們需要nodemon去做這件事情。

npm install nodemon --save-dev

先安裝在開發(fā)目錄,然后修改package.json:

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

等于讓nodemon去監(jiān)視webpack.config.js,變化了就去啟動(dòng)它。

webpack,自動(dòng)刷新

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

代理

不過有一點(diǎn)疑問,就是WDS這個(gè)站點(diǎn)的替代性,因?yàn)槲覀冏约翰渴鸬膎ginx有一些api的代理。如果掛在WDS的這個(gè)默認(rèn)站點(diǎn)上自然是無法訪問的。換句話說可否給WDS配置一個(gè)刷新路徑。如果文件改變?nèi)ニ⑿轮付ǖ牡刂罚蛘咦屛胰ヅ鋫€(gè)代理。既然它本身是一個(gè)http服務(wù)器,肯定也有代理的功能。搜了下果然有: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這個(gè)字段替換成http://jsonplaceholder.typicode.com/,并將其從原地址中刪掉,這樣就可以自己實(shí)現(xiàn)代理了。皆大歡喜!WDS是通過http-proxy-middleware來實(shí)現(xiàn)代理。更多參考:http://webpack.github.io/docs/webpack-dev-server.html;https://github.com/chimurai/http-proxy-middleware#options

but,這種刷新是怎么實(shí)現(xiàn)的呢?因?yàn)轫撁嫔蠜]有嵌入什么別的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來監(jiān)視文件變化,server的內(nèi)部維護(hù)的有一個(gè)socket集合:

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

sock是一個(gè)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,其中有一個(gè)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的時(shí)候觸發(fā)一個(gè)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通知到客戶端,這樣就實(shí)現(xiàn)了刷新。之前WebSocket的第三方只用過socket.io,看起來sockjs也蠻好用的。不必外帶一個(gè)js,在主js里面就可以寫了。

小結(jié):效率提高的一方面是將一些機(jī)械的重復(fù)性流程或動(dòng)作自動(dòng)化起來。WDS和nodemon就是兩個(gè)為你干活的小弟。

demo:webpack-ch2.rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 高雄县| 大同县| 三亚市| 房山区| 凤凰县| 水富县| 池州市| 溧阳市| 新沂市| 蒙城县| 淄博市| 社旗县| 永定县| 阳泉市| 汉川市| 任丘市| 苍梧县| 太仆寺旗| 荃湾区| 云浮市| 屯昌县| 平邑县| 青海省| 绥棱县| 铅山县| 郁南县| 鄄城县| 嘉禾县| 怀集县| 治县。| 南漳县| 内丘县| 南川市| 宁都县| 望谟县| 高平市| 太和县| 上高县| 河源市| 保德县| 天镇县|