此自述文件适用于使用 Babel v7 的 babel-loader v8/v9。如果您使用的是旧版 Babel v6,请参阅 7.x 分支 文档
此包允许使用 Babel 和 webpack 转换 JavaScript 文件。
注意:输出问题应报告给 Babel Issues 跟踪器。
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
文件夹,则回退到默认的操作系统临时文件目录。
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 的调用者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 的结果对象,允许加载器对其进行额外的调整。