從 webpack v1 遷移到 webpack v2

發表於2017-01-22

resolve.root, resolve.fallback,resolve.modulesDirectories

上述配置項被一個單獨的配置項 resolve.modules 取代。詳見 resolving

resolve.extensions

此配置項不再需要傳一個空字串。此行為被遷移到 resolve.enforceExtension。詳見 resolving

resolve.*

還有更多的變化,由於不常用,不在這裡詳細列出。詳見 resolving

module.loaders 改成了 module.rules

舊的 loader 配置被更強大的 rules 系統取代,後者允許配置 loader 以及其他更多項。為了相容舊版,module.loaders 語法被保留,舊的屬性名依然可以被解析。新的命名約定更易於理解並且是升級配置使用 module.rules 的好理由。

鏈式 loaders

與 v1 版本相同,loaders 可以鏈式呼叫,上一個 loader 的輸出被作為輸入傳給下一個 loader。使用 rule.use 配置項,use 可以設定為一個 loaders 的列表。在 v1 版本中,loaders 通常被用 ! 連寫。這一寫法在新版中只在使用舊的 module.loaders 時有效。

取消了在模組名中自動新增 -loader 字尾

現在在指定 loader 的時候不能再省略 -loader 字尾了:

你仍然可以啟用這一舊行為,方法是通過配置 resolveLoader.moduleExtensions 項,但是我們不推薦這麼做。

瞭解這一改變背後的原因,請參閱 #2986

json-loader 不再需要手動新增

如果沒有為 JSON 檔案配置 loader,webpack 將自動嘗試通過 載入 json-loader JSON 檔案。

我們決定這麼做 以消弭 webpack、 node.js 和 browserify 之間的環境差異。

loader 預設的 resolve 配置是相對於 context 的

在 webpack 1 中,loader 預設配置下 resolve 相對於被匹配的檔案。而在 webpack 2 中預設配置的 resolve 相對於 context 配置項。

這解決了一些問題,比如使用 npm link 或引用 context 之外的模組時導致重複載入。

你可以不再需要使用一些變通方案了:

取消了 module.preLoaders 以及 module.postLoaders

UglifyJsPlugin sourceMap

UglifyJsPluginsourceMap 配置項現在預設為 false 而不是 true

這意味著如果你在壓縮程式碼時啟用了 source map,或者想要讓 uglifyjs 的警告能夠對應到正確的程式碼行,你需要將 UglifyJsPluginsourceMap 設為 true

UglifyJsPlugin warnings

UglifyJsPlugincompress.warnings 配置項現在預設為 false 而不是 true

這意味著如果你想要看到 uglifyjs 的警告資訊,你需要將 compress.warnings 設為 true

UglifyJsPlugin 壓縮 loaders

UglifyJsPlugin 不再壓縮 loaders。在未來很長一段時間裡,需要通過設定 minimize:true 來壓縮 loaders。參考 loader 文件裡的相關配置項。

loaders 的壓縮模式將在 webpack 3 或更高的版本中被取消。

為了相容舊的 loaders,loaders 可以通過外掛來切換到壓縮模式:

OccurrenceOrderPlugin 被預設載入

我們不再需要在配置裡指定它:

ExtractTextWebpackPlugin 大變化

ExtractTextPlugin 1.0.0 不能在 webpack v2 下工作。 你需要明確地安裝 ExtractTextPlugin v2。

npm install --save-dev extract-text-webpack-plugin@beta

這一外掛的配置變化主要體現在語法上。

ExtractTextPlugin.extract

new ExtractTextPlugin({options})

全動態 requires 現在預設會失敗

只有一個表示式的依賴(例如 require(expr))將建立一個空的 context 而不是一個完整目錄的 context。

如果有上面那樣的程式碼,最好把它重構了,因為在 ES2015 模組下它不可以用。如果你確定不會有 ES2015 模組,你可以使用 ContextReplacementPlugin 來提示編譯器進行正確的處理。

此處欠一篇關於動態依賴的文章。

在 CLI 和配置中使用自定義引數

如果你之前濫用 CLI 來傳自定義引數到配置中,比如:

webpack --custom-stuff

你將會發現新版中不再允許這麼做。CLI 現在更加嚴格了。

替代地,現在提供了一個介面來傳遞引數給配置。我們應該採用這種新方式,在未來許多工具將可能依賴它。

webpack --env.customStuff

詳見 CLI

require.ensure 以及 AMD require 的非同步

現在這些函式總是非同步的,而不是當 chunk 已經載入過的時候同步呼叫它們的 callback。

注意 require.ensure 現在依賴於原生的 Promise。如果在不支援 Promise 的環境裡使用require.ensure,你需要新增 polyfill。

