webpack(2)——配置項詳解

引子

昨天有關 Webpack 筆記也是有許多人喜好的,因此今天再接再礪彙總了第二篇筆記,歡迎各位指點不足之處。
以後的筆記應該會記錄一些實際開發了,但願在這個週末內完全入門 Webapckcss

  1. webpack (1)——核心概念的理解
  2. webpack(2)——配置項詳解
  3. ...

1. mode

mode 配置項是 webpack4 新增的配置項,這個配置項是必須的。html

若是使用的不是 webpack4 ,該配置項瞭解一下便可,使用了 webpack4 以上版本,也能夠了解一下便可。
事實上它並不是必須的,可是若是忽略它, webpack 會有個警告。vue

該配置項的屬性值類型是 String,並有三個可選項:node

  • production
  • development
  • none

1.1 production 默認值

production 默認值會給你提供一系列有效的默認值以便部署你的應用,它注重:react

  • 小的輸出體積
  • 運行快速的代碼
  • 忽略僅在開發時須要的代碼
  • 不暴露源碼和文件路徑
  • 易於使用的輸出產物

1.2 development 默認值

該默認顧名思義是注重最好的開發體驗,它注重:jquery

  • 瀏覽器調試工具
  • 快速開發週期中的快速增量編譯
  • 在運行過程當中提供有效的錯誤信息

當人對於初學者來講,對於 webpack 的優化還有一段距離,首先咱們大致瞭解一下便可。webpack

它還有不少其餘的優化默認值,可是效果可能並不美好,由於它針對的某些特定的大型項目,而咱們只是入門,因此瞭解便可。web

2. Module

module 中配置處理模塊的規則。正則表達式

2.1 配置 Loader

rules 配置模塊的讀取和解析規則,一般用來配置 Loader。其類型是一個數組,數組裏每一項都描述瞭如何去處理部分文件。配置一項 rules 時大體可經過如下方式來實現:npm

  1. 條件匹配:經過 testincludeexclude 三個配置項來命中 Loader 要應用規則的文件。
  2. 應用規則:對選中後的文件經過 use 配置項來應用 Loader,能夠只應用一個 Loader 或者按照從後往前的順序應用一組 Loader,同時還能夠分別給 Loader 傳入參數。
  3. 重置順序:一組 Loader 的執行順序默認是 從右到左 執行,經過 enforce 選項可讓其中一個 Loader 的執行順序放到最前或者最後。
module: {
  rules: [
    {
      // 命中 JavaScript 文件
      test: /\.js$/,
      // 用 babel-loader 轉換 JavaScript 文件
      // ?cacheDirectory 表示傳給 babel-loader 的參數,用於緩存 babel 編譯結果加快從新編譯速度
      use: ['babel-loader?cacheDirectory'],
      // 只命中src目錄裏的js文件,加快 Webpack 搜索速度
      include: path.resolve(__dirname, 'src')
    },
    {
      // 命中 SCSS 文件
      test: /\.scss$/,
      // 使用一組 Loader 去處理 SCSS 文件。
      // 處理順序爲從後到前,即先交給 sass-loader 處理,再把結果交給 css-loader 最後再給 style-loader。
      use: ['style-loader', 'css-loader', 'sass-loader'],
      // 排除 node_modules 目錄下的文件
      exclude: path.resolve(__dirname, 'node_modules'),
    },
    {
      // 對非文本文件採用 file-loader 加載
      test: /\.(gif|png|jpe?g|eot|woff|ttf|svg|pdf)$/,
      use: ['file-loader'],
    },
  ]
}
複製代碼

上面的例子基本將配置 loader 的大部分配置項都涵蓋了,很是清晰簡潔。

// 使用一組 Loader 去處理 SCSS 文件。
// 處理順序爲從後到前,即先交給 sass-loader 處理,再把結果交給 css-loader 最後再給 style-loader。
use: ['style-loader', 'css-loader', 'sass-loader']
複製代碼

在上面的例子中,對於多 Loader 處理方式中,採用的是數組,執行數序爲從左到右

除此以外,咱們還能夠經過一個 Object 方式來寫這一塊的代碼

use: [
  {
    loader:'babel-loader',
    options:{
      cacheDirectory:true,
    },
    // enforce:'post' 的含義是把該 Loader 的執行順序放到最後
    // enforce 的值還能夠是 pre,表明把 Loader 的執行順序放到最前面
    enforce:'post'
  },
  // 省略其它 Loader
]
複製代碼

對於 Loader 的最後一點補充就是關於命中文件的三個配置項:textincludeexclude

