最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2018年04月09日 10:09:41   作者:stoneniqiu  
這篇文章主要介紹了淺談webpack 自動(dòng)刷新與解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

前端需要頻繁的修改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)之后,它會檢測文件是否發(fā)生改變并再自動(dòng)編譯一次。

1.安裝

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

先通過npm將其安裝到開發(fā)目錄。安裝完成之后會在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)了。

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

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

3.直接啟動(dòng)

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

webpack-dev-server --env development

但會出現(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

4.8080端口占用

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

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

再啟動(dòng)WDS:

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

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

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

WDS是監(jiān)視開發(fā)文件的,webpack.config.js改變不會引起自動(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)它。

這樣就你可以讓你的雙手專心的開發(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_jb51.rar

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

相關(guān)文章

  • JavaScript制作3D旋轉(zhuǎn)相冊

    JavaScript制作3D旋轉(zhuǎn)相冊

    這篇文章主要為大家詳細(xì)介紹了JavaScript制作3D旋轉(zhuǎn)相冊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 微信小程序利用swiper+css實(shí)現(xiàn)購物車商品刪除功能

    微信小程序利用swiper+css實(shí)現(xiàn)購物車商品刪除功能

    這篇文章主要介紹了微信小程序利用swiper+css實(shí)現(xiàn)購物車商品刪除功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 小程序自定義索引菜單

    小程序自定義索引菜單

    這篇文章主要為大家詳細(xì)介紹了小程序自定義索引菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JS逆向之?webpack?打包站點(diǎn)實(shí)戰(zhàn)原理分享

    JS逆向之?webpack?打包站點(diǎn)實(shí)戰(zhàn)原理分享

    本文主要介紹了JS逆向之webpack打包站點(diǎn)實(shí)戰(zhàn)原理分享,webpack是前端程序員用來進(jìn)行打包JS的技術(shù),打包之后的代碼特征非常明顯,更多相關(guān)知識需要的小伙伴可以參考下面文章詳細(xì)內(nèi)容
    2022-06-06
  • JavaScript Event Loop相關(guān)原理解析

    JavaScript Event Loop相關(guān)原理解析

    這篇文章主要介紹了JavaScript Event Loop相關(guān)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • JavaScript中自定義swiper組件詳解

    JavaScript中自定義swiper組件詳解

    這篇文章主要介紹了微信小程序 swiper組件輪播圖詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • 性能優(yōu)化之代碼優(yōu)化頁面加載速度

    性能優(yōu)化之代碼優(yōu)化頁面加載速度

    本文主要介紹了代碼優(yōu)化頁面加載速度的方法。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-03-03
  • JavaScript模板引擎EJS特性及用法詳解

    JavaScript模板引擎EJS特性及用法詳解

    EJS是一種簡單而靈活的模板引擎,用于將數(shù)據(jù)動(dòng)態(tài)渲染到網(wǎng)頁上,本文將從介紹EJS的背景和起源開始,詳細(xì)介紹EJS的特性和使用方法,包括安裝配置、基本語法和標(biāo)簽、數(shù)據(jù)綁定和邏輯控制、模板的繼承和包含等方面,感興趣的同學(xué)跟著小編一起來學(xué)習(xí)吧
    2023-06-06
  • uniapp上傳圖片和上傳視頻的實(shí)現(xiàn)方法

    uniapp上傳圖片和上傳視頻的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于uniapp上傳圖片和上傳視頻的實(shí)現(xiàn)方法,文中還介紹了上傳文件的方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • JavaScript?canvas實(shí)現(xiàn)字符雨效果

    JavaScript?canvas實(shí)現(xiàn)字符雨效果

    這篇文章主要為大家詳細(xì)介紹了JavaScript?canvas實(shí)現(xiàn)字符雨效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評論

哈巴河县| 南昌市| 澜沧| 丹东市| 沈丘县| 乐山市| 石棉县| 格尔木市| 达日县| 雅江县| 灵山县| 康定县| 平乡县| 中牟县| 寿阳县| 麻城市| 塔河县| 贵阳市| 麻江县| 舟曲县| 德安县| 兴义市| 新丰县| 清原| 彭泽县| 宜兴市| 大悟县| 平潭县| 巴林右旗| 武穴市| 安达市| 甘南县| 丹江口市| 封丘县| 韶关市| 四子王旗| 凉城县| 西安市| 弋阳县| 伽师县| 镇远县|