此 README 適用於搭配 Babel v7 的 babel-loader v8/v9。如果您使用舊版 Babel v6,請參閱 7.x 分支 文件
此套件允許使用 Babel 和 webpack 來轉譯 JavaScript 檔案。
注意:輸出問題應回報給 Babel 問題 追蹤器。
babel-loader 支援的 webpack 版本 支援的 Babel 版本 支援的 Node.js 版本 8.x 4.x 或 5.x 7.x >= 8.9 9.x 5.x ^7.12.0 >= 14.15.0
npm install -D babel-loader @babel/core @babel/preset-env webpack
webpack 文件:載入器
在 webpack 組態物件中,您需要將 babel-loader 加入模組清單,如下所示
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }]
]
}
}
}
]
}
請參閱 babel
選項。
您可以透過使用 options
屬性將選項傳遞給載入器
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }]
],
plugins: ['@babel/plugin-proposal-class-properties']
}
}
}
]
}
此載入器還支援下列載入器特定選項
cacheDirectory
:預設為 false
。設定後,將使用指定的目錄快取載入器的結果。未來的 webpack 建置會嘗試從快取中讀取,以避免在每次執行時執行可能耗時的 Babel 重新編譯程序。如果在選項中將值設定為 true
({cacheDirectory: true}
),載入器將使用 node_modules/.cache/babel-loader
中的預設快取目錄,或是在任何根目錄中找不到 node_modules
資料夾時退回到預設的 OS 暫存檔案目錄。
cacheIdentifier
:預設為由 @babel/core
的版本、babel-loader
的版本、.babelrc
檔案的內容(如果存在),以及環境變數 BABEL_ENV
的值(退回到環境變數 NODE_ENV
)組成的字串。如果識別碼變更,可以將此設定為自訂值以強制快取失效。
cacheCompression
:預設為 true
。設定後,每個 Babel 轉換輸出都會使用 Gzip 壓縮。如果您想退出快取壓縮,請將其設定為 false
-- 如果您的專案編譯了數千個檔案,這可能會對您的專案有幫助。
customize
:預設為 null
。匯出 custom
回呼的模組路徑,類似傳遞給 .custom()
的路徑。由於你已經建立新的檔案來使用此功能,建議改用 .custom
建立包裝載入器。只有在必須繼續直接使用 babel-loader
,但仍想自訂時,才使用此功能。
metadataSubscribers
:預設為 []
。採用內容函式名稱陣列。例如,如果你傳遞 ['myMetadataPlugin'],你會在 webpack 外掛的掛勾中將訂閱函式指定給 context.myMetadataPlugin
,而該函式將會呼叫 metadata
。
請確定你轉換的檔案越少越好。由於你可能比對 /\.m?js$/
,你可能會轉換 node_modules
資料夾或其他不需要的來源。
若要排除 node_modules
,請參閱上方所述的 loaders
設定中的 exclude
選項。
你也可以透過使用 cacheDirectory
選項,將 babel-loader 的速度提升至 2 倍。這會將轉換快取至檔案系統。
雖然我們通常建議不要編譯 node_modules
,但你可能需要在使用不支援 IE 11 或任何舊版目標的函式庫時進行編譯。
針對這個情況,你可以使用 test
和 not
的組合,或 傳遞函式 給你的 exclude
選項。你也可以使用負向先行斷言正規表示法,如 此處 所建議。
{
test: /\.(?:js|mjs|cjs)$/,
exclude: {
and: [/node_modules/], // Exclude libraries in node_modules ...
not: [
// Except for a few of them that needs to be transpiled because they use modern syntax
/unfetch/,
/d3-array|d3-scale/,
/@hapi[\\/]joi-date/,
]
},
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "ie 11" }]
]
}
}
}
Babel 使用非常小的輔助程式來執行一般函式,例如 _extend
。預設情況下,這會新增至需要它的每個檔案。
你也可以將 Babel 執行時間作為獨立模組來需要,以避免重複。
下列設定會停用 Babel 中的自動逐檔案執行時間注入,而需要 @babel/plugin-transform-runtime
,並讓所有輔助程式參考都使用它。
請參閱 文件 以取得更多資訊。
注意:你必須執行 npm install -D @babel/plugin-transform-runtime
才能將其包含在你的專案中,並將 @babel/runtime
本身作為相依性,並使用 npm install @babel/runtime
。
rules: [
// the 'transform-runtime' plugin tells Babel to
// require the runtime instead of inlining it.
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }]
],
plugins: ['@babel/plugin-transform-runtime']
}
}
}
]
由於 @babel/plugin-transform-runtime 包含一個多重載入,其中包含自訂 regenerator-runtime 和 core-js,因此下列使用 webpack.ProvidePlugin
的一般性假冒方法將無法運作
// ...
new webpack.ProvidePlugin({
'Promise': 'bluebird'
}),
// ...
下列方法也無法運作
require('@babel/runtime/core-js/promise').default = require('bluebird');
var promise = new Promise;
輸出為 (使用 runtime
)
'use strict';
var _Promise = require('@babel/runtime/core-js/promise')['default'];
require('@babel/runtime/core-js/promise')['default'] = require('bluebird');
var promise = new _Promise();
前一個 Promise
函式庫在被覆寫之前被參考並使用。
一種方法是在你的應用程式中有一個「開機」步驟,在你的應用程式之前覆寫預設全域變數
// bootstrap.js
require('@babel/runtime/core-js/promise').default = require('bluebird');
// ...
require('./app');
babel
的 Node.js API 已移至 babel-core
。如果您收到此訊息,表示您已安裝 npm 套件 babel
,並在 webpack 設定中使用載入器的簡寫符號(在 webpack 2.x 中已不再有效)
{
test: /\.(?:js|mjs|cjs)$/,
loader: 'babel',
}
webpack 接著會嘗試載入 babel
套件,而不是 babel-loader
。
若要修正此問題,您應該解除安裝 npm 套件 babel
,因為它已在 Babel v6 中棄用。(請改為安裝 @babel/cli
或 @babel/core
。)如果您的其中一個相依性正在安裝 babel
,而您無法自行解除安裝,請在 webpack 設定中使用載入器的完整名稱
{
test: /\.(?:js|mjs|cjs)$/,
loader: 'babel-loader',
}
如果 core-js
和 webpack/buildin
被 Babel 轉譯,將會造成錯誤。
您需要將它們從 babel-loader
中排除。
{
"loader": "babel-loader",
"options": {
"exclude": [
// \\ for Windows, / for macOS and Linux
/node_modules[\\/]core-js/,
/node_modules[\\/]webpack[\\/]buildin/,
],
"presets": [
"@babel/preset-env"
]
}
}
該函式是由 Webpack 本身在執行 babel-loader
之後 注入的。預設情況下,Webpack 假設您的目標環境支援部分 ES2015 功能,但您可以使用 output.environment
Webpack 選項(文件)覆寫此行為。
若要避免頂層箭頭函式,您可以使用 output.environment.arrowFunction
// webpack.config.js
module.exports = {
// ...
output: {
// ...
environment: {
// ...
arrowFunction: false, // <-- this line does the trick
},
},
};
Webpack 支援組合多個 目標。對於您可能想要為每個目標(例如 web
和 node
)使用不同 Babel 設定的情況,此載入器透過 Babel 的 caller API 提供 target
屬性。
例如,若要根據 webpack 目標變更傳遞給 @babel/preset-env
的環境目標
// babel.config.js
module.exports = api => {
return {
plugins: [
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining"
],
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "entry",
// caller.target will be the same as the target option from webpack
targets: api.caller(caller => caller && caller.target === "node")
? { node: "current" }
: { chrome: "58", ie: "11" }
}
]
]
}
}
babel-loader
公開一個載入器建構器工具程式,讓使用者可以為每個它處理的檔案新增 Babel 組態的自訂處理。
.custom
接受一個回呼函式,該函式會使用載入器的 babel
實例呼叫,以便工具程式可以確保它使用與載入器本身完全相同的 @babel/core
實例。
在您想要自訂但實際上沒有檔案可以呼叫 .custom
的情況下,您也可以傳遞 customize
選項,並附帶指向匯出您的 custom
回呼函式的檔案的字串。
// Export from "./my-custom-loader.js" or whatever you want.
module.exports = require("babel-loader").custom(babel => {
// Extract the custom options in the custom plugin
function myPlugin(api, { opt1, opt2 }) {
return {
visitor: {},
};
}
return {
// Passed the loader options.
customOptions({ opt1, opt2, ...loader }) {
return {
// Pull out any custom options that the loader might have.
custom: { opt1, opt2 },
// Pass the options back with the two custom options removed.
loader,
};
},
// Passed Babel's 'PartialConfig' object.
config(cfg, { customOptions }) {
if (cfg.hasFilesystemConfig()) {
// Use the normal config
return cfg.options;
}
return {
...cfg.options,
plugins: [
...(cfg.options.plugins || []),
// Include a custom plugin in the options and passing it the customOptions object.
[myPlugin, customOptions],
],
};
},
result(result) {
return {
...result,
code: result.code + "\n// Generated by some custom loader",
};
},
};
});
// And in your Webpack config
module.exports = {
// ..
module: {
rules: [{
// ...
loader: path.join(__dirname, 'my-custom-loader.js'),
// ...
}]
}
};
customOptions(options: Object): { custom: Object, loader: Object }
針對載入器的選項,將自訂選項從 babel-loader
的選項中拆分出來。
config(cfg: PartialConfig, options: { source, customOptions }): Object
針對 Babel 的 PartialConfig
物件,傳回應該傳遞給 babel.transform
的 options
物件。
result(result: Result): Result
針對 Babel 的結果物件,允許載入器對它進行額外的調整。