webpack4 經常使用配置項使用整理

mode

type: stringjavascript

模式配置,webpack 可根據不一樣的模式選擇不一樣的 內置優化過程css

production: "生產模式"。 當前模式下,部分配置項的默認值以下:html

  • devTool 配置項的值爲 false,不生成 .map 文件 ;vue

  • cache 配置項的值爲 false,即 webpack 上一次編譯生成的 moduleschunks 不被緩存,每次編譯的時候須要從新生成 moduleschunksjava

  • output.pathinfo 配置項的值爲 false, ***;node

  • optimization.flagIncludedChunks 配置項的值爲 true,用於標記 子chunk, 詳見下面描述;react

  • optimization.occurrenceOrder 配置項的值爲 true, 告訴 webpack 找出 module 的順序,致使最小的初始包(僅字面意思,未理解);jquery

  • optimization.sideEffects 配置項的值默認爲 true, 用於移除 JavaScript上下文 中的 未引用代碼(dead-code);webpack

  • optimization.usedExports 配置項的值爲 true, 告訴 webpack 肯定每一個 module 已使用的導出, 爲 使用的導出 生成 導出;web

  • optimization.concatenateModules 配置項的值爲 true, 用於鏈接多個module爲一個module;

  • optimization.splitChunks.minSize 配置項的值爲 30kb,若是將 被分離出的chunk的大小 小於 minSize 值, 代碼分離失敗

  • optimization.splitChunks.maxAsyncRequests 配置項的值爲 5, 即按序加載時容許的最大並行請求數爲 5, 不然代碼分離會失敗;

  • optimization.splitChunks.maxInitialRequests 配置項的值爲3,即入口處的最大並行請求數爲 3, 不然代碼分離失敗;

  • optimization.noEmitOnErrors 的值爲 true,若是編譯錯誤,不輸出打包文件(??);

  • optimization.minimize 配置項的值爲 true,對打包文件進行 壓縮混淆

development: "開發模式"。當前模式下,部分配置項的默認值以下:

  • devTool 配置項的值默認爲 "eval", 使用 eval() 包裹模塊代碼;

  • cache 配置項的值默認爲 true。 webpack 上一次編譯生成的 modules、chunks 都會緩存在 內存 中,當源文件發生變化從新編譯構建模塊依賴圖時,若是模塊對應的文件沒有變化,則直接使用內存中緩存的 module,大大的減小編譯時間;

  • output.pathinfo 配置項的值爲 true, ***;

  • optimization.splitChunks.maxAsyncRequests 配置項的值爲 Infinity,對按需加載時容許的最大並行請求數不作限制;

  • optimization.splitChunks.maxInitialRequests 配置項的值爲 Infinity,對入口處容許的最大並行請求數不作限制;

  • optimization.splitChunks.minSize 配置項的值爲 10kb,若是將 被分離出的chunk的大小 小於 minSize 值, 代碼分離失效

  • optimization.namedModules 配置項的值爲 true,打包文件中以 模塊源文件的路徑(url) 做爲 模塊標識符

  • optimization.namedChunks 配置項的值爲 true,打包文件中以 chunk的名稱 做爲 chunk標識符

若是未配置 mode, 默認狀況下爲 "production"。

context

type: string

基礎目錄絕對路徑,用於從配置中解析 入口起點(entry point)loader

context: path.resolve(__dirname, '../')
複製代碼

entry

type: string | [string] | object { : string | [string] } | function

應用程序的入口。 從這個起點開始,應用程序啓動執行。

若是 entry 配置項的值的類型爲 string, 對應 單頁面單入口應用。在編譯過程當中, 生成 一個模塊依賴關係圖

若是 entry 配置項的值的類型爲 [string], 對應 單頁面多入口應用。應用程序啓動時,數組中的入口文件按序執行。在編譯過程當中,生成 一個模塊依賴關係圖

若是 entry 配置項的值爲 object, 對應 多頁面(單入口/多入口)應用。在編譯過程當中,生成 多個模塊依賴關係圖

若是 entry 配置項的值的類型爲 function,則是 動態入口(待研究)。

Resolve

type: object

Resolve配置項 能夠設置 源文件npm包 如何被 解析

webpack構建依賴關係圖 時會經過 resolve 配置項 解析模塊的url 來獲取 模塊源文件的絕對地址。 經過 源文件的絕對地址,讀取源文件的內容,而後使用 解析器(parser) 解析源文件的代碼結構,獲取 依賴模塊

此外,webpack 使用 loader 處理 源文件 時,也會經過 resolve 配置項 解析 loader包 的 入口文件 的絕對地址,而後使用 入口文件 提供的方法處理 源文件 內容。

webpack 會提供 合理的默認值,若是不知足須要,咱們也能夠本身設置 Resolve配置項

  • alias | object

    建立 importrequire 的別名, 確保模塊引入變的更加簡單。

    建立模塊 的時候, webpack 會解析模塊的 請求路徑(request path)。若是 請求路徑 中使用了 別名webpack 會根據 resolve.alias 配置項,將 請求路徑(request path) 轉化爲 源文件的絕對路徑

    用法詳見 官網

  • aliasFields | [string]

    指定一個字段,根據此規範進行解析, 默認值爲 ["browser"]

  • descriptionFiles

    用於描述的 JSON 文件,默認值爲 ["package.json"]

    使用npm包時, 能夠經過 package.json文件 獲取 npm包入口文件

  • enforceExtension | boolean

    是否 強制須要文件擴展名。 默認值爲 false, 即 不須要

    若是值爲 true,則 不容許無擴展名文件,不然 報錯

    // main.js
    import { func1 } from '../util.1.js' 
    import { func2 } from '../util.2' // enforceExtension:true, 解析模塊路徑會報錯
    複製代碼
  • enforceModuleExtension | boolean

    對模塊是否須要使用的擴展, 默認爲 false

  • extensions | [string]

    自動解析的擴展, 默認值爲 [".wasm", ".mjs", ".js", ".json"]

  • mainFields | [string]

    當從 npm包 中導入 模塊 時(例如,import * as D3 from "d3"),此選項將決定在 package.json 中使用 哪一個字段 導入模塊。

    若是 target配置項 的值爲 webworker, web 或者 沒有指定,默認值爲:["browser", "module", "main"]

    對於 其餘任意的 target(包括 node),默認值爲:["module", "main"]

    用法詳見 官網

  • mainFiles | [string]

    解析目錄時要使用的文件名,默認值: ["index"]

  • modules | [string]

    告訴 webpack 解析模塊時應該搜索的 目錄

    數組中指定的目錄的 優先級: 高 -> 低

    默認值: ["node_modules"]

    webpack 在解析 npm包 的路徑時,會在工做目錄下的 node_modules 目錄中查找。

    用法詳見 官網

  • unsafeCache | regex | array | boolean

    是否啓用 緩存, 默認值爲 true

    若是值爲 true啓用 ; 若是值爲 false禁用

    webpack 在解析 模塊npm包入口文件 路徑時,會把 解析結果(文件絕對路徑、描述文件package.json信息等) 緩存起來。等到下次解析 相同模塊、npm包 時, 直接使用緩存。

  • cacheWithContext | boolean

    若是啓用了 unsafeCache,緩存解析結果的 cachekey 中會包含 context配置項 指定的信息。

    默認值爲 false

  • plugins | [object]

    使用的額外的 解析插件

  • symlinks | boolean

    是否將符號連接(symlink)解析到它們的符號連接位置(symlink location)。

    默認值爲 true

    暫未理解。

  • cachePredicate | function

    指定一個 自定義函數,用於判斷 源文件npm包解析結果 是否會被 緩存

    若是返回 false, 即便 unsafeCache 的值爲 true, 解析結果也 不會被緩存

    自定義函數使用時會傳入一個帶有 請求信息對象

    resolve: {
            cachePredicate: function(params) {
                // params.path 對應 context 配置項的值
                // params.request 對應 請求path : './src/utils/util.1.js'
                return /\/src/.test(params.request)
            }
        }
        
    複製代碼

resolveLoader

type: object

resolveLoader配置項 用法和 resolve配置項 徹底一致, 區別是它 用於 解析webpack的loader包

即當 webpack 須要解析 loader包入口文件 時,纔會用到 resolveLoader配置項

默認值

{
        cacheWithContext: false,
        unsafeCache: true,
        extensions: ['.js', '.json'],
        mainFields: ['loader', 'main'],
        mainFiles: ['index']
        
    }
複製代碼
  • moduleExtensions | ['string']

    解析 loader 時,用到 擴展名(extensions)/後綴(suffixes)

    具體用法以下:

    {
        module: {
            rules: [{
                test: /\.(css|scss)$/,
                loaders: ['css']
            }]
        },
        resolveLoader: {
            moduleExtensions: ['-loader']
        }
        ...
    }
    複製代碼

module

type: object