在上述例子中,這三兄弟的配置只傳入了一個字符串或者是正則,其實他們還均可以支持數組,數組之間的關係爲 「或」的關係,即文件知足數組中的任何一個條件,都會被命中。

2.2 noParse

noParse 配置項可讓 Webpack 忽略對部分沒采用模塊化的文件的遞歸解析和處理,這樣作的好處是能提升構建性能。 緣由是一些庫例如 jQueryChartJS 它們龐大又沒有采用模塊化標準,讓 Webpack 去解析這些文件耗時又沒有意義。

noParse 是可選配置項,類型須要是 RegExp、[RegExp]、function 其中一個。

// 使用正則表達式
noParse: /jquery|chartjs/

// 使用函數,從 Webpack 3.0.0 開始支持
noParse: (content)=> {
  // content 表明一個模塊的文件路徑
  // 返回 true or false
  return /jquery|chartjs/.test(content);
}
複製代碼

注意被忽略掉的文件裏不該該包含 import 、 require 、 define 等模塊化語句,否則會致使構建出的代碼中包含沒法在瀏覽器環境下執行的模塊化語句。

2.3 parse

由於 Webpack 是以模塊化的 JavaScript 文件爲入口,因此內置了對模塊化 JavaScript 的解析功能,支持 AMD、CommonJS、SystemJS、ES6。 parser 屬性能夠更細粒度的配置哪些模塊語法要解析哪些不解析,和 noParse 配置項的區別在於 parser 能夠精確到語法層面, 而 noParse 只能控制哪些文件不被解析。 parser 使用以下:

module: {
  rules: [
    {
      test: /\.js$/,
      use: ['babel-loader'],
      parser: {
      amd: false, // 禁用 AMD
      commonjs: false, // 禁用 CommonJS
      system: false, // 禁用 SystemJS
      harmony: false, // 禁用 ES6 import/export
      requireInclude: false, // 禁用 require.include
      requireEnsure: false, // 禁用 require.ensure
      requireContext: false, // 禁用 require.context
      browserify: false, // 禁用 browserify
      requireJs: false, // 禁用 requirejs
      }
    },
  ]
}
複製代碼

3. Resolve

該配置項主要是配置 Webapck 如何尋找模塊所對應的文件。
Webpack 內置 JavaScript 模塊化語法解析功能,默認會採用模塊化標準里約定好的規則去尋找,但你也能夠根據本身的須要修改默認的規則。

該配置項的屬性蠻多的,可是我以爲我能用獲得的也就幾個=。=

3.1 alias

resolve.alias 配置項經過別名來把原導入路徑映射成一個新的導入路徑。例如使用如下配置:

// Webpack alias 配置
resolve:{
  alias:{
    components: './src/components/'
  }
}
複製代碼

當你經過 import Button from 'components/button' 導入時,實際上被 alias 等價替換成了 import Button from './src/components/button'

以上 alias 配置的含義是把導入語句裏的 components 關鍵字替換成 ./src/components/

這樣作可能會命中太多的導入語句,alias 還支持 $ 符號來縮小範圍到只命中以關鍵字結尾的導入語句:

resolve:{
  alias:{
    'react$': '/path/to/react.min.js'
  }
}
複製代碼

react$ 只會命中以 react 結尾的導入語句,即只會把 import 'react' 關鍵字替換成 import '/path/to/react.min.js'

該方法的應用場景有待我去探索,真不太清楚這樣替換的緣由。
可是我以爲是蠻有用的。

3.2 extensions

在導入語句沒帶文件後綴時,Webpack 會自動帶上後綴後去嘗試訪問文件是否存在。 resolve.extensions 用於配置在嘗試過程當中用到的後綴列表,默認是:

extensions: ['.js', '.json']

這個配置項應該有用,在處理 TypeScriptvue 這些文件的時候,能夠設置一下

3.3 enforceExtension

resolve.enforceExtension 若是配置爲 true 全部導入語句都必需要帶文件後綴, 例如開啓前 import './foo' 能正常工做,開啓後就必須寫成* import './foo.js'。*

對於 Resolve 的其餘配置項,大致瞭解一下便可,我以爲可能用的不是特別多。

3.4 Plugins

對於 Plugins 的使用,上一節也寫到過,仍是那句話吧:

使用 Plugin 的難點在於掌握 Plugin 自己提供的配置項,而不是如何在 Webpack 中接入 Plugin。

4. DevServer

使用 DevServer 能幹啥?

  • 提供 HTTP 服務來預覽本地文件;
  • 監聽文件的變化並自動刷新頁面;
  • 支持 Source Map,以方便調試。

