webpack4.0.0.beta嚐鮮

date: 2018-03-19 16:01:31javascript

標籤(空格分隔): webpackcss


此處輸入圖片的描述
近年來前端技術如雨後春筍蓬勃發展,咱們也在不斷學習中成長。例如:jsx 方便了咱們在 js 中編寫 html,less/sass 的出現提升了咱們書寫 css 的能力,AMD/CommonJS/ES6 的出現爲咱們模塊化開發提供了便利。然而,咱們須要使用其它工具將這些工具轉化成原生語言以運行在瀏覽器上。但這樣致使的問題就是代碼體積愈來愈大,變的複雜不可控。因而,咱們就開始考慮針對這些龐大的代碼進行優化,webpack 就是這個需求下的產物。 webpack 能夠看作是模塊打包機。它作的事情是:分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。目前,webpack 總共發佈了三個穩定版本。從17年八月底開始,經歷了長達五個月的開發週期,webpack 團隊經過增長大量新特性、bug修復、問題改善並於近期發佈了 webpack4 的 beta 版本。若是你對 webpack 感興趣,下面咱們就來學習一下 webpack4 beta 的新特性。

P.S. 如下全部代碼演示代碼都是基於 webpack 4.0.0-beta.0html

1、安裝webpack v4.0.0-beta.0

若是你使用yarn yarn add webpack@next webpack-cli --dev 若是你使用npm npm install webpack@next webpack-cli --save-dev前端

2、webpack 4.0 新特性介紹

下面是一些你確定會感興趣的新特性。在閱讀完本章以後,若是你以爲不過癮,完整的修改列表請查看官方修改日誌 github.com/webpack/web…java

本章將從如下幾部分來介紹 webpack 4.0。node

2.1 環境

webpack 運行環境升級。已經不支持 Node.js 4 版本。源碼升級到更高的 ECMAScript 版本。react

根據 webpack package.json 配置中顯示 Node.js 最低支持版本:"node": ">=6.11.5"webpack

2.2 模塊

webpack 模塊類型及 .mjs 的支持:

長久以來,JS是webapck中惟一的模塊類型。正所以,開發者沒法有效地打包其它類型的文件。目前,webpack實現了五種模塊類型,它們各有本身的優點,可按須要使用(後面會詳細說明)。git

  1. javascript/auto: (webpack3中默認)支持全部的JS模塊系統:CommonJS、AMD、ESM。
  2. javascript/esm: EcmaScript模塊,全部其餘模塊系統不可用(.mjs文件中默認)。
  3. javascript/dynamic: 不支持CommonJS和EcmaScript模塊。
  4. json: JSON數據,能夠經過require和import導入(.json文件默認)。
  5. webassembly/experimental: WebAssembly模式(目前處於實驗性階段,.wasm文件默認)。

用法: module.rules 中的 type 就是新增長的屬性,用來支持不一樣的模塊類型。github

module: {
    rules: [{
      test: /\.special\.json$/,
      type: "javascript/auto",
      use: "special-loader"
    }]
  }
複製代碼

此外,如今webpack 按照 .wasm, .mjs, .js, 以及 .json 等擴展名的順序來解析。

javascript/esm 相比於 javascript/auto 處理ESM更加嚴格

咱們說既然有了 javascript/auto 爲何還要細分那麼多其餘類型呢?這是由於每種類型都有本身獨特的處理優點。具體表如今兩個方面:

  1. 導入的名稱必須存在於導入的模塊中。
  2. 動態的模塊(非ESM,例如CommonJS)只能經過默認 import 導入,其餘全部(包括命名空間導入)的導入都會報錯。

2.3 用法

  • 必須在 「開發或者生產」 中選擇一種模式(這裏有一種隱藏模式 none,能夠禁用一切功能)。
    • 生產模式不支持監聽,開發模式針對快速增量重建進行了優化。
    • 生產模式一樣支持模塊串聯,即變量提高(此功能在webpack 3 中已經實現)。
    • 開發模式下支持註釋和提示,而且支持 eval 的source map。
  • 將 CLI 移動到 webpack-cli 中,你須要經過安裝 webpack-cli 使用 CLI。
  • 你可使用 optimization.* 標誌來配置本身的自定義模式。
  • webpackIncludewebpackExclude 能夠經過神奇的註釋來支持 import() ,他們容許在使用動態表達式時過濾文件。
  • 使用 System.import() 會發出警告:
    • 可使用 Rule.parser.system: true 關閉警告。
    • 你也可使用 Rule.parser.system: false 關閉 System.import()
  • 對於遷移到新的插件系統的插件 ProgressPlugin 如今顯示插件名稱。
  • webpack 如今能夠本地處理 JSON。若是用 loader 轉換 json 爲 js,須要設置:type: "javascript/auto"。固然,不用 loader webpack 依然能夠正常工做。