用於處理項目中的 不一樣類型(.js、.css、.sass、.vue、.png ...) 的模塊。

  • noParse | RegExp | [RegExp] | function

    在構建 依賴關係圖 時,webpack 會讀取 模塊源文件 的內容,而後 將源文件內容解析成一顆AST樹。 分析 AST樹,獲取模塊的 依賴靜態模塊懶加載模塊全局變量

    若是 模塊的url(絕對路徑) 匹配 noParse配置項指定的表達式, 那麼 模塊對應的源文件的代碼結構 不會被解析。 不解析大型的library能夠 提升構建性能

    不解析的模塊源文件中不該該含有 importrequiredefineurl全局變量 等。

    用法:

    module: {
        noParse: /vue|loadsh/
    }
    
    module: {
        // content 爲模塊源文件的絕對路徑
        // vue-D:\study\demo\webpack\webpack-4-demo\node_modules\_vue@2.6.10@vue\dist\vue.runtime.esm.js" noParse: function(content) { return /vue|loadsh/.test(content) } } 複製代碼

    效果:

    // noParse: /vue/
    
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["vendors-main"],{
        "./node_modules/_vue@2.6.10@vue/dist/vue.runtime.esm.js":
            (function(module, __webpack_exports__, __webpack_require__) {...})
    }])
    
    
    
    // 不使用 noParse
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["vendors-main"],{
        "./node_modules/_process@0.11.10@process/browser.js": 
            (function(module, exports) {...}),
        "./node_modules/_setimmediate@1.0.5@setimmediate/setImmediate.js":
            (function(module, exports, __webpack_require__) {...}),
        "./node_modules/_timers-browserify@2.0.10@timers-browserify/main.js":
            (function(module, exports, __webpack_require__) {...}),
        "./node_modules/_vue@2.6.10@vue/dist/vue.runtime.esm.js":
            (function(module, __webpack_exports__, __webpack_require__) {...}),
        "./node_modules/_webpack@4.34.0@webpack/buildin/global.js":
            (function(module, exports) {...})
    }])
    
    複製代碼

    若是 不使用noParsevue.js 在構建 依賴關係圖 時會被 解析爲AST樹,獲取 vue 依賴的全局變量 globalsetImmediate,而後構建相應的模塊。"browser"、"setImmediate"、"main"、"global" 就是解析vue模塊生成的模塊。若是使用了 noParse: /vue/, vue模塊不會被解析,全局變量對應的模塊也不會生成。

  • rules | [object]

    模塊(module) 構建時, 若是 源文件url(絕對路徑) 匹配 module.rules 中的規則, 那麼 匹配規則 將會 修改 模塊的建立方式。匹配規則 可以對 模塊(module) 應用 loader,或者 修改解析器(parser)

    module.rules 是一個 arrayrules 中的每個 rule 是一個 object

    每個 規則(rule) 能夠分紅三部分:條件(conditions)結果(results)嵌套規則(nested rules)

    條件(conditions)輸入值 有兩種:

    1. resource - 源文件的path(絕對路徑);

    2. issuer - 發佈者( issuer - A中引入B,則A是B的issuer )的path(絕對路徑)

    若是 moduleresource屬性 匹配 rule.testrule.includerule.excluderule.resource, 或者 moduleissuer 屬性匹配 rule.issuer, 則 模塊匹配當前規則rule, 可使用 rule中的loader 處理模塊。

    結果(results)輸出值 有兩個:

    1. loader - 應用在 resource 上的 loader數組,將 源文件 轉化爲 瀏覽器可識別的文件類型;

    2. parser option - 用於構建parser(將源文件代碼解析爲AST結構, 分析源文件的依賴)

    嵌套規則(nested rules) :

    可使用屬性 rulesoneOf 指定 嵌套規則。這些規則用於在 規則條件(rule condition)匹配 時進行取值。

    一個 模塊 只有知足 規則(rule)條件(conditions),才能拿到 規則(rule)對應的結果(loader、parser options)處理模塊

    rule 的配置項以下:

    • resource | object

      規則(rule)條件(condition)配置項。若是 模塊path(絕對路徑) 符合 條件(condition),將使用 當前規則對應的loaders處理模塊。

      • test | RegExp | string | function | [RegExp] | [string] | [function]

        條件配置項,不考慮其餘配置項的狀況下,若是 模塊path(絕對路徑)知足 test 指定條件,則 匹配 當前規則。

        test 的值通常爲 正則表達式,經過 文件後綴 來判斷模塊是否匹配規則。

        test: /\.css$/
        複製代碼

        test 的值也能夠是 string, 若是 模塊path(絕對路徑)包含test指定的值(path.indexOf(test) === 0), 則模塊匹配當前規則。

        // test的值必須是絕對路徑
        test: path.resolve(__dirname, '../src')
        
        // 因爲模塊path是絕對路徑,path.indexOf('src') !== 0, 不匹配
        test: 'src'
        複製代碼

        若是 test 的值是 string 類型,則必須是 絕對路徑

        test 的值也能夠是 function,用戶可 自定義條件

        test: function(request) {
            return /\.css$/.test(request)
        }
        複製代碼

        若是 test 的值是一個 array( [RegExp]、[string]、[function] ), array條件 之間的關係爲 ,只要 模塊path(絕對路徑) 知足 test中的某一個條件,那麼模塊就匹配當前規則。

      • include | RegExp | string | function | [RegExp] | [string] | [function]

        條件配置項,不考慮其餘配置項的狀況下,若是 模塊path(絕對路徑)知足指定條件,則 匹配 當前規則, 用法和test徹底一致

      • exclude | RegExp | string | function | [RegExp] | [string] | [function]

        條件配置項,不考慮其餘配置項的狀況下,若是 模塊path(絕對路徑)不知足指定條件,則 匹配 當前規則。

        exclude的用法和test基本相同, 惟一的區別是若是 exclude 的值是一個 array( [RegExp]、[string]、[function] ), array條件 之間的關係爲 ,只有 模塊path(絕對路徑) 不知足 exclude中的全部條件,模塊才能匹配當前規則。

      在實際應用中, test 通常配合 include 或者 exclude 使用,test指定文件類型include或者exclude指定範圍

      另外,testincludeexclude 之間的關係是 模塊path(絕對路徑)必須所有知足,才能匹配當前規則。

    • test

      Rule.testRule.resource.test縮寫

      注意,使用 Rule.test 以後就不能再使用 Rule.resource,不然會 報錯

      // 這種也是不容許的
      {
          test: /\.js$/,
          resource: {
              include: [path.resolve(__dirname, '../src')]
          }
      }
      複製代碼
    • include

      Rule.includeRule.resource.include縮寫

      注意,使用 Rule.include 以後就不能再使用 Rule.resource,不然會 報錯

    • exclude

      Rule.excludeRule.resource.exclude縮寫

      注意,使用 Rule.exclude 以後就不能再使用 Rule.resource,不然會 報錯

    • issuer

      不考慮其餘配置項的狀況下,若是 模塊的發佈者(issuer)的path(絕對路徑) 知足 issuer 指定的條件,那麼模塊匹配當前規則。

      即,模塊B模塊A 引用, 若是 模塊A(issuer) 知足 issuer 指定的條件, 那麼 模塊B 匹配當前規則。

      這個選項能夠用來將 loader 應用到一個特定模塊或一組模塊的依賴中

      Rule.issuer 的用法和 Rule.test 徹底一致。

    • resourceQuery

      不考慮其餘配置項的狀況下,若是 模塊path(絕對路徑)query參數 知足 resourceQuery 指定的條件, 那麼模塊匹配當前規則。

      // main.js
      import A from './styles/style.css?inline'
      
      // webpackConfig.js
      module: {
          rules: [{
              test: /\.css$/,
              resourceQuery: /inline/
              // resourceQuery: 'inline'   '?inline'.indexOf('inline') !== 0, 匹配失敗
          }]
      }
      複製代碼

      resourceQuery配置項 的用法和 test配置項 的用法 徹底同樣

      須要注意的是,在匹配的時候,會拿 模塊path(絕對路徑)query 部分, 即 '?inline', 與 resourceQuery 對應的值作比較。 若是 resourceQuery 的值爲 string,匹配規則爲 query.indexOf(resourceQuery) === 0resourceQuery 提供的值必定要 精確,才能匹配成功。

      通常狀況下, resourceQuery配置項 的值爲 RegExp 或者 function

    • use | object | [object] | string | [string] | function

      指定應用於模塊的 loader

      模塊path(絕對路徑) 匹配 規則條件(rule conditions) 時,可以使用 use配置項指定的loaders 處理模塊。

      use配置項 的值能夠是一個 object,具體屬性以下:

      • loader | string

        指定使用的 loader名稱, 例 loader: 'css-loader'

        loader 屬性是 必要屬性, 缺乏會報錯。

      • options | object

        指定 loader配置項調整loader的行爲

      • query | object

        指定 loader配置項調整loader的行爲

        query配置項 的做用和 options 同樣, 兩者只需一個。同時存在會報錯

      use: {
              loader: 'css-loader',
              options: {
                  minimize: true
              }
          } 
      複製代碼

      use配置項 的值也能夠是一個 string, 如:

      use: 'css-loader?minimize=true'
          
          // 在 webpack 處理過程當中,會轉化爲一個 object
          {
              loader: 'css-loader',
              options: {
                  minimize: true
              }
          } 
      複製代碼

      use配置項 的值也能夠是一個 [object], 每個 object 含有 loaderoptions/query 屬性;

      use: [{
              loader: 'style-loader'
          }, {
              loader: 'css-loader',
              options: {
                  minimize: true
              }
          }]
      複製代碼

      use配置項 的值也能夠是一個 **[string]****, 如:

      use: ['style-loader', 'css-loader']
      複製代碼

      若是 use 配置項的值爲 array,即 存在多個loaderwebpack會倒序使用loader處理模塊。例如, use: ['style-loader', 'css-loader'], webpack 會先使用 css-loader,再使用 style-loader

      use配置項 的值也能夠是一個 function,具體使用參照 官網

    • loader | string

      rule.loaderrule.use: [{loader}] 的縮寫。

      loader: 'css-loader'  // 至關於 use: [{loader: ‘css-loader’}]
          
          loader: 'style-loader!css-loader' // 至關於 use: [{loader: ‘style-loader’}, {loader: ‘css-loader’}]
      複製代碼
    • loaders

      rule.loadersrule.use 的別名,用法和 rule.use 徹底一致。

      rule.loaderrule.loaders 只須要提供一個就夠了,不然會報錯。

    • options | object

      指定 loader配置項調整loader的行爲

      options配置項必須配合loader配置項 使用, 不然報錯。

      rules: [{
          test: /\.css$/,
          loader: 'css-loader',
          options: {
              minimize: true
          }
      }]
      
      // 等價於: 
      rules: [{
          test: /\.css$/,
          use: [{
              loader: 'css-loader',
              options: {
                  minimize: true
              }
          }]
      }]
      複製代碼

      若是loader 爲 'style-loader!css-loader' 這種格式, 使用options會報錯。

      同時使用 loadersoptions 會報錯。

      即只有 rule 使用 單一loader 時,才能使用 options

    • query | object

      rule.query 用法和 rule.options 徹底一致。

    • rules | [object]

      嵌套規則(nested rules)

      rule.rules 的用法和 module.rules 的徹底一致。

      示例:

      module: {
          rules: [{
              test: /\.(css|scss)$/,
              loaders: ['style-loader', 'css-loader'],
              rules: [{
                  test: /\.scss$/,
                  loader: 'sass-loader'
              }]
          }]
      }
      複製代碼

      在上述例子中, .css文件 使用 css-loaderstyle-loader 處理, .scss文件 會使用 scss-loadercss-loaderstyle-loader 處理。

      注意: 若是 外層規則(rule) 和 嵌套規則(nested rules) 都有 loader,嵌套規則 的 loader 先於 外層規則 的 loader 運行

    • oneOf | [obj]

      規則數組,僅使用 第一個匹配的規則 做用於模塊。

      示例:

      // webpackConfig.js
      module: {
          rules: [{
              test: /\.css$/,
              oneOf: [{
                  resourceQuery: /inline/,
                  loader: 'url-loader'
              }, {
                  resourceQuery: /external/,
                  loader: 'file-loader'
              }, {
                  loader: ['style-loader', 'css-loader']
              }]
          }]
      }
      
      
      // main.js
      import A from './styles/style.css?inline'
      複製代碼

      上面的例子中, 模塊 A 匹配 oneOf 中的 第一個規則 ,即便用 url-loader 處理源文件,不會再使用 css-loaderstyle-loader 處理。

      注意: 若是 外層規則(rule) 和 oneOf 都有 loader,oneOf 的 loader 先於 外層規則 的 loader 運行

    • type | string

      用於設置 匹配模塊的類型,常見的值爲:'javascript/auto''javascript/dynamic''javascript/esm''json''webassembly/experimental'

      構建 parser 會使用這個屬性,做用 ???

    • enforce | string

      指定 loader 的種類, 可能的值爲:"pre" | "post"

      若是 未指定值,則爲 normal loader

      webpack 中, loader 可分爲四類( 按優先級排序): pre loaderinline loadernormal loaderpost loader

      rules: [{
              test: /\.scss$/,
              loader: 'sass-loader'
          }, {
              test: /\.scss$/,
              loader: 'css-loader'
          }, {
              test: /\.scss$/,
              loader: 'style-loader'
          }]
      複製代碼

      若是未使用 enforce屬性 指定 loader優先級module收集的loaders 將按照 定義順序倒序執行。 在上面的示例中,對於 .scss 文件, loaders 順序爲 style-loadercss-loadersass-loader,會致使 編譯報錯

      rules: [{
              test: /\.scss$/,
              loader: 'sass-loader',
              enforce: 'pre'
          }, {
              test: /\.scss$/,
              loader: 'css-loader'
          }, {
              test: /\.scss$/,
              loader: 'style-loader',
              enforce: 'post'
          }]
      複製代碼

      使用 enforce屬性 後, loaders 順序爲 css-loaderstyle-loadersass-loader, 編譯成功。

      內聯loader

      // loader順序很重要
      import css from 'style-loader!css-loader!sass-loader!./styles/style.scss'
      複製代碼

      全部 normal loader 能夠經過在 請求 中加上 ! 前綴來忽略(覆蓋)。

      全部 normal loaderpre loader 能夠經過在 請求 中加上 -! 前綴來忽略(覆蓋)。

      全部 normal loaderpre loaderpost loader 能夠經過在 請求 中加上 !! 前綴來忽略(覆蓋)。

      rules: [{
          test: /\.scss$/,
          loader: 'sass-loader',
          enforce: 'pre'
      }, {
          test: /\.scss$/,
          loader: 'css-loader'
      }, {
          test: /\.scss$/,
          loader: 'style-loader',
          enforce: 'post'
      }]
      
       // 不使用css-loader處理
      import css from '!./styles/style.scss' 
      
      // 不使用css-loader、sass-loader處理
      import css from '-!./styles/style.scss' 
      
      // 不使用sass-loader、css-loader、style-loader處理
      import css from '!!./styles/style.scss' 
      
      複製代碼
    • parser | object

      解析器配置項,用於構建解析當前模塊的 parser

      ???

    • sideEffects

      指示模塊的哪些部分包含反作用, 詳見 tree shaking

    • resolve | object

      能夠在 模塊級別 配置 解析(resolve), 詳見 官網(webpack.js.org/configurati…)。