DevServer 會啓動一個 HTTP 服務器 用於服務網頁請求,同時會幫助啓動 Webpack,並接收 Webpack 發出的文件更新信號,經過 webSocket 協議自動刷新網頁作到實時預覽。

4.1 開啓一個DevServer 服務

集成 DevServer ,首先須要安裝一下:

npm i -D webpack-dev-server
複製代碼

若是不是經過 npm run 啓動,直接將 webpack-dev-server 安裝到全局,直接使用,會報: webpack-dev-server: command not found

安裝成功後,執行 webpack-dev-server 命令,接着一連串日誌輸出:

i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wdm」: Hash: 5cece8a0d7243a4cf1ba
Version: webpack 4.8.3
Time: 1627ms
Built at: 2018-05-18 14:18:57

......
複製代碼

4.2 ./dist/bundle.js 加載 404 問題

用瀏覽器直接打開這個地址你會發現頁面空白,錯誤緣由是 ./dist/bundle.js 加載404了。 同時你會發現並無文件輸出到 dist 目錄,緣由是 DevServer 會把 Webpack 構建出的文件保存在內存中,在要訪問輸出的文件時,必須經過 HTTP 服務訪問。 因爲 DevServer 不會理會 webpack.config.js 裏配置的 output.path 屬性,因此要獲取 bundle.js 的正確 URLhttp://localhost:8080/bundle.js

4.3 實時預覽

webpack --watch 會開啓監聽模式,而 webpack 啓動默認是關閉的,開啓 DevServer 默認開啓監聽模式,因此修改須要被打包的文件瀏覽器會被自動刷新,這裏主要應用到了 Websocket ,有須要的童鞋能夠去了解一下。

4.4 修改index.html並不會被刷新的緣由

若是嘗試修改 index.html 文件並保存,你會發現這並不會觸發以上機制,致使這個問題的緣由是 Webpack 在啓動時會以配置裏的 entry 爲入口去遞歸解析出 entry 所依賴的文件,只有 entry 自己和依賴的文件纔會被 Webpack 添加到監聽列表裏。 而 index.html 文件是脫離了 JavaScript 模塊化系統的,因此 Webpack 不知道它的存在。

能夠嘗試用 raw-loader 來處理一下 html

4.5 熱更新 --hot

固然上述實現頁面更改都是基於頁面刷新實現的,DevServer 還有一種被稱做模塊熱替換的刷新技術——熱更新。

DevServer 默認是關閉熱更新的,能夠經過

webpack-dev-server --hot
複製代碼

來開啓

4.6 Source Map

webpack-dev-server --devtool source-map
複製代碼

這個功能就很少說了。

4.7 devserver 配置項

plugins: [
    new webpack.HotModuleReplacementPlugin()
],
devServer: {
    hot: true,
    open: 'http://127.0.0.1:9000',
    // inline: true,
    // contentBase: path.join(__dirname, "dist"),
    compress: true,
    port: 9000
}
複製代碼

devServer 的配置項也是蠻多的,看了很久,發現有用的也就是這幾個吧:

  • hot: 開啓熱更新;
  • open:自動打開要開發的網頁;
  • inline:實時預覽功能,即頁面刷新,用熱更新替代便可,不必管他;
  • compress: 開啓 Gzip 壓縮;
  • port:服務器監聽的端口號,指定便可,若是不指定,默認是 8080 ,衝突了會自動順位 808一、8082,挺讚的。

該配置項還有不少其餘的屬性,我以爲目前我是用不上,但不妨礙咱們瞭解一下,在此我就不一一記錄了。

寫在最後

webpack 的基本操做到目前爲止基本結束,他能完成的功能仍是有不少的,從它的 N 多配置項就能看出來,但咱們不須要所有記住,記住以前的核心概念和它的基本原理就能夠,以後再根據本身的經驗去判斷它屬於哪一塊再去查文檔就沒問題。

  • 讓源文件加入到構建流程中去被 Webpack 控制,配置 entry。
  • 自定義輸出文件的位置和名稱,配置 output。
  • 自定義尋找依賴模塊時的策略,配置 resolve。
  • 自定義解析和轉換文件的策略,配置 module,一般是配置 module.rules 裏的 Loader。
  • 其它的大部分需求可能要經過 Plugin 去實現,配置 plugin。

參考

webpack4:模式與優化
深刻淺出 Webpack
webpack 配置項
[HMR] Hot Module Replacement is disabled
Gzip

相關文章
相關標籤/搜索