2.4 配置

  • 刪除了一些經常使用內置插件:
    • NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors (生產模式默認)
    • ModuleConcatenationPlugin -> optimization.concatenateModules (生產模式默認)
    • NamedModulesPlugin -> optimization.namedModules (開發模式默認)
    • **刪除了經常使用的CommonsChunkPlugin -> optimization.splitChunks**對於那些須要細粒度控制緩存策略的人,能夠經過 optimization.splitChunks和optimization.runtimeChunk。
  • 如今可使用module.rules[].resolve來配置解析。它與全局配置合併
  • optimization.minimize 用於控制minimizing的開關。
    • 生產模式默認爲開,開發模式默認爲關。
  • optimization.minimizer 用於配置minimizers和選項。
  • 許多支持佔位符的配置選項如今也支持函數形式。
  • 錯誤的 options.dependencies 配置如今會拋出異常。
  • sideEffects 能夠經過 module.rules 覆蓋。
  • 添加 output.globalObject 配置選項以容許在運行時選擇全局對象引用。
  • 無需顯式設置entry和output屬性,webpack默認設置entry屬性爲./src,output的屬性爲./dist。
  • 移除module.loaders。

2.5 優化

  • uglifyjs-webpack-plugin 升級到了 v1,而且支持 ES6語法。
  • 能夠在 package.json 中配置sideEffects: false 。當設置這個字段以後,標識在使用的庫裏沒有任何反作用。這意味着webpack能夠從代碼中安全地清除任何re-exports。
  • 使用JSONP數組來代替JSONP函數 –> 異步支持。
  • 引入新的 optimization.splitChunks 選項。
  • webpack 能夠刪除無用代碼,以前是由 Uglify 刪除無用的代碼,如今 webpack 也能夠刪除無用的代碼。這能夠有效防止在 import 無用的代碼以後發生的崩潰。

如下是一些內部優化:

  • 用 tap 調用替換 plugin 調用(新的插件系統)
  • 將許多廢棄的插件遷移到新的插件系統API
  • 爲 json 模塊添加了 buildMeta.exportsType: "default"
  • 刪除了 Parser (parserStringArray, parserCalculatedStringArray) 中未使用的方法

2.6 性能

  • 默認狀況,UglifyJS 默認緩存和並行化(並未徹底實現緩存和並行化,webpack5的里程碑)。
  • 發佈了一個新版本的插件系統,因此事件鉤子和處理程序變的單一化。
  • 多個性能改進,特別是更快的增量重建。
  • 改進了RemoveParentModluesPlugin的性能。

2.7 破壞性的改變(插件、loader相關)

  • 新的插件系統
    • 插件方法是向後兼容的
    • 插件如今應該這樣使用 Compiler.hooks.xxx.tap(<plugin name>, fn)
  • Chunk.chunks/parents/blocks 再也不是數組。在內部使用一個集合,而且有方法來訪問它。
  • Parser.scope.renamesParser.scope.definitions 再也不是對象/數組,而是Map/Set。
  • 解析器使用 StackedSetMap(相似於LevelDB的數據結構)而不是數組。
  • 在應用插件時再也不設置 Compiler.options
  • 全部模塊的構造參數都發生了變化。
  • options 合併到 ContextModuleresolveDependenciesoptions 對象中.
  • 更改並重命名 import() 的依賴關係
  • Compiler.resolvers 移入可經過插件訪問的 Compiler.resolverFactory中。
  • Dependency.isEqualResource 已被替換爲 Dependency.getResourceIdentifier
  • Template 方法都是靜態的。
  • 已經添加了一個新的 RuntimeTemplate 類,outputOptionsrequestShortener 已經被移動到這個類中。
    • 已經更新了許多方法來代替 RuntimeTemplate 的使用。
    • 咱們計劃將訪問運行時的代碼移動到這個新類中
  • Module.meta已被Module.buildMeta所取代
  • 已添加Module.buildInfo和Module.factoryMeta
  • Module的一些屬性已經被移動到新的對象中
  • 添加指向上下文選項的 loaderContext.rootContextloaders 可使用它來建立相對於應用程序根目錄的東西。
  • 當啓用HMR時,將 this.hot 標誌添加到 loader 上下文中。
  • buildMeta.harmony 已被替換爲 buildMeta.exportsType:namespace
  • chunk 圖已經改變:
    • 以前:Chunks 的鏈接與嵌套依賴關係有關。
    • 如今:ChunksGroups 的鏈接與引用依賴有關,按照順序串聯。
    • 以前:AsyncDependenciesBlocks 按順序引用 Chunks 列表。
    • 如今:AsyncDependenciesBlocks 引用一個 ChunkGroup。

★★ 注意:以上內容都是關於 loaders、plugins 重大的變化。

3、重點更新詳解

3.1 更好的默認值

直到今日,webpack 老是要求顯式地設置 entryoutput 屬性。webpack4 中,webpack 會自動設定你的 entry 屬性爲 ./src 以及 output 的屬性爲 ./dist。 這意味着您再也不須要配置文件來啓動 webpack。接下來咱們爲你演示 webpack 4 的便捷操做:

一、咱們須要安裝好 webpack 以後,在 package.json 中添加以下腳本便可啓動:

"scripts": {
    "build": "webpack"
  },
複製代碼

二、在工程中添加簡單示例代碼以下圖(整個工程沒有 webpack 配置文件,便可運行打包):

無配置示例
(圖1,圖中示例代碼爲 webpack3 官網示例)

三、打包過程當中咱們發現有新特性的提示:

WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment. 
複製代碼

這就是咱們下節要說的內容模式設置

★★ 注意:入口默認爲 ./src 若是缺乏此文件夾會報錯!

> webpack --mode production

ERROR in Entry module not found: Error: Can't resolve './src' in 'D:\workspace\github\Webpack-Example' 複製代碼

3.2 模式設置

以往的項目使用 webpack3 腳手架生成項目初始模板都會有兩個甚至三個配置文件,好比 webpack.base.conf.jswebpack.prod.conf.jswebpack.dev.conf.js 而如今能夠作到一個配置文件都不須要,直接在啓動命令中傳入參數 --mode development | production 達到區分不一樣模式的效果。

接下來修改 package.json 設置不一樣的模式:

"scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
複製代碼

從新執行 npm run devnpm run build 便可看到不一樣的打包結果:

不一樣模式打包
咱們能夠看到兩種模式的結果徹底不一樣,下面咱們會更深刻的按照咱們真實的需求來說解一些經常使用配置。

接下來這個配置是最經常使用到的,咱們使用 webpack 的主要目的之一就是爲了更好的支撐前段模塊化的能力,既然須要模塊化固然少不了代碼分割,目前代碼分割有如下幾種:

  1. 經過 entry 分割不一樣入口,經常使用於多頁應用;
  2. 經過 CommonsChunkPlugin 插件來分割不一樣功能模塊;
  3. 經過動態 import 來分割。 下面咱們主要講解 webpack 4 版本的重大變化刪除了 CommonsChunkPlugin 插件。

3.3 刪除 CommonsChunkPlugin

webpack 4 刪除了 CommonsChunkPlugin,以支持兩個新的選項(optimization.splitChunksoptimization.runtimeChunk)。

從 4.0 開始分割 Chunk 將不在使用 CommonsChunkPlugin 插件,而是使用 optimization 配置項,具體的實現原理能夠參考:gist.github.com/sokra/1522d…

因爲尚未正式官方文檔出來,如下是咱們經過實踐出的 optimization 配置方法: 其中用到了新增的 splitChunks 屬性,此屬性看字面意思就明白是分割代碼塊的選項,其下可配置項已在下面示例代碼中列出(有興趣的朋友能夠自行實踐):

entry: {
  vendor: ['lodash']
},

...

optimization: {
    splitChunks: {
      chunks: "initial",         // 必須三選一: "initial" | "all"(默認就是all) | "async" 
      minSize: 0,                // 最小尺寸,默認0
      minChunks: 1,              // 最小 chunk ,默認1
      maxAsyncRequests: 1,       // 最大異步請求數, 默認1
      maxInitialRequests : 1,    // 最大初始化請求書,默認1
      name: ()=>{},              // 名稱,此選項課接收 function
      cacheGroups:{                 // 這裏開始設置緩存的 chunks
        priority: "0",              // 緩存組優先級
        vendor: {                   // key 爲entry中定義的 入口名稱
          chunks: "initial",        // 必須三選一: "initial" | "all" | "async"(默認就是異步) 
          test: /react|lodash/,     // 正則規則驗證,若是符合就提取 chunk
          name: "vendor",           // 要緩存的 分隔出來的 chunk 名稱
          minSize: 0,
          minChunks: 1,
          enforce: true,
          maxAsyncRequests: 1,       // 最大異步請求數, 默認1
          maxInitialRequests : 1,    // 最大初始化請求書,默認1
          reuseExistingChunk: true   // 可設置是否重用該chunk(查看源碼沒有發現默認值)
        }
      }
    }
  },
複製代碼

以上就是 optimization.splitChunks 的全部可用的配置項屬性。

總結

以上就是咱們初步整理的關於 webpack 4 的新特性,包含了一部分的官方更新日誌的翻譯,還有咱們本身試驗的一些屬性。固然若是你有興趣,也能夠等到正式的官方文檔發佈以後進行實踐。

若是上面的信息不可以徹底知足你的興趣,還請關注官方日誌。在將來不到一個月的時間裏,webpack 將對插件、加載器以及整個生態系統進行更加嚴格的測試,併發布最終的官方穩定版本。若是你喜歡 webpack,你能夠參與使用 webpack4.0.0.beta,若是提出的問題越多,即可覺得你們提供更加穩定的版本。

示例代碼:

demo

參考資料:


webpack 4 beta — try it today! . Sean T. Larkin

webpack v4.0.0-beta.0 release . Tobias Koppers

webpack 4.0.0-alpha.5 feedback . Tobias Koppers

相關文章
相關標籤/搜索