optimization

type: object

webpack4 會根據用戶選擇的模式 mode 進行優化。咱們能夠 手動設置optimization 覆蓋webpack的默認配置來進行優化。

  • minimize | boolean

    告訴 webpack 使用 TerserPlugin 最小化打包文件,對打包文件進行 壓縮混淆production模式 下, 默認爲 true

  • minimizer

    容許用戶提供 一個或多個自定義TerserPlugin實例 去覆蓋 默認的TerserPlugin實例

    實際用法詳見 官方文檔

  • splitChunks | object

    一個 配置對象,指引 splitChunkPlugin 進行 代碼分離

    默認狀況下,會將 第三方模塊(node_modules)被至少2個chunk共享的module 分離爲新的 chunk

    • automaticNameDelimiter | string

      默認狀況下,若是未指定代碼分離的 chunkname, webpack會爲分離的chunk自動生成 name

      例如, 從 main chunk 分離出 vendors chunk 時, 若是未指定 vendors chunkname, 新生成的 chunk 的名稱爲 'vendors~main'

      automaticNameDelimiter 屬性會指定生成的名稱之間的 鏈接符, 默認爲 '~'

    • automaticNameMaxLength | number

      生成的chunk名稱字符串的最大長度, 默認爲 109

      注意: webpack4 最新版本中,該屬性已廢棄。

    • chunks | string | function(chunk)

      代表能夠選擇哪些 chunks 中的 modules 進行分離,默認值爲 'async'

      代碼分離以前,源文件會編譯打包成兩類 chunkinitial chunk (入口文件所在的chunk)async chunk (懶加載module所在的chunk)。代碼分離,就是把一些知足分離條件的 module所在的chunk分離出來,而後從新生成 新的chunkchunks 會告訴咱們分離的時候,module 應該從哪類 chunk 中選擇。

      若是chunks的值爲 'async', 則只能選擇 async chunk 中的 module 作代碼分離;

      若是chunks的值爲 'initial', 則只能選擇 initial chunk 中的 module 作代碼分離;

      若是chunks的值爲 'all', 能夠選擇全部的 chunk(async chunk 和 initial chunk) 中的 module 作代碼分離;

      咱們也能夠經過自定義一個 function,來篩選chunk進行優化(詳見官網)。

    • maxAsyncRequests | number

      按需加載 時的 最大容許並行請求數

      production模式 下爲 5development模式 下爲 Infinity(不作限制)

      咱們經過一個簡單的例子來解釋:

      // webpack.js
      {
          mode:'production',
          entry: {
            'main': './src/main.js',
          },
          optimization: {
              splitChunks: {
                  chunks: 'all'
                  maxAsyncRequests: 1, // 生產模式下, 默認爲 5
                  minSize: 10,
                  cacheGroups: {
                      common: {
                          name: 'common'
                          minChunks: 2,
                          priority: 0
                      }
                  }
              }
          },
          ...
      }
      
      // main.js
      import(/* webpackChunkName: "exp1" */ './examples/example.1.js')
      import(/* webpackChunkName: "exp2" */ './examples/example.2.js')
      
      // example.1.js
      import { func1 } from '../utils/util.1'
      export const example1 = () => {
          func1()
          console.log('example1')
      }
      
      
      // example.2.js
      import { func1 } from '../utils/util.1'
      export const example2 = () => {
          func1()
          console.log('example2')
      } 
      複製代碼

      第一步,webpack會根據 入口文件main 生成 initial chunk - main chunk

      第二步,從 initial chunk 中分離出 async chunk - exp1 chunk 和 exp2 chunk

      第三步,使用 splitChunkPluginexp1 chunkexp2 chunk 中的 共享module - func1 分離出來(依據common - cache group)。 這樣 main.js 中動態加載 example.1.js的時候,須要加載 common chunkexp1 chunk

      因爲 maxAsyncRequests 的 值爲 1, 即 按需加載example.1.js 的時候,容許的最大並行請求爲 1, 則 代碼分離失敗,沒法將 func1 moduleexp2 chunk 分離出來。

    • maxInitialRequests | number

      入口點處最大並行請求數

      production模式 下爲 3development模式 下爲 Infinity(不作限制)

      咱們經過一個簡單的例子來解釋:

      // webpack.js
      {
          mode:'production',
          entry: {
            'main1': './src/main.1.js',
            'main2': './src/main.2.js'
          },
          optimization: {
              splitChunks: {
                  chunks: 'all'
                  maxInitialRequests: 2, // 生產模式下, 默認爲3
                  minSize: 10,
                  cacheGroups: {
                      vendors: {
                          name: 'vendors',
                          test: /[\\/]node_modules[\\/]/,
                          priority: 10
                      },
                      common: {
                          name: 'common'
                          minChunks: 2,
                          priority: 0
                      }
                  }
              }
          },
          ...
      }
      
      // main.1.js
      import Vue from 'vue'
      import { func1 } from './utils/util.1.js'
      
      ...
      
      
      // main.2.js
      
      import Vue from 'Vue'
      import { func1 } from './utils/util.1.js'
      import { func2 } from './utils/util.2.js'
      
      ...
      複製代碼

      上述例子是一個簡單的多頁面應用。

      第一步, webpack 會將根據 入口文件(main.1.js, main.2.js), 生成兩個 initial chunk(main.1 - [vue module, func1 module],main.2 - [vue module, func1 module, func2 module])

      第二步,使用 splitChunkPlugin插件 進行代碼分離, 先將 vue module(知足vendors - cacheGroup) 分離到 vendors chunk, 而後將 func1 module(知足common - cacheGroup) 分離到 common chunk。分離完成之後,加載 main.1 chunk 以前須要先加載 vendors chunkcommon chunk, 這樣加載首頁的時候就會有 vendorscommonmain.1 三個請求。

      因爲 maxInitialRequests 的值爲 2, 即入口處的並行最大請求數爲2, 所以 func1 modulemain.1 chunk 中分離的時候, 因爲已經有 vendorsmain.1 兩個chunk, 代碼分離失敗, 不能分離爲 新的chunk

    • minChunks | number

      代碼分割前必須共享模塊的最小塊數。即若是minChunks爲3, 則 module 必須被至少三個chunk共享才能被分離出來, 默認值爲 1

      注意: 若是分離出來的chunk的大小小於 minSize,則 代碼分離不起做用

    • minSize | number

      指定生成塊的最小大小, 以字節爲單位。

      production模式 下默認爲 30000字節

      development模式 下默認爲 10000字節

      若是分離出來的 chunk 的大小小於 minSize, 則 代碼分離不起做用

      注意:代碼分離的時候若是知足 minChunksmaxInitialRequestsmaxInitialRequestscacheGroup(enforce: false) 可是不知足 minSize, 代碼分離仍是會失效。

    • maxSize | number

      webpack嘗試將大於 maxSize 的塊拆分紅更小的部分。

      通常咱們會把第三方庫單獨打包成一個chunk: vendors。若是第三方庫比較大,致使vendors會比較大,致使更大的下載量。 此時,咱們能夠經過設置 maxSize 屬性, 將 vendors chunk 拆成更小的 chunk。

    • name | string | boolean | function: string

      指定 代碼分離 之後生成的 新的chunk 的名稱,默認值爲 true

      若是 name的值爲 true,使用 cacheGroup的屬性名源chunk的名稱 來生成 chunk 的名稱 如 'vendors~chunk'

      若是 name 的值爲 false 則使用 chunkindex 做爲 chunk 的名稱,名稱爲 數字

      若是 name 的值爲 字符串,會使用當前字符串做爲 chunk 的名稱;

      若是 name 的值爲 函數, 使用 函數返回字符串做爲 chunk的 名稱;

      若是將name的屬性設置爲字符串或者返回字符串的函數,源chunk分離出來的多個chunk會合併爲一個chunk,可能會致使更大的初始下載量和減慢頁面的加載速度。

      通常狀況下,name屬性更多的使用在 cacheGroup中,詳見 官方文檔

    • cacheGroups

      緩存組,用於指定 代碼分離策略,將知足條件的 module 從原來所屬的 chunk(initial chunk / async chunk) 中分離出來, 構成新的 chunkcacheGroup 能夠 繼承/複寫splitChunks的任何配置,只有 testpriorityreuseExistingChunkcacheGroups 特有的。

      cacheGroups的默認值以下:

      {
          ...
          optimization: {
              splitChunks: {
                  cacheGroups: {
                      // 將被至少2個chunk共享的module分離成新的chunk
                      default: {
                          automaticNamePrefix: '',
                          reuseExistingChunk: true,
                          minChunks: 2,
                          priority: -20
                      },
                      // 將引用的第三方庫分離成新的chunk
                      vendors: {
                          automaticNamePrefix: 'vendors',
                          test: /[\\/]node_modules[\\/]/,
                          priority: -10
                      }
                  }
              }
          }
      }
      複製代碼
      • priority | number

        指定 cache group優先級

        若是一個模塊能夠屬於多個 cache group, 那麼它將屬於 優先級更高cache group。 例如,一個第三方模塊(jquery),既知足 'vendors' 條件, 也知足 'default' 條件,可是因爲 'vendors' 的優先級高於 'default'jquery 模塊最後會被分離到 vendors chunk 中。

        默認 cache group 的優先級爲 負數(vendors: -10, default: -20), 咱們能夠自定義 cache group, 只要 priority 的值大於-10, 便可先於默認cache group 發揮做用。

      • reuseExistingChunk | boolean

        若是分離出來的module已經存在於某個chunk中,那麼重用這個chunk,不須要從新生成一個chunk。 這樣可能致使生成的chunk的名稱不符合預期。

        咱們經過一個簡單的例子來講明:

        // webpack
        {
            splitChunks: {
                cacheGroups: {
                    common: {
                        name: 'common',
                        minChunks: 2,
                        priority: 0,
                        reuseExistingChunk: false,
                        enforce: true
                    }
                }
            }
        }
        
        // main.1.js
        import(/* webpackChunkName: "exp1" */ './examples/example.1.js')
        import(/* webpackChunkName: "exp2" */ './examples/example.2.js')
        
        // example.1.js
        import { func2 } from '../utils/util.2'
        export const example1 = () => {
            func2()
            console.log('example1')
        }
        
        // example.2.js
        import { func2 } from '../utils/util.2'
        export const example2 = () => {
            func2()
            console.log('example2')
        }
        
        
        // main.2.js
        import(/* webpackChunkName: "util1" */ './utils/util.1')
        import(/* webpackChunkName: "util2" */ './utils/util.2')
        
        // util.1.js
        export const func1 = () => {
            console.log('func1')
        }
        
        // util.2.js
        export const func2 = () => {
            console.log('func2')
        }
        
        複製代碼

        上面的例子是一個簡單的多頁面應用。

        第一步, webpack 會將根據 入口文件(main.1.js, main.2.js), 生成兩個 initial chunk(main.1 chunk, main.2 chunk) 和 四個 async chunk(exp1 chunk, exp2 chunk, util1 chunk, util2 chunk)

        第二步,使用 splitChunkPlugin插件 進行 代碼分離。因爲 util.2 moduleexp1 chunkexp2 chunkutil2 chunk 共享, 將會被分離成一個 新的chunk'common'

        若是 reuseExistingChunk 的值爲 true,因爲 common chunk 中的 moduleutil2 chunk 中存在, 因此 util2 chunk 會被複用, common chunk 不會被新建, 最後輸出的 chunk 爲: main.1, main.2, exp1, exp2, util1, util2

        若是 reuseExistingChunk 的值爲 falsecommon chunk 會被建立, 最後輸出的 chunk 爲: main.1, main.2, exp1, exp2, util1, common(exp一、exp二、util2 中的 util.2 module 會分離到 common chunk 中, 致使 util2 chunk 中的 module 爲 0, 而後被刪除)。

      • test | string | Regexp | function(module, chunks): boolean

        選擇知足條件的module來生成chunk,詳見 官方文檔。。

      • filename | string

        output.filename 用法同樣。當且僅當是 initial chunk 時,覆蓋文件名。(待研究)

      • enforce | boolean

        若是爲 true,則始終爲當前 cache group 建立 chunk,默認爲 false

        splitChunks: {
            minSize: 30000,
            cacheGroups: {
                common: {
                    name: 'chunk-common',
                    minChunks: 2,
                    enforce: true
                }
            }
        }
        複製代碼

        webpack 會根據上面的配置項將 被至少2個chunk共享的module 分離爲 新的chunk('chunk-common',實際大小爲10kb)。若是 enforcefalse, 因爲 chunk-common的實際大小小於minSize(30kb), 代碼分離失效,chunk-common塊不會生成。此時,咱們能夠將 enforce 設置爲 true,強制令代碼分離生效, 生成 chunk-common

  • runtimeChunk | boolean | object

    webpack 編譯打包源文件時,會生成一段 runtime代碼, 用於 加載chunk加載module緩存module等。若是 runtimeChunk 配置項的值爲 true 或者 object 時, runtime代碼 會從被分離成一個單獨的 chunk(runTime chunk)。應用加載時, runtime chunk 會首先加載。

    默認狀況下爲 false,即不分離 runtime chunk。若是 runtimeChunk 的值爲對象,對象只有一個name屬性,用於聲明 runtime chunk 的名稱。

    optimization: {
        runTimeChunk: true   // 生成名稱爲 runtime~main.js 的chunk
    }
    // 若是配置項的值爲對象, 對象的屬性只有name。 name的類型能夠爲字符串或者函數
    optimization: {
        runTimeChunk:{
            name: 'runtime'  // 生成名稱爲 runtime.js 的chunk
        }
    }
        
    optimization: {
        runTimeChunk:{
            name: function(entrypoint) { // entrypoint -> entry chunk, 通常爲main chunk
                return `runtime~${entrypoint.name}`  //  entrypoint.name => main
            }
        }
    }
    複製代碼
  • noEmitOnErrors | boolean

    編譯錯誤時,emit階段會跳過,即不會輸出打包文件到指定位置。production模式 下,默認爲 true

  • namedModules | boolean

    在編譯過程當中,每個 module 都會生成一個 標識符 用於標識 module。若是設置爲true,在打包文件中會以 模塊源文件的路徑 做爲標識符, 方便咱們調試。

    optimization.namedModules: true 等同於 optimization.moduleIds: 'named'

    development模式 下, 默認爲 trueproduction模式 下,默認爲 false

    // main~chunk.js
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{
    /***/ "./src/main.js":   // 以'.src/main.js' 標識 main.js 對應的 module
    /***/ (function(module, __webpack_exports__, __webpack_require__) {
            "use strict";
            __webpack_require__.r(__webpack_exports__);
            /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/_vue@2.6.10@vue/dist/vue.runtime.esm.js");
    
            console.log(vue__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])
            alert('1')
    
    /***/ })
    
    },[["./src/main.js",0,1]]]);
    
    複製代碼
  • namedChunks | boolean

    若是設置爲 true,在打包文件中使用 chunk的名稱 來標識 chunk,方便咱們調試。

    optimization.namedChunks: true 等同於 optimization.chunkIds: named

    development模式 下,默認爲 trueproduction模式 下,默認爲 false

    // main~chunk.js
    // namedChunks: false, 以數字做爲chunk的標識符;
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["2"],{
        ...
    },[["Vtdi","0","1"]]]);
    
    // namedChunks: true, 以chunk的名稱做爲chunk的標識符
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["main"],{
        ...
    },[["Vtdi","runtime~main","chunk-vendors"]]]);
    
    複製代碼
  • modulesId | boolean | string

    告訴webpack使用哪一種算法來生成 module id。 在最後的打包文件中,會使用 module id 來標識每個 module

    說明
    false 使用內置的算法生成 module id, module id 爲 數字
    natural 使用 modulemodules列表 中的 index 做爲 idmain.js 對應的 module id0
    named 使用 源文件url 做爲 module id
    hashed 使用 源文件url 經過 md5算法 生成的 hash值前四位 做爲 module id
    size modules 按照 最小的初始下載大小排序, module 的 index 即爲 module id(未理解)
    total-size modules 按照 最小的總下載大小排序, module 的 index 即爲 module id(未理解)

    moduleIds: 'hash' 比較經常使用。

  • chunkIds

    告訴 webpack 使用那種算法來生成 chunk id。 在最後的打包文件中,會使用 chunk id 來標識 chunk

    說明
    false chunks列表 中的 chunk 按照 name 從小到大排序, chunks列表chunk的index 即爲 chunk id
    natural chunks列表 中的 chunk 按照 加載順序 從小到大排序, chunks列表chunk的index 即爲 chunk id
    named chunk 的名稱做爲 chunk id,方便調試
    size chunks 按照 最小的初始下載大小排序, chunk 的 index 即爲 chunk id(未理解)
    total-size chunks 按照 最小的總下載大小排序, chunk 的 index 即爲 chunk id(未理解)
  • removeAvailableModules | boolean

    若是 children chunk 中含有 parent chunk 已經存在的 module,將 modulechildren chunk 中移除。

    咱們經過一個簡單的例子來講明:

    // main.js
    import { func1 } from './utils/util.1'
    func1()
    import(/* webpackChunkName: "example1" */ './examples/example.1.js').then(res => {
      res.example1()
    })
    
    
    // example1.js
    import { func1 } from '../utils/util.1'
    export const example1 = () => {
        func2()
        console.log('example1')
    } 
    複製代碼

    咱們在使用 webpack 編譯打包源文件的時候,會先將源文件打包爲一個 initial chunk(main)。若是有須要 動態導入module,則會建立一個 新的chunk,即 async chunk(example1)。此時 main chunkexample1 chunkparent

    若是 removeAvailableModulestrue, webpack 會檢查 example1 chunk 中包含的 module(util.1) 是否也存在於 main chunk 中, 若是存在,刪除 example1 chunk 中的對應 module,即 example1打包文件 中不包含 utils.1 模塊。

    若是將 removeAvailableModules 屬性設置爲false,webpack 將不會檢查 子chunk 中是否存在 重複module 並移除, 即 'main'打包文件'example1'打包文件 中都含有 utils.1 模塊。

    無論是 production模式 仍是 development模式removeAvailableModules 默認爲 true

  • nodeEnv | string

    告訴 webpackprocess.env.NODE_ENV 設置爲給定的 字符串值(production / development)

    默認爲 mode配置項 的值, 若是未指定 mode 的值,設置爲 'production'

  • mangleWasmImports

    默認值爲 false

  • removeEmptyChunks | boolean

    默認爲 true,若是生成的 chunk 中沒有 module,則將 chunk 移除。

    在使用 spiltChunkPlugin代碼分離 的時候,可能會出現 收集的module被分離爲新的chunk而致使本身的modules列表爲空 的狀況。此時, 沒有module的chunk就會被移除

  • mergeDuplicateChunks | boolean

    默認爲 true,告訴 webpack 合併包含相同 moduleschunk

    mergeDuplicateChunks 配置項會指引 MergeDuplicateChunksPlugin源文件編譯打包之後的chunks 作優化,將 包含相同moduleschunks 作合併處理。優化之後的 chunks 纔會使用 splitChunkPlugin代碼分離

    咱們經過一個簡單的小例子來講明一下:

    // webpack.js
    {
        entry: {
            'main1': './src/main.1.js',
            'main2': './src/main.2.js'
        },
        optimization: {
            mergeDuplicateChunks: true
        }
    }
    
    
    // main.1.js
    import(/* webpackChunkName: "exp1" */ './examples/example.1.js')
    
    
    // main.2.js
    import(/* webpackChunkName: "example1" */ './examples/example.1.js')
    複製代碼

    源文件會經過 webpack 打包成兩類 chunk: initial chunk(main.1 chunk, main.2 chunk), async chunk(exp1 chunk,example1 chunk);

    若是 mergeDuplicateChunks 的值爲 true, 對生成的 chunks 優化。上述 chunks 中, exp1 chunkexample chunk 中的 module 徹底一致, example chunk 會合併到 exp1 chunk 中。合併完成之後,example1 chunk 會被 刪除。 這樣使用 splitChunkPlugin 進行 代碼分離chunks 爲: main.1 chunk、main.2 chunk、exp1 chunk

    若是 mergeDuplicateChunks 的值爲 false, 則 不做合併優化,使用 splitChunkPlugin 進行 代碼分離chunks 爲: main.1 chunk、main.2 chunk、exp1 chunk、 example1 chunk

  • flagIncludedChunks | boolean

    production模式 下,默認爲 true

    假設存在兩個 chunkA(id = 'A')chunkB(id = 'B')。若是 chunkAchunkB子集(即chunkA中的module在chunkB中都存在), 那麼 chunkBid = 'B,A'

    咱們經過一個簡單的小例子來講明:

    // main.js
        import(/* webpackChunkName: "exp1" */ './examples/example.1.js')
        import(/* webpackChunkName: "exp2" */ './examples/example.2.js')
        
        // example.1.js
        import { example3 } from './example.3.js'
        export const example1 = () => {
            example3()
            console.log('example1')
        } 
        
        // example.2.js
        export const example2 = () => {
            import(/* webpackChunkName: "exp3" */ './examples/example.3.js')
            console.log('example2')
        }
        
        
        // example.3.js 
        export const example3 = () => {
            console.log('example3')
        }
    複製代碼

    上面的例子中,會生成三個 async chunkexp1 chunkexp2 chunkexp3 chunk。因爲 exp3 chunk 中的 modulesexp1 chunk 中都存在, 因此 exp3 chunkexp1 chunk 的子集, exp1 chunkid'exp1, exp3'

    應用啓動的時候, 會經過 動態添加script的方式 加載 exp1 chunkexp2 chunk。因爲 exp1 chunkid'exp1, exp3', 因此會認爲 exp1exp2exp3 都已經加載了。 這樣當咱們須要加載 exp3 chunk 的時候,就不要經過動態添加script的方式來加載了,直接使用 緩存 便可。

  • occurrenceOrder | boolean

    告訴 webpack 找出 module 的順序,致使最小的初始包。

    optimization.occurrenceOrder: true 等同於 optimization.chunkIds: 'total-size'

    optimization.occurrenceOrder: true 也等同於 optimization.moduleIds: 'size'

    production模式 下默認爲 true

  • providedExports | boolean

    默認爲 true。 告訴 webpack 找出 module輸出 來生成更有效的代碼。

    咱們經過一個簡單的例子來講明:

    // main.js
        import { add, sub } from '../utils/util.js'
        add()
        sub()
        
        // util.js
        export const add = () => { 
            console.log('add')
        }
        
        export const sub = () => {
            console.log('sub')
        }
    複製代碼

    啓動應用後,咱們會加載 main moduleutil module, 而後緩存到 installedModules 中, installedModules 的結構爲:

    installedModules = {
            'main.js': {
                i: 'main.js',   // module id
    			l: true,        // module 是否已加載
    			exports: {}     // module 輸出
            },
            'util.js': {
                i: 'util.js',
                l: true,
                exports: {
                    add: function() {...},
                    sub: function() {...}
                }
            }
        }
    複製代碼

    若是 providedExports 的值爲 true, 則會對 util module 的輸出的名稱進行 優化, 即 installedModules['util.js'].exports = {a: function(...) {}, b: function() {...}};

    若是 providedExports 的值爲 false, installedModules['util.js'].exports = {add: function(...) {}, sub: function() {...}};

  • usedExports | boolean

    production模式 下爲 true。告訴 webpack 肯定每一個 module 已使用的導出, 爲 使用的導出 生成 導出

    咱們經過一個簡單的例子來講明:

    // main.js
    import { add, sub } from '../utils/util.js'
    add()
    
    // util.js
    export const add = () => { 
        console.log('add')
    }
    
    export const sub = () => {
        console.log('sub')
    }
    複製代碼

    啓動應用後,咱們會加載 main moduleutil module, 而後緩存到 installedModules 中, installedModules 的結構爲:

    installedModules = {
            'main.js': {
                i: 'main.js',   // module id
    			l: true,        // module 是否已加載
    			exports: {}     // module 輸出
            },
            'util.js': {
                i: 'util.js',
                l: true,
                exports: {
                    add: function() {...},
                    sub: function() {...}
                }
            }
        }
    複製代碼

    在上面的示例中, util module 的輸出,只有 add 被用到。

    若是 usedExporttrue, 那麼 installedModules['util.js'].exports = { add: function() {...}};

    若是 usedExportfalse, 那麼 util module全部輸出 仍是會出現中 exports 中。

    注意:若是 usedExporttrue, sub 方法不會出如今 exports 中。 sub方法代碼 儘管沒有使用, 但仍是會被打包。 使用 tree shaking 才能在打包過程當中去除 未使用的代碼

  • concatenateModules | boolean

    鏈接多個module爲一個module。

    production模式 下默認爲 true

    示例:

    // main.js
        import { add } from './utils/util.1.js'
        
        // util.1.js
        export const add = () => {
            console.log('add')
        }
    複製代碼

    若是 concatenateModules 爲true, util.1 modulemain module 會合併爲一個 module;

    若是 concatenateModulesfalse, 不作 合併

    ES6模塊才能夠被合併。模塊合併 發生在 代碼分離 以後。

  • sideEffects | boolean

    用於移除 JavaScript上下文 中的 未引用代碼(dead-code) - tree shaking

    product模式 下默認爲 true

    爲了 tree shaking 生效, 咱們須要:

    • 使用 ES2015 模塊語法(即 import 和 export)

    • 在項目 package.json 文件中,添加一個 "sideEffects" 入口。

    詳細用法見: 官方文檔

  • portableRecords | boolean

    告訴 webpack 生成 具備相對路徑的記錄,以便可以 移動上下文文件夾

    默認狀況下,optimize.portableRecords 被禁用。

    若是至少有一個記錄選項( recordsPathrecordsInputPathrecordsOutputPath)提供,則自動啓用。

