咱們今天要涉及到把mode屬性設置爲development(時的情形)。這會讓webpack自動配置成更適合開發(時用)。此外,咱們也將涉及到webpack-dev-server和webpack-serve - 其包括了熱模塊替換(譯註:webpack-serve如今已不推薦使用,用好webpack-dev-server就夠了,詳見https://github.com/webpack-co...)。開始吧!javascript
加強開發體驗的一個前置步驟是以觀察模式運行webpack,試着以webpack --watch啓動,如今,每當你作了些修改,webpack就會重建你的項目且輸出相應的信息(譯註: 原文是」and outputs he code「,小小疑惑一下)。而Webpack-dev-server就更強大了,作得更多。(使用Webpack-dev-server時)輸出文件不是寫到磁盤的目標目錄中,而是在內存裏處理。構建以後,這些輸出啓動了一個本地服務器。css
首先要安裝html
npm install webpack-dev-server
其次在package.json中添加腳本java
"scripts": { "build": "webpack", "start": "webpack-dev-sever" }
如今啓動它,只需輸入 npm start(譯註:在前面的教程中,做者寫的啓動腳本的命令形如npm run build,實際上在較高版本的npm中,能夠省略這個run了)。你就會看到下面的信息:webpack
「wds」: Project is running at http://localhost:8080/
剩下的事情就只需你在瀏覽器中打開http://localhost:8080/了git
每當對代碼作了些修改,站點就會獲得更新(由於重建項目了啊),刷新頁面以後,你就會看到這些改變了的效果。github
爲了使開發體驗更佳,能夠使用熱模塊替換來避免老是手動刷新。好比,每當你改變了一些樣式,你無需重載整個應用來觀察改變的效果。web
注意,在教程4中咱們用到了MiniCssExtractPlugin這個插件,到寫這篇文章的時候爲止,MiniCssExtractPlugin還不支持熱模塊替換。更多信息請參考 GitHub issue。所以如今你在開發模式下還需繼續要用到style-loader這個加載器。(譯註:style-loader的做用就是把你的樣式插入到<style>標籤中,在開發模式下,輸出都是放在內存中,所以把css抽取出來仍是放在<style>標籤中,都無所謂了,不用考慮太多)
正規狀況下,webpack-dev-server也是經過同一個配置文件(即webpack.config.js)來運行。能在webpack.config.js中添加一個叫devServer的參數來設置附加的配置選項。咱們在其上啓用熱模塊替換。npm
devServer: { hot: true, }
剩下最後一件事情就是將webpack.HotModuleReplacementPlugin寫到plugins屬性裏。json
// webpack.config.js const webpack = require('webpack'); module.exports = { devServer: { hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }
注意啓動webpack-dev-server時加上 -hot參數也會加載HotModuleReplacementPlugin插件。你要是不經意加載了兩次,可能會給你帶來一些麻煩。
如今工做於CSS中已經很是奏效了,但在javascript中,咱們還須要進一步。
index.js import { divide } from "./divide"; console.log(`6 / 2 = ${divide(6,2)}`); if(module.hot) { module.hot.accept(); }
// divider.js export function divide(a, b) { return a/b; }
運行module.hot.accept()將使得模塊可替換。這也會在它導出的模塊身上起效果。上面的代碼例子意味着在index.js中運行了accept(),則它導出的divide模塊也變成可替換的了。(譯註:咱們在一些開箱即用的框架中每每看到做者爲你配了一個相似dev-client.js的文件,這個文件的做用就是讓後面被它導出的模塊可以熱替換)。
函數module.hot.accept()能夠附加配置來運行,若是感興趣,請參閱 文檔
使用HotModuleReplacementPlugin插件時,若是在輸出文件名中用了chunkhash,會碰到問題。所以,最好HotModuleReplacementPlugin只用在開發服務器中(且不使用chunkhash)。
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官方已不推薦使用,咱們略過這一節的巴拉巴拉)
在前面的教程中,咱們已經涉及了mode爲production時的狀況。如今咱們來看看當其值爲development時,對咱們作了什麼。
就象前面所說的,這個插件建立全局常量編譯時解析。
更多細節講述請參閱教程5。
如今其值是 "process.env.NODE_ENV": JSON.stringify("development") :
module.exports = { mode: "development", // using mode: "development" attaches the following configuration: plugins: [ new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), ] }
這是在設置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)。
NameChunksPlugin插件的做用與NamedModulesPlugin插件有點類似。有了NamedChunksPlugin插件,不但你的模塊有了名字,chunks也有了。 當在瀏覽器中運行應用時,你能在window.webpackJsonp屬性中找到它們。
NamedModulesPlugin和NamedChunksPlugin另一個優點是你無需使用模塊id(ids),ids在增刪依賴時可能會發生變化。由於ids或名字用在實際輸出的文件裏,即便你模塊的內容沒有變化,改變ids或名字也會改變文件的hash。因此使用NamedModulesPlugin和NamedChunksPlugin插件將幫助你更好的應付瀏覽器緩存機制。咱們比較一下輸出代碼。
// Without NamedModulesPlugin and NamedChunksPlugin (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{ /***/ 6: (...) // divide.js module output code /***/ 7: (...) // substract.js module output code ]);
// Using NamedModulesPlugin and 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 ]);
除了加載了一些插件,設置mode: "development"(譯註:原文誤爲production)時還多作了一件事,它經過設置devtool屬性爲eval來啓用源碼映射(Source Maps)。
module.exports = { mode: "development", // using mode: "development" attaches the following configuration: devtool: "eval" }
轉換,醜化,打包你的代碼會讓用戶(體驗)更爽,在這些措施以後,代碼變小了,執行變快了。然而調式這些代碼變困難了。所以,引入了源碼映射機制。它們映射輸出代碼到源文件,使得調式器用起來更簡單及能在源代碼中打斷點。咱們將在接下來的教程中深挖源碼映射,但若是你如今就想去定製,請查閱文檔。
Webpack是開發現代web應用強有力的工具。它不但優化你的產品代碼,也能經過定製的方式來提高開發體驗。這一次咱們涉及到了運行一個開發服務器和設置mode屬性爲development。咱們也學習瞭如何使用熱模塊替換。這些結合起來會大大幫助你更快更容易的開發應用。