通過 options 配置 loader

你不能再通過 webpack.config.js 的自定義屬性來配置 loader。只能通過 options 來配置。下面配置的 ts 屬性在 webpack 2 下不再有效:

什麼是 options?

好問題。嚴格來說,有兩種辦法,都可以用來配置 webpack 的 loader。典型的 options 被稱為query,是一個可以被新增到 loader 名之後的字串。它比較像一個 query string,但是實際上有更強大的能力

不過它也可以分開來,寫成一個單獨的物件,緊跟在 loader 屬性後面:

LoaderOptionsPlugin context

有的 loader 需要從配置中讀取一些 context 資訊。在未來很長一段時間裡,這將需要通過 loader options 傳入。詳見 loader 文件的相關選項。

為了保持對舊 loaders 的相容,這些資訊可以通過外掛傳進來:

debug

在 webpack 1 中 debug 配置項切換 loaders 到 debug 模式。在未來很長一段時間裡,這將需要通過 loader 配置項傳遞。詳見 loader 文件的相關選項。

loaders 的 debug 模式將在 webpack 3 或後續版本中取消。

為了保持對舊 loaders 的相容,loader 可以通過外掛來切換到 debug 模式。

ES2015 的程式碼分割

在 webpack v1 中,你能使用 require.ensure 作為方法來懶載入 chunks 到你的應用中:

ES2015 模組載入規範定義了 import() 方法來執行時動態地載入 ES2015 模組。

webpack 將 import() 作為分割點並將被請求的模組放到一個單獨的 chunk 中。

import() 接收模組名作為引數,並返回一個 Promise。

好訊息是:如果載入 chunk 失敗,我們可以進行處理,因為現在它基於 Promise

警告:require.ensure 允許用可選的第三個引數為 chunk 簡單命名,但是 import API 還未提供這個能力。如果你想要保留這個功能,你可以繼續使用 require.ensure

(注意廢棄的 System.import:Webpack 對 System.import 的使用不符合新提出的標準,所以它在v2.1.0-beta.28 版本中被廢棄,轉向支援 import()

由於這個建議還在 Stage 3,如果你想要同時使用 importBabel,你需要安裝/新增 dynamic-import 語法外掛來繞過解析錯誤。當建議被新增到規範之後,就不再需要這個語法外掛了。

動態表示式

可以傳遞部分表示式給 import()。這與 CommonJS 對錶達式的處理方式一致(webpack 為所有可能匹配的檔案建立 context)。

import() 為每一個可能的模組建立獨立的 chunk。

混合使用 ES2015、AMD 和 CommonJS

你可以自由混合使用三種模組型別(甚至在同一個檔案中)。在這個情況中 webpack 的行為和 babel 以及 node-eps 一致:

值得注意的是,你需要讓 Babel 不解析這些模組符號,從而讓 webpack 可以使用它們。你可以通過設定如下配置到 .babelrc 或 babel-loader 來實現這一點。

.babelrc

Hints

不需要改變什麼,不過也可以改變。

模板字串

webpack 現在支援表示式中的模板字串了。這意味著你可以在 webpack 構建中使用它們:

配置中使用 Promise

webpack 現在支援在配置檔案中返回 Promise 了。這讓你能在配置檔案中做非同步處理。

webpack.config.js

高階 loader 匹配

webpack 現在支援對 loader 進行更多方式的匹配。

更多的 CLI 引數項

你可以使用一些新的 CLI 引數項:

--define process.env.NODE_ENV="production"DefinePlugin.

--display-depth 顯示每個模組到入口的距離。

--display-used-exports 顯示一個模組中被使用的 exports 資訊。

--display-max-modules 設定輸出時顯示的模組數量(預設是 15)。

-p 能夠定義 process.env.NODE_ENV"production"

Loader 變化

僅與 loader 作者有關的改變。

Cacheable

Loaders 現在預設可被快取。Loaders 如果不想被快取,需要選擇不被快取。

複合 options

webpack 1 只支援能夠 JSON.stringify 的物件作為配置項。webpack 2 現在支援任意 JS 物件作為 loader 配置項。

使用複合 options 只有一個附加條件。你需要在 options 物件上新增一個 ident,讓它能夠被其他 loader 引用。

options 物件上有了 ident ,內聯的 loader 就可以引用這個 options 物件。下面是個例子:

require("some-loader??by-ident!resource")

這種內聯風格在常規的程式碼裡一般用不著,但是在 loader 生成的程式碼裡比較常見。比如,style-loader 生成一個模組,通過 require 載入其餘的請求(它們輸出 CSS)。

所以如果你使用複合 options,告訴你的使用者你使用的 ident

相關文章