output

type: Obect

用於指示 webpack 如何以及在何處輸出打包文件、資源以及其餘使用webpack打包或者加載的文件。

  • path | string

    指定 打包文件輸出目錄,即打包後 文件在硬盤中的存儲位置

    輸出目錄是一個 絕對路徑

  • publicPath | string

    此選項指定在瀏覽器中所引用的 輸出目錄(path)對應的公開URL

    publicPath 並不會對 生成文件的路徑 形成影響,主要是 對頁面裏面引入的資源的路徑作對應的補全

    {
        output: {
            path: path.resolve(__dirname, '../dist'), // 打包文件會輸出到path指定的位置
            publicPath: '/'  // 瀏覽器會訪問 publicPath 指定位置的文件
        }
    }
    複製代碼
  • pathinfo | boolean

    告訴 webpackchunk 中引入 所包含模塊信息的相關注釋

    默認值false,而且 不該該用於生產環境(production),可是 對閱讀開發環境(development)中的生成代碼(generated code)極其有用

    這些註釋也會被添加至通過 tree shaking 後生成的 bundle 中。

  • filename | string | function

    指定 輸出的打包文件文件名, 默認值爲

    咱們可使用如下經常使用方式爲每個 打包文件 提供 惟一文件名

    • 'bundle.js' - 指定 入口文件(main.js) 所在的 chunk文件名僅適用於單頁面應用

    • '[name].js' - 使用 chunkname

    • '[name].[hash].js' - 使用 compilationhash全部chunk文件名中hash值同樣

    • '[name].[chunkhash].js' - 使用 chunk 內容的 hash每一個chunk文件名中的hash值都不同

    • '[name].[id].js' - 使用 chunkid

    • [name].[contenthash].js - 使用提取內容的 hash??

    咱們也能夠將 filename 指定一個 function 來返回輸出的文件名, 返回值 的格式和上面同樣。

    經常使用命名方式: [name].[chunkhash].js

  • chunkFilename | string

    指定 非入口chunk(不包含runtime code) 的文件名。

    若是未指定, 使用 '[id].js' 或者 filename指定的文件名

  • chunkLoadTimeout | number

    chunk請求超時的時間,單位爲 毫秒,默認爲 120000

    咱們會經過 動態添加script元素 的方式來進行 懶加載。若是在指定時間內未獲取到指定的chunk, 則認爲 超時

  • crossOriginLoading | boolean | string

    告訴 webpack 是否啓用 chunk跨域加載, 默認值爲 false

    若是值爲 false禁用;若是值爲 字符串,在 動態添加script元素 的方式來進行 懶加載時,會給 script元素 添加 crossorigin 屬性。

    'anonymous' - 無需憑據 便可啓用 跨域加載

    'use-credentials' - 使用憑證 啓用 跨域加載';

  • jsonpScriptType | string

    動態添加script元素 的方式來進行 懶加載時,指定 script元素 的類型,即 設置type屬性的值。

    如: jsonpScriptType: 'text/javascript'

  • library | string | object

    經常使用於 開發類庫, 需和 libraryTarget屬性 配合使用。

    若是是 string,將 入口文件的返回值 賦值給 library屬性 指定的 變量

    若是是 object, 則用於給每一個 target(libraryTarget) 起不一樣的名稱。

    output: {
      library: {
        root: "MyLibrary",
        amd: "my-library",
        commonjs: "my-common-library"
      },
      libraryTarget: "umd"
    }
    複製代碼
  • libraryTarget | string

    配置如何暴露 library。 假設 output.library: 'myLibrary':

    • 'var'

      類庫加載完畢之後,入口文件的返回值 將分配給一個 使用var定義的變量

      // 編譯打包之後的輸出文件: main.js
      var myLibrary = (function(modules){
      
          return xxx
          
      })([...modules])
      複製代碼
    • 'assign'

      類庫加載完畢之後,入口文件的返回值 將分配個一個 不使用var定義的變量

      // 編譯打包之後的輸出文件: main.js
      myLibrary = (function(modules){
      
          return xxx
          
      })([...modules])
      
      複製代碼
    • 'this'

      類庫加載完畢之後,入口文件的返回值 將做爲 當前上下文this 的一個 屬性,屬性名爲 myLibrary

      // 編譯打包之後的輸出文件: main.js
      // this 通常爲 window
      this["myLibrary"] = (function(modules){
      
          return xxx
          
      })([...modules])
      複製代碼
    • 'window'

      類庫加載完畢之後,入口文件的返回值 將做爲 window對象 的一個 屬性,屬性名爲 myLibrary

      // 編譯打包之後的輸出文件: main.js
      window["myLibrary"] = (function(modules){
      
          return xxx
          
      })([...modules])
      複製代碼
    • 'self'

      類庫加載完畢之後,入口文件的返回值 將做爲 self 的一個 屬性,屬性名爲 myLibrary

      // 編譯打包之後的輸出文件: main.js
      self["myLibrary"] = (function(modules){
      
          return xxx
          
      })([...modules])
      複製代碼
    • 'global'

      類庫加載完畢之後,入口文件的返回值 將做爲 globalObject屬性指定的全局變量 的一個 屬性,屬性名爲 myLibrary

      // 編譯打包之後的輸出文件: main.js
      // globalObject 默認爲 window
      window["myLibrary"] = (function(modules){
      
          ...
          
      })([...modules])
      複製代碼
    • 'commonjs'

      輸出的類庫符合 commonJs規範

      入口文件的返回值 將做爲 exports 的一個 屬性,屬性名爲 myLibrary

      // 編譯打包之後的文件: main.js
      exports["myLibrary"] = (function(modules){
      
          return xxx
          
      })([...modules])
      
      
      複製代碼
    • commonjs2

      輸出的類庫符合 commonJs規範

      入口文件的返回值 會被分配給 module.exports

      // 編譯打包之後的文件: main.js
      module.exports = (function(modules){
      
          return xxx
          
      })([...modules])
      複製代碼
    • amd

      輸出的類庫 符合 AMD規範

      // 編譯打包之後的文件: main.js
      define("MyLibrary", [], function() { return (function(modules){
      
          return xxx
          
      })([...modules])}
      複製代碼
    • umd

      輸出的類庫 符合 UMD規範

      // 編譯打包之後的輸出文件:main.js
      (function(root, factory){
          if(typeof exports === 'object' && typeof module === 'object')
              module.exports = factory();
          else if(typeof define === 'function' && define.amd)
              define([], factory);
          else if(typeof exports === 'object')
              exports["my-common-library"] = factory();
          else
              root["MyLibrary"] = factory();
      }(window, function() {
          return  (function(modules){
      
              ...
          
          })([...modules])
      }))
      複製代碼
    • jsonp

      入口起點返回值,包裹到一個 jsonp 包裝容器中。

      MyLibrary((function(modules){
      
          return xxx
          
      })([...modules]))
      複製代碼

      需配合 extenals配置項 使用。

    • system

      輸出類庫格式

      System.register("MyLibrary", [], function(__WEBPACK_DYNAMIC_EXPORT__) {
      
      	return {
      
      		execute: function() {
      			__WEBPACK_DYNAMIC_EXPORT__((function(modules) {
      			
      			    return xxx
      			    
      			}([...modules])));
      		}
      	};
      });
      複製代碼

      系統模塊 要求在執行 類庫時,須要 瀏覽器 中存在 全局變量System

  • globalObject | string

    librarylibraryTarget 一塊兒使用,指示將 入口文件的返回值 分配給哪一個 全局對象

    默認值爲 window

    // webpack.js
    output: {
        library: 'myLibrary',
        libraryTarget: 'global',
        globalObject: 'self'
    }
    
    // 編譯打包之後的文件: main.js
    self["myLibrary"] = (function(modules){
        
        return xxx
            
    })([...modules])
    複製代碼
  • libraryExport | string | [string]

    用於指定 具體的入口文件的返回值

    常見的使用方式:

    • 未指定值
    // webpack.js
    outout: {
        library: 'myLibrary',
        libraryTarget: 'var'
    }
    
    // main.js
    var myLibrary = (function(modules){
        
        return xxx
            
    })([...modules])
    
    複製代碼
    • 'default'
    // webpack.js
    outout: {
        library: 'myLibrary',
        libraryTarget: 'commonjs2',
        libraryExport: 'default'
    }
    
    // main.js
    module.exports = (function(modules){
        
        return xxx
            
    })([...modules])["default"]
    複製代碼
    • 'myModule'
    // webpack.js
    outout: {
        library: 'myLibrary',
        libraryTarget: 'amd',
        libraryExport: 'myModule'
    }
    
    // main.js
    define("MyLibrary", [], function() { return (function(modules){
        
        return xxx
            
    })([...modules])["myModule"]})
    複製代碼
    • ['myModule', 'mySubModule']
    // webpack.js
    outout: {
        library: 'myLibrary',
        libraryTarget: 'umd',
        libraryExport: ['myModule', 'mySubModule'
    }
    
    // main.js
    (function(root, factory){
        if(typeof exports === 'object' && typeof module === 'object')
    	    module.exports = factory();
        else if(typeof define === 'function' && define.amd)
    	    define([], factory);
        else if(typeof exports === 'object')
    	    exports["my-common-library"] = factory();
        else
    	    root["MyLibrary"] = factory();
    }(window, function() {
        return  (function(modules){
        
            return xxx
            
        })([...modules])["myModule"]["mySubModule"]
    }))
    
    複製代碼
  • auxiliaryComment | string | object

    在和 output.libraryoutput.libraryTarget 一塊兒使用時,此選項容許用戶向 導出容器(export wrapper) 中插入 註釋

    具體用法詳見: 官網

  • jsonpFunction | string

    輸出多個chunk 時, webpack 會構建一個 全局方法, 用於 安裝chunk

    jsonpFunction 可用於指定 安裝chunk方法名

    若是 未指定, 則方法名爲:'webpackJsonp'

    若是 指定(如:'myFunction'), 則方法名爲 'myFunction'

    // 未指定
    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],[...modules])
    
    // jsonpFunction: 'myFunction'
    (window["myFunction"] = window["myFunction"] || []).push([[0],[...modules])
    複製代碼
  • sourceMapFilename

    配置 source map 的命名方式。默認使用 '[file].map'

    只在 devtool 啓用了 SourceMap 選項時才使用。

  • strictModuleExceptionHandling | boolean

    若是一個模塊在導入時拋出異常,告訴 webpack模塊實例緩存刪除 這個模塊。

    默認值爲 false, 即 不刪除

    若是設置爲 true刪除

    // strictModuleExceptionHandling: true
    function __webpack_require__(moduleId) {
    	// Check if module is in cache
    	if(installedModules[moduleId]) {
    		return installedModules[moduleId].exports;
    	}
    	// Create a new module (and put it into the cache)
    	var module = installedModules[moduleId] = {
    		i: moduleId,
    		l: false,
    		exports: {}
    	};
    
    	// Execute the module function
    	var threw = true;
    	try {
    	    // 導入模塊
    		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    		threw = false;
    	} finally {
    	    // 導入模塊時, 若是發生異常,將模塊實例從installedModules緩存中刪除
    		if(threw) delete installedModules[moduleId];
    	}
    
    	// Flag the module as loaded
    	module.l = true;
    
    	// Return the exports of the module
    	return module.exports;
    }
    
    
    
    // strictModuleExceptionHandling: false
    
    function __webpack_require__(moduleId) {
    	// Check if module is in cache
    	if(installedModules[moduleId]) {
    		return installedModules[moduleId].exports;
    	}
    	// Create a new module (and put it into the cache)
    	var module = installedModules[moduleId] = {
    		i: moduleId,
    		l: false,
    		exports: {}
    	};
    
    	// Execute the module function
    	modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    
    	// Flag the module as loaded
    	module.l = true;
    
    	// Return the exports of the module
    	return module.exports;
    }
    
    複製代碼
  • umdNamedDefine| boolean

    會對 UMD 的構建過程當中的 AMD 模塊進行命名。不然就使用 匿名define

    // webpack.js
    output: {
        libraryTarget: 'umd',
        umdNamedDefine: true,
        library: 'myLibrary'
        
    }
    
    // main.js
    (function(root, factory){
        if(typeof exports === 'object' && typeof module === 'object')
    	    module.exports = factory();
        else if(typeof define === 'function' && define.amd)
            // 若是 umdNamedDefine: false, 則define([], factory)
    	    define(["myLibrary"], factory);
        else if(typeof exports === 'object')
            exports["myLibrary"] = factory();
        else
    	    root["MyLibrary"] = factory();
    }(window, function() {
        return  (function(modules){
        
            ...
            
        })([...modules])
    }))
    
    複製代碼
  • futureEmitAssets | boolean

    告訴 webpack輸出文件到指定位置 時,使用 將來的版本, 它容許輸出之後 釋放內存

    webpack5移除,做爲一個 默認行爲

output剩餘配置項使用較少, 後續整理。

devtool

type: string | boolean

該配置項用以控制是 否生成source map 以及 怎樣生成source map

不一樣的值會明顯影響到 構建(build)從新構建(rebuild) 的速度。

source map 是一個 信息文件,裏面儲存着 位置信息。也就是說,轉換後的代碼 的每個位置,所對應的 轉換前的位置source map 文件的 內容結構 以下:

{
    // source map 的版本
	"version": 3,
	// 轉換前的文件名, 是一個數組, 可能存在文件合併
	"sources": ["webpack:///./src/examples/example.1.js"],
	// 轉換前的全部變量名和屬性名
	"names": ["a", "example1", "alert"],
	// 記錄位置信息的字符串(一個 ; 表明一個行映射, 一個 , 表明一個列映射)
	"mappings": ";;;;;;AAAA;AAAA;AAAA,IAAMA,IAAI,KAAV;AACO,IAAMC,WAAW,SAAXA,QAAW,GAAM;AAC1BC,UAAMF,CAAN;AACH,CAFM,C",
	// 轉換後的文件名
	"file": "exp1.js",
	// 轉換前的內容
	"sourcesContent": ["const a = '123'\r\nexport const example1 = () => {\r\n alert(a)\r\n} "],
	// 轉換前的文件所在的目錄。若是與轉換前的文件在同一目錄,該項爲空
	"sourceRoot": ""
}
複製代碼

devtool 的各個配置項,實際上是由幾個 關鍵字: eval, source-map, cheap, module, inline, hidden, nosources 組合生成的。這幾個關鍵字的含義以下:

  • eval

    使用 eval() 包裹模塊代碼。

  • source-map

    生成 .map 文件,在 調試 時用於 追蹤轉換前的代碼

  • cheap

    需配合 'source-map' 一塊兒使用, Source Map 中只有 生成的代碼(generated code)轉換後的代碼(transformed code) 之間的 行映射關系, 沒有 列映射關係

  • module

    需配合 'source-map' 一塊兒使用,Source map 中存在 生成的代碼(generated code)源代碼(riginal source) 以前的 行映射 關係、列映射 關係。

  • inline

    需配合 'source-map' 一塊兒使用,不單獨生成 .map 文件,.map 文件做爲 DataUrl 嵌入 **打包文件(bundle)**中。

  • hidden

    需配合 'source-map' 一塊兒使用,會生成 .map文件,但 不會爲 bundle 添加引用註釋

  • nosources

    需配合 'source-map' 一塊兒使用,會生成 .map文件,可是 sourcesContent 的內容爲空,沒法追蹤轉換之後的代碼或者源代碼。

具體用法詳見: 官網

devServer

type: object

咱們經過使用 webpack-dev-server 來快速開發應用程序。

devServer配置項 用於指引 wepack-dev-server 的行爲。

當咱們經過 Node.js API 來使用 dev-server, devServer 中的選項將被忽略。將選項做爲第二個參數傳入: new WebpackDevServer(compiler, devServer)

  • inline | boolean

    development模式 下,webpack-dev-server監聽源文件是否發生變化。 若是發生變化,會 自動刷新頁面

    默認值爲 true, 即爲 inline模式。 若是 inline 的值爲 false, 則爲 iframe模式

    inline模式iframe模式 的原理相同, 都是 瀏覽器服務器 之間創建 websocket鏈接。當源文件發生變化時,通知瀏覽器 從新加載頁面 進行更新。

    inline模式 下, 瀏覽器端 創建websocket鏈接的邏輯代碼 會和咱們的 應用代碼 打包到一塊兒, 會增長編譯時間;

    iframe模式 下,瀏覽器端 創建websocket鏈接的邏輯代碼咱們的應用代碼 是分開的。 當咱們經過 localhost:port/webpack-dev-server/ 訪問應用時, 服務端會返回一個 html頁面html頁面 中會包含一個 live.bundle.js 的文件, 負責 創建與服務器之間的websocket鏈接, 並 動態創建一個iframe用於加載實際應用。當源文件發生變化時, 頁面不刷新, 會通知 iframe 從新更新。

    iframe模式 下沒法啓用 HMR

  • hot | boolean

    設置爲 true,將啓用 HMR 功能。

    若想觸發 HRM 功能,需知足三個條件:

    • hot配置項 的值爲 true

    • 啓用 inline模式

    • 必須顯示聲明 module.hot.accept('url', callback), 不然只能刷新頁面;

  • hotOnly | false

    默認狀況爲 false,當 HMR 失敗之後,瀏覽器端經過 從新加載頁面響應服務端更新

    若是設置爲 true, 當 HMR 失敗之後, 瀏覽器端沒法響應服務端更新。

    若是未顯示聲明 module.hot.accept('url', callback)HMR 就會失敗, 若此時 hotOnly 的值爲 true, 則 瀏覽器端沒法響應服務端更新

  • open | boolean

    設置爲true, dev-server 自動打開 默認瀏覽器 啓動應用。

  • useLocalIp

    設置爲true,dev server 會以 本地IP 打開默認瀏覽器。

    使用時,open = true

  • openPage | string

    指定 dev-server 自動打開 默認瀏覽器 之後的 默認跳轉頁面

  • host | string

    指定要使用的 host, 默認是 localhost

  • port | string

    指定監聽的 端口號, 默認是 8080

  • liveReload

    默認狀況下,dev-server 將在 檢測到參與編譯打包的文件文件更改從新加載/刷新頁面。 即若是若是一個文件 未參與編譯打包過程, 那麼它發生變化時 不會觸發從新加載/刷新頁面

    經過將 liveReload 設置爲 false禁用 它(修改什麼文件也 不會觸發從新加載/刷新頁面)。

  • contentBase | boolean | string | [string] | number

    告訴服務器從哪裏提供內容,默認值爲 當前工做目錄

  • watchContentBase

    告訴 dev-server 監視 devServer.contentBase選項 所服務的文件, 默認狀況下 禁用 它。

    默認狀況下, 若是一個文件 參與編譯打包過程,那麼當這個文件發生變化時,纔會 觸發從新加載/刷新頁面, 不然 無效

    設置爲 true啓用,即便某個文件 未參與編譯打包,當它發生變化時,也會 觸發從新加載/刷新頁面

  • watchOptions | object

    一個配置項集合,用於自定義 watch mode

    • aggregateTimeout | number

      第一個文件 修改之後,延遲從新編譯 的過程。這容許 webpack 將在這個時間段內的全部修改 聚合 到一個從新編譯的過程當中。

      傳遞的值以 毫秒 爲單位。

    • ignored | RegExp

      不監聽 知足 ignored 條件的文件的變化。

    • poll | boolean | number

      經過傳遞 true 或者 以毫秒爲單位的數值指定輪詢間隔啓用輪詢,檢查文件變化。

      文件監聽不起做用 時,能夠嘗試啓用 poll 功能。

  • writeToDisk | boolean | function:filePath

    默認爲 false, 即 不將編譯打包之後的內容寫入磁盤

    若是設置爲 true,會將 編譯打包之後的內容 寫入 output配置項 指定的位置。

    若是設置爲 function,該 function 是一個 filter function, 將 知足條件的文件名對應的文件寫入磁盤

    具體用法詳見 官網文檔

  • lazy | boolean

    若是設置爲 true, dev-server會進入 懶惰模式, 僅在請求時編譯該bundle。 這意味着 webpack不會監視任何文件更改

    ???

    注意:使用 lazy模式 時, 必須提供 filename, 不然報錯。

  • filename | string

    此選項可以讓您減小 lazy模式 下的 編譯。 默認狀況下,在 lazy模式 下,每一個請求都會產生 新的編譯。 使用 filename,只能在請求某個文件時進行編譯。

    ???

  • overlay | boolean | object

    當存在 編譯錯誤或者警告 時,將 錯誤或者警告全屏覆蓋 的形式在瀏覽器中展現。

    默認 禁用, 具體用法詳見 官網文檔

  • proxy | object | [object, function]

    先後端分離 的開發過程當中,使用 proxy 能夠有效的幫咱們解決 跨域請求問題

    一般,咱們會在 proxy配置項 中指定每一個 API請求 對應的 代理

    {
        devServer: {
            proxy: {
                'test': {
                    target: 'http://localhost:3000',
                    changeOrigin: true,
                    router: {...}
                },
                
            }
        }
    }
    複製代碼
    • target | string

      指定一個 服務器地址

      dev-server 接收到一個 API Request 之後,會向 匹配的test 對應的 服務器 從新發出 Request, 將 response 經過 dev-server 返回給 Client

    • changeOrigin | boolean

      默認值爲 false

      若是指定爲 true,??

    • pathRewrite | object | function

      重寫 Request API

      若是 pathRewrite 的值爲 object, 則 key 爲一個 RegExpvaluestringRequest API匹配RegExp 的會被 string 替換;

      若是 pathRewrite 的值爲 function, 可自定義返回新的 Request API

    • router | object | function

      若是請求的 host 或者 host + path 能匹配 router 配置項中的屬性 key,則使用對應的屬性值 value 覆蓋 proxy.target

    其餘配置項及詳細用法詳見: http-proxy-middle

  • progress | boolean

    控制檯 輸出 進度信息,僅適用於 CLI模式

  • allowedHosts | array

    將容許訪問 dev server服務列入白名單

剩餘配置項應使用較少,後續整理。

target

type: string | function(compiler)

webpack 可以爲 多種環境 編譯構建, 可經過 target配置項 指定一個 具體的環境

若是 target 的值爲 字符串, 能夠支持如下環境:

  • web

    webpack編譯打包的代碼 應用於 web環境(瀏覽器)。對於須要 懶加載的chunk,會經過 動態添加script元素的方式加載,而後經過一個 全局方法(webpackJsonp) 來安裝。

  • webworker

    webpack編譯打包之後的代碼 應用於 web worker環境。使用 chunk 時,經過 importScripts 方法加載。

    // chunk.js
    self["webpackChunk"]([0],{
        5:  (function(module, __webpack_exports__, __webpack_require__) {
            
            ...
            
        })
    });
    
    // 加載
    importScripts('./chunk.js')
    複製代碼
  • node

    webpack編譯打包之後的代碼 應用於 node環境非入口chunk的代碼符合CMD規範。使用 chunk 時,經過 require 方法加載。

    // chunk.js, 符合cmd規範
    exports.ids = [0];
    exports.modules = {
        6: (function(module, __webpack_exports__, __webpack_require__) {
            
            ...
            
        })
    
    }
    
    // 加載
    require('./chunk')
    
    
    複製代碼
  • async-node

    webpack編譯打包之後的代碼 應用於 node環境非入口chunk的代碼符合CMD規範。使用 chunk 時,經過 fs模塊異步加載

    // chunk.js, 符合cmd規範
    exports.ids = [0];
    exports.modules = {
        6: (function(module, __webpack_exports__, __webpack_require__) {
            
            ...
            
        })
    
    }
    
    // 加載
    let filename = require('path').join(__dirname, "/", 'chunk.js')
    require('fs').readFile(filename, 'utf-8',  function(err, content) {
        ...
    }
    複製代碼
  • node-webkit

    webpack編譯打包之後的代碼 應用於 node-webkit環境

    node-webkit 是一個基於 ChromiumNode.jsWeb 運行環境,可以讓你直接在 DOM 中調用 Node.js 模塊,並可以使用任何現有的 Web 技術來編寫本地應用。

  • electron-main

    webpack編譯打包之後的代碼 應用於 electron 主進程

  • electron-renderer

    webpack編譯打包之後的代碼 應用於 electron render進程

  • elentron-preload

    webpack編譯打包之後的代碼 應用於 electron render進程

externals

type: string | array | object | function | RegExp

在某些狀況下,咱們是 不但願將依賴的類庫 打包到最後輸出的 bundle 中的。此時, 咱們經過經過 externals配置項指定不參與編譯打包的類庫

通常狀況下,若是 應用程序中引入了類庫webpack 會把 類庫打包到輸出文件 中。在 運行打包後的代碼 時,會 先運行類庫代碼,拿到 類庫輸出結果(exports), 而後使用 類庫的結果 進行下一步操做。 ,

若是使用了 externals配置項 指定 不參與編譯打包的類庫,那咱們在 運行打包之後的代碼 時,因爲 打包代碼中並無類庫的代碼直接使用類庫的輸出結果會報錯。此時咱們必須 先準備好類庫(先加載或者安裝npm包),才能使用 類庫的輸出結果 進行下一步操做。

示例:

// config.js
{
    externals: {
        jquery: 'jQuery' 
    }
}

// main.js
import $ from 'jquery'

console.log($)

複製代碼

在上面的 示例 中,應用程序中引入的類庫名(jquery) 必須和 externals配置項 中的 屬性名 徹底一致, 不然 externals配置項無效。在 運行打包代碼 時,會使用 變量jQuery 或者 經過 require('jQuery') 的方式獲取 類庫輸出結果

使用 externals配置項 時, 會受到 output.libraryTarget配置項output.globalObject配置項 的影響。

若是 output.libraryTarget 的值爲 'var''assign', 應用程序 會經過 變量jQuery 來獲取類庫輸出結果, 此時 當前上下文環境中 必須 存在 已定義 變量jQuery(先加載類庫), 打包結果以下:

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            module.exports = jQuery   // jQuery在使用main.js前,必須已經存在
        })
    }))
