今回は、webpack を使用した自動更新と解析の手順について詳しく説明します。webpack を使用して自動更新と解析を行う際の 注意事項 について、実際のケースを見てみましょう。
フロントエンドは js とスタイルを頻繁に変更する必要があり、ブラウザのページ効果に応じて常に調整する必要があります。多くの場合、開発ディレクトリとローカル公開ディレクトリは同じではないため、変更後に公開する必要があります。もう 1 つの点は、ページをダブルクリックするだけですべての効果が確認できるわけではないということです。多くの場合、nginx を使用してローカルにサイトを構築して観察する必要があります (テスト環境に置く前に自分のコンピューター上で行うことは問題ありません)。したがって、ブラウザを手動で更新し、手動で (またはクリックして) 公開し、サイトを開始する必要がある場合、それは確かに多くの物理的な作業になります。これら 3 つのポイント webpack は、それを実現するのに役立ちます。webpack-dev-serverwebpack
は、webpack-dev-server (WDS) による自動更新を実装します。 WDS は、メモリ内で実行される開発サーバー (エクスプレス) です。起動後、ファイルが変更されたかどうかを検出し、自動的に再度コンパイルされます。1. インストール
npm install webpack-dev-server --save-dev
2. npm を起動します
次に、package.json を変更します: (前のセクションに基づいて)"scripts": { "start": "webpack-dev-server --env development", "build": "webpack --env production" }
3. 直接起動
公式サイトでは、以下のコマンドでWDSを直接起動できることが紹介されています。webpack-dev-server --env development
C:UsersAdministrator.9BBOFZPACSCXLG2AppDataRoamingnpm;C:Program Files (x86)Microsoft VS Codebin;E:Html5node_modules.bin
4.8080ポートが占有されています
デフォルトが80の場合ポート 80 が占有されている場合、WDS は交換してください。たとえば、nginx を使用して最初に公開します。server{ listen 8080; location / { root E:/Html5/build; index index.html index.htm; } }
devServer:{ //... port: 9000 }
nodemon は自動的に起動します
WDS は開発ファイルを監視し、webpack.config.js を変更しても自動起動は行われません。したがって、これを行うにはnodemonが必要です。npm install nodemon --save-dev
"scripts": { "start": "nodemon --watch webpack.config.js --exec \"webpack-dev-server --env development\"", "build": "webpack --env production" },
プロキシ
しかし、私たちが自分たちでデプロイしたnginxにはいくつかのAPIプロキシが含まれているため、WDSサイトの代替可能性については少し疑問があります。 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"; } } } } } }
即将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中文网其它相关文章!
推荐阅读:
以上がWebpack を使用した自動更新と解析手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。