今天我們將介紹mode屬性的development值。它會自動為你配置Webpack以簡化開發過程。除此之外,我們還會介紹webpack-dev-server——包括模塊熱替換。開始吧! ...
轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。
原文出處:https://wanago.io/2018/08/06/webpack-4-course-part-six-increasing-development-experience
今天我們將介紹mode屬性的development值。它會自動為你配置Webpack以簡化開發過程。除此之外,我們還會介紹webpack-dev-server——包括模塊熱替換。開始吧!
開發體驗優化的其中一步是讓Webpack運行在watch模式下。試試webpack --watch。現在每當你對源碼做出修改,Webpack會重新編譯你的工程然後輸出。webpack-dev-server則做得更多。它不是把輸出文件寫到文件夾下,而是直接把它們寫入記憶體。在構建完之後,輸出可作為本地伺服器資源被訪問。
運行 webpack-dev-server
首先是安裝它。
npm install webpack-dev-server
然後是在你的package.json文件中加入它:
"scripts": { "build": "webpack", "start": "webpack-dev-server" } ··· 現在就可以使用`npm start`來啟動它。你會看到下麵的提示信息: ```bash 「wds」: Project is running at http://localhost:8080/
剩下的事情只是在瀏覽器中打開http://localhost:8080/了。
模塊熱替換
為進一步優化你的開發體驗,可以使用模塊熱替換,你甚至跳過刷頁面的需求。比如,當你對某些樣式做了修改,不必刷新整個頁面就可以看到效果。
在第四節教程我們曾使用了MiniCssExtractPlugin。請註意,在寫文本時,對MiniCssExtractPlugin的熱模塊更新支持還沒有實現。更多信息請可查看Github上的此issue。在當前開發環境,你可能需要使用的是style-loader。
當你運行webpack-dev-server時,它使用與正常構建時相同的配置文件。你可以在webpack.config.js中加入一個叫devServer的參數來進行額外的配置。我們需要它來開啟模塊熱替換。
// webpack.config.js const webpack = require('webpack'); module.exports = { devServer: { hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] };
註意,當開啟 -hot 標誌以運行 webpack-dev-server 時也會在plugins裡加入HotModuleReplacementPlugin。如果你添加了兩次,可能會出現問題。
這對於我們的CSS調試是很有吸引力的。但當修改是JavaScript時,還需點額外步驟。
// index.js import { divide } from "./divide"; console.log(`6 / 2 = ${divide(6,2)}`); if(module.hot) { module.hot.accept(); } // divide.js export function divide(a, b) { return a / b; }
運行module.hot.accept()會讓模塊可熱替換。這同樣適用於它引入的所有其他模塊。上面的代碼意味著,index.js中的accept()讓divide模塊能夠被熱替換。
運行module.hot.accept()函數時可以傳參,如果你感興趣,請查看文檔。
當使用HotModuleReplacementPlugin插件時,如果輸出文件名中使用了chunkhash欄位,就可能會出現一些問題。這種情況下,只在開發環境下使用HotModuleReplacementPlugin是個好主意(而且避免使用chunckhash)。
// webpack.config.js const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const isDevServer = require.main.filename.includes('webpack-dev-server'); const plugins = [ new HtmlWebpackPlugin({ template: './src/index.html' }), ]; if(isDevServer) { plugins.push(new webpack.HotModuleReplacementPlugin()); } module.exports = { output: { filename: isDevServer ? '[name].bundle.js' : '[name].[chunkhash].bundle.js', path: path.resolve(__dirname, 'dist'), }, plugins, devServer: { hot: true } }
webpack-serve
譯者註:由於webpack-serve其實已經不再維護了。推薦仍然使用上面所說的webpack-dev-sever。
mode: "development"
在之前的課程,我們介紹了mode屬性的production值。現在該輪到development了。讓我們看看它為我們做了我們。
DefinePlugin
如之前所說,這個插件允許你創建編譯時的全局常量。
因為這個插件也在mode: produnction中使用,更多信息可查看教程的第五部分。
這次它的值為process.env.NODE_ENV: JSON。stringify("development"):
module.exports = { mode: "development", // 使用 mode: "development" 會添加以下配置: plugins: [ new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), ] }
NamedModulesPlugin
這是在使用mode: "development"時預設加入的另一個插件。它在使用模塊熱替換時很有用。有了NamedModulesPlugin,我們能夠看到被替換模塊的相對路徑。
[WDS] App updated. Recompiling... [WDS] App hot update... [HMR] Checking for updates on the server... [HMR] Updated modules: [HMR] - ./src/style.css [HMR] App is up to date
否則我們只會看到一個id,而不是像./src/style.css這樣的路徑。
NamedChunksPlugin
它的左右和NamedModulesPlugin類似。有了它,不僅模塊能看到名字,chunk也能。當應用在瀏覽器中運行起來是,你可以在window.webpackJsonp屬性中查看它們。
使用NamedModulesPlugin和NamedChunksPlugin的一個額外好處是,當添加和刪除依賴時,打包不再需要使用模塊的順序id。因為這些id和名字會在最終的輸出產物中使用,修改它們會導致文件哈希值的變化,即使這些文件使用的模塊本身並沒有改變。使用以上兩個插件會幫助你處理瀏覽器的緩存問題。讓我們來比較一下代碼:
沒使用NamedModulesPlugin和NamedChunksPlugin:
// 輸出產物 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{ /***/ 6: (...) // divide.js module output code /***/ 7: (...) // substract.js module output code ]);
使用了NamedModulesPlugin和NamedChunksPlugin:
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["utilities~main"],{ /***/ "./src/utilities/divide.js": (...) // divide.js module output code /***/ "./src/utilities/substract.js": (...) // substract.js module output code ]);
Devtool
除了添加插件,設置mode: "development"還做了一件事,即通過設置devtool的值為eval開啟了源碼映射(Source Map)。
// webpack.config.js module.exports = { mode: "development", // 使用 mode: "development:" 添加了以下配置 devtool: "eval" }
轉譯、壓縮和打包你的代碼能讓你的用戶有更好的體驗。經過這些步驟之後,代碼變得更精簡和高效。而調試這樣的代碼則變得非常困難。因此,引入了源碼映射(Source Map)。它們把輸出後的的代碼與源碼對應起來。有了它,相對於瀏覽器真正運行的打包後的輸出,你能看到其對應的源碼,從而更加容易地使用調試工具和設置斷點。我們會在接下來的課程中對源碼映射做進一步介紹,但如果你需要現在就定製它,可查看它的文檔。
總結
Webpack是開發現代Web應用的強大工具。它不僅讓你優化生產環境的代碼,而且還可以並定製,用以增強開發時的體驗。這次我們介紹瞭如何運行開發時伺服器,以及把mode屬性設成development的一些作用。我們還學習使用了模塊的熱替換。所有這些組合起來,能幫你更容易和更快地開發應用。