複製代碼

若是 output.libarayTarget 的值爲 'window', 應用程序 會經過 window["jQuery"] 來獲取類庫輸出結果, 此時 window 對象中必須存在 已定義的屬性: jQuery

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            // window.jQuery在使用main.js前,必須已經存在
            (function() { module.exports = window["jQuery"]; }())   
        })
    })
})
複製代碼

若是 output.libarayTarget 的值爲 'this', 應用程序 會經過 this["jQuery"] 來獲取類庫輸出結果, 此時 當前上下文環境對象中 必須存在 已定義的屬性: jQuery

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            // this.jQuery在使用main.js前,必須已經存在
            (function() { module.exports = this["jQuery"]; }())   
        })
    })
})
複製代碼

若是 output.libarayTarget 的值爲 'self', 應用程序 會經過 self["jQuery"] 來獲取類庫輸出結果, 此時 webworker上下文環境對象中 必須存在 已定義的屬性: jQuery

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            // self.jQuery在使用main.js前,必須已經存在
            (function() { module.exports = self["jQuery"]; }())   
        })
    })
})
複製代碼

若是 output.libarayTarget 的值爲 'global'output.globalObject 的值爲 'window', 應用程序 會經過 window["jQuery"] 來獲取類庫輸出結果, 此時 window 必須存在 已定義的屬性: jQuery

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            // this.jQuery在使用main.js前,必須已經存在
            (function() { module.exports = this["jQuery"]; }())   
        })
    })
})
複製代碼

