@babel/register
你可以使用 Babel 的方式之一是通过 require 钩子。require 钩子会绑定到 node 的 require,并在运行时自动编译文件。这相当于 CoffeeScript 的 coffee-script/register。
🌐 One of the ways you can use Babel is through the require hook. The require hook
will bind itself to node's require and automatically compile files on the
fly. This is equivalent to CoffeeScript's
coffee-script/register.
安装
🌐 Install
- npm
- Yarn
- pnpm
- Bun
npm install @babel/core @babel/register --save-dev
yarn add @babel/core @babel/register --dev
pnpm add @babel/core @babel/register --save-dev
bun add @babel/core @babel/register --dev
用法
🌐 Usage
require("@babel/register");
所有后续由 Node 需要的扩展名为 .es6、.es、.jsx、.mjs 和 .js 的文件都会被 Babel 转换。
🌐 All subsequent files required by node with the extensions .es6, .es, .jsx,
.mjs, and .js will be transformed by Babel.
在使用需要它的功能(比如生成器)时,你必须单独包含polyfill。
默认忽略 node_modules
🌐 Ignores node_modules by default
注意: 默认情况下,所有对 node_modules 的请求都会被忽略。你可以通过传递 ignore 选项来覆盖这个设置:
require("@babel/register")({
// This will override `node_modules` ignoring - you can alternatively pass
// an array of strings to be explicitly matched or a regex / function
ignore: [],
});
指定选项
🌐 Specifying options
require("@babel/register")({
// Array of ignore conditions, either a string, regex or a function. (Optional)
// File paths that match any condition are not compiled.
ignore: [
// When a file path matches this regex then it is **not** compiled
/regex/,
// The file's path is also passed to any ignore functions. It will
// **not** be compiled if `true` is returned.
function(filepath) {
return filepath !== "/path/to/es6-file.js";
},
],
// Array of accept conditions, either a regex or a function. (Optional)
// File paths that match all conditions are compiled.
only: [
// File paths that **don't** match this regex are not compiled
/my_es6_folder/,
// File paths that **do not** return true are not compiled
function(filepath) {
return filepath === "/path/to/es6-file.js";
},
],
// Setting this will remove the currently hooked extensions of `.es6`, `.es`, `.jsx`, `.mjs`,
// .cjs and .js so you'll have to add them back if you want them to be used again.
extensions: [".es6", ".es", ".jsx", ".js", ".mjs", ".cjs"],
// Setting this to false will disable the cache.
cache: true,
});
你也可以传入所有其他选项,包括 plugins 和 presets。注意,配置文件 也会被加载,并且程序化配置会覆盖文件配置选项。@babel/register 在配置文件中不支持 ignore 和 only。
🌐 You can pass in all other options as well, including plugins and presets.
Note that config files will also be loaded and the programmatic
config will be merged over top of the file config options. @babel/register does not support
ignore and only in config files.
环境变量
🌐 Environment variables
默认情况下,@babel/node 命令行工具和 @babel/register 会保存到你临时目录中的 json 缓存。
🌐 By default @babel/node cli and @babel/register will save to a json cache in your
temporary directory.
随着你的文件启动和编译,这将大大改善。不过,有些情况下你可能想改变这种行为,并且有一些环境变量可以让你做到这一点。
🌐 This will heavily improve with the startup and compilation of your files. There are however scenarios where you want to change this behaviour and there are environment variables exposed to allow you to do this.
BABEL_CACHE_PATH
指定不同的缓存位置。
🌐 Specify a different cache location.
BABEL_CACHE_PATH=/foo/my-cache.json babel-node script.js
BABEL_DISABLE_CACHE
禁用缓存。
🌐 Disable the cache.
BABEL_DISABLE_CACHE=1 babel-node script.js
即时编译插件和预设
🌐 Compiling plugins and presets on the fly
@babel/register 使用 Node 的 require() 钩子系统在加载文件时即时编译文件。虽然总体上这非常有用,但这也可能导致一些令人困惑的情况,比如在 require() 钩子中的代码会引发更多对 require 的调用,从而造成依赖循环。以 Babel 为例,这可能意味着在 Babel 尝试编译用户文件的过程中,Babel 自己可能在加载时就被迫去编译自己。
为了避免这个问题,这个模块明确禁止重入编译,例如,Babel 自身的编译逻辑显然不能即时触发对其他文件的进一步编译。这样做的缺点是,如果你想定义一个本身需要实时编译的插件或预设,整个过程会比较复杂。
🌐 To avoid this problem, this module explicitly disallows re-entrant compilation, e.g. Babel's own compilation logic explicitly cannot trigger further compilation of any other files on the fly. The downside of this is that if you want to define a plugin or preset that is itself live-compiled, the process is complicated.
关键是你自己的代码需要先加载插件/预设。假设插件/预设会预先加载它的所有依赖,你想要做的就是:
🌐 The crux of it is that your own code needs to load the plugin/preset first. Assuming the plugin/preset loads all of its dependencies up front, what you'll want to do is:
require("@babel/register")({
// ...
});
require("./my-plugin");
因为是你自己的代码触发了加载,而不是 @babel/register 本身的逻辑,所以这应该能够成功编译任何同步加载的插件/预设。
🌐 Because it is your own code that triggered the load, and not the logic within
@babel/register itself, this should successfully compile any plugin/preset
that loads synchronously.
实验性 Babel 8 实现
🌐 Experimental Babel 8 implementation
你还可以测试将在 Babel 8 中默认启用的新实验性实现,使用
🌐 You can also test the new experimental implementation that will be enabled by default in Babel 8, using
require("@babel/register/experimental-worker");
它内部异步运行 Babel,因此兼容 .mjs 配置文件。你已经可以在一些注意事项下将其作为 @babel/register 的替代品使用:
🌐 It internally runs Babel asynchronously, so it's compatible with .mjs configuration files. You can already use it as a replacement of @babel/register with a few caveats:
- 如果你以编程方式指定
@babel/register选项(使用require("@babel/register")({ /* ... options */ })),你必须确保它们是可序列化的。这意味着你不能传递内联定义的插件函数,而必须把它们移到单独的./my-plugin.js文件或babel.config.js文件里。 - 新的实现仍处于实验阶段:它应该有和现有版本一样的功能,但可能会出现一些新的错误和回归问题。
注意: @babel/register 不支持即时编译原生 Node.js ES 模块,因为目前没有用于拦截 ES 模块加载的稳定 API。