若是 output.libarayTarget 的值爲 'commonjs''commonjs2', 應用程序 會經過 require('jQuery') 來獲取類庫輸出結果, 此時 jQuery包 必須已經安裝。

// main.js
(function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            // 在使用main.js前,jQuery包必須已經安裝
           module.exports = require("jQuery");  
        })
    })
})
複製代碼

若是 output.libarayTarget 的值爲 'amd',打包結果以下:

// main.js
define(['jQuery'], function(__WEBPACK_EXTERNAL_MODULE_jquery__) {
    return (function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;
        })
    }))
})

// requireConfig.js
require.config({
    paths:{
        "jQuery":'../lib/jquery.min'  // 這個配置項是必須存在的, 不然會找不到jQuery
    }
});

// 使用
require('./main.js', function() {...})
複製代碼

若是 output.libarayTarget 的值爲 'umd',打包結果以下:

// main.js
(function(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        // cmd規範,應用與node環境,經過require加載類庫
		module.exports = factory(require("jQuery"));  
	else if(typeof define === 'function' && define.amd)
	    // amd規範, 使用requirejs加載類庫, 必須有關於jQuery的require.config配置
		define(["jQuery"], factory);  
	else {
	    // 通常爲經過script元素的方式加載類庫
		var a = typeof exports === 'object' ? factory(require("jQuery")) : factory(root["jQuery"]);
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
    
}(window, function(__WEBPACK_EXTERNAL_MODULE_jquery__) {
    return (function(modules){
        ...
        
        return __webpack_require__(__webpack_require__.s = "./src/main.js");
        
    }({
        'main': {
            ...
            var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("jquery")
            ...
        },
        'jquery': (function(module, exports) {
            module.exports = __WEBPACK_EXTERNAL_MODULE_jquery__;
        })
    }))
}))
複製代碼

externals配置項 的值的類型能夠是 Object, 以下:

externals: {
    // 根據output.libraryTarget的值選擇使用類庫的方式
    jQuery: 'jQuery',  
    // 經過requirejs方式使用類庫輸出, 若是libraryTarget的值不是amd, 則沒有意義
    vue: 'amd Vue',
    // 根據 output.libraryTarget 的值選擇 加載類庫時類庫的名稱 或者 應用類庫輸出結果時使用的變量
    // 若是未指定, 則爲 undefined
    react: {
        // module.exports = React_var
        // 若是 libraryTarget: var 且 未指定 var: xxxx,  module.exports = undefined
        var: 'React_var',  
        // module.exports = require('React_common')
        // 若是 libraryTarget: commonjs 且 未指定 commonjs: xxxx,  module.exports = require (undefined)
        commonjs: 'React_common', 
        commonjs2: 'React_common2', 
        // define(['React_amd'], function(obj) {...})
        //  若是 libraryTarget: amd 且 未指定 amd: xxxx,  define([undefined], function(obj) {...})
        amd: 'React_amd',
        // amd、commonjs的集合
        umd: 'React_umd',
        // module.exports = window[React_window]
        // 若是 libraryTarget: window 且 未指定 window: xxxx, module.exports = window[undefined]
        window: 'React_window', 
        // module.exports = self[React_window]
        // 若是 libraryTarget: self 且 未指定 self: xxxx, module.exports = self[undefined]
        self: 'React_self',   // module.exports = self[React_self]
        // module.exports = this[React_window]
        // 若是 libraryTarget: this 且 未指定 this: xxxx, module.exports = this[undefined]
        this: 'React_this'   
    }
}
複製代碼

externals配置項 的值的類型能夠是 string, 如:

externals: 'jQuery'

// 等價與:

externals: {
    jQuery: 'jQuery'
}

// 不支持 externals: 'amd jQuery'
複製代碼

externals配置項 的值的類型能夠是 RegExp, 如:

externals: /^(jquery|\$)$/i
複製代碼

externals配置項 的值的類型能夠是 function, 如:

// request 對應 import $ from 'jquery' 中的就juqery
externals: function(context, request, callback) {
    if ( /^(jquery|\$)$/i.test(request)){
      return callback(null, 'commonjs ' + request);
    }
    callback();
 }
複製代碼

externals配置項 的值的類型能夠是 array, 數組元素的類型能夠是上面的任意一種。

performance

type: object

用於配置如何展現性能提示。例如,若是一個資源超過 250kb,webpack 會對此輸出一個警告來通知你。

  • hints | false | 'warning' | 'error'

    打開或關閉提示, 默認值爲 'warning'

    若是 hints 的值爲 false關閉提示

    若是 hints 的值爲 warning當輸出文件的體積超過指定體積時,輸出 警告信息依然完成編譯打包工做, 適用於 開發模式

    若是 hints 的值爲 error當輸出文件的體積超過指定體積時中斷編譯打包,並輸出 錯誤信息, 適用於 生產模式

  • maxEntrypointSize | int

    指定 入口文件最大致積, 默認值爲 250000 bytes

    若是 超過最大致積hints 的值 不是false, 輸出 警告/錯誤 信息。

  • maxAssetSize | int

    指定 單個資源(包括入口文件)最大致積,默認值爲 250000 bytes

  • assetFilter | function

    自定義 哪些文件的 體積超過最大致積 時,輸出 警告/錯誤 信息。

相關文章
相關標籤/搜索