跳至主内容

@babel/plugin-transform-modules-umd

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

History
VersionChanges
v7.14.0Implemented the importInterop option
信息

此插件已包含在 @babel/preset-envmodules 选项中

此插件可将 ES2015 模块转换为 UMD 格式。请注意仅会转换 import/export 语句的_语法_(如 import "./mod.js"),因为 Babel 无法感知 ES2015 模块与 UMD 在解析算法上的差异。

⚠️ 本插件不支持动态导入 (import('./lazy.js'))。

示例

输入

JavaScript
export default 42;

输出

JavaScript
(function(global, factory) {
if (typeof define === "function" && define.amd) {
define(["exports"], factory);
} else if (typeof exports !== "undefined") {
factory(exports);
} else {
var mod = {
exports: {},
};
factory(mod.exports);
global.actual = mod.exports;
}
})(this, function(exports) {
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true,
});

exports.default = 42;
});

安装

npm install --save-dev @babel/plugin-transform-modules-umd

用法

通过配置文件(推荐)

babel.config.json
{
"plugins": ["@babel/plugin-transform-modules-umd"]
}

当模块在浏览器中运行时,您可以覆盖特定库的全局变量名称。例如 es6-promise 库会将自己暴露为 global.Promise 而非 global.es6Promise,可通过以下方式配置:

babel.config.json
{
"plugins": [
[
"@babel/plugin-transform-modules-umd",
{
"globals": {
"es6-promise": "Promise"
}
}
]
]
}

默认语义

关于默认语义需注意以下几点:

首先,此转换使用每个导入的基本文件名来生成 UMD 输出中的全局变量名。这意味着如果您导入多个具有相同基本名的模块,例如:

JavaScript
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";

将会被转译为引用同一个浏览器全局变量:

JavaScript
factory(global.fooBar, global.fooBar);

如果设置插件选项为:

JSON
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
}
}

仍然会将两者转译为同一个浏览器全局变量:

JavaScript
factory(global.fooBAR, global.fooBAR);

因为转换逻辑仅使用导入的基本名。

其次,指定的覆盖值仍会传递给 babel-types/src/converters 中的 toIdentifier 函数。这意味着如果指定成员表达式形式的覆盖值:

JSON
{
"globals": {
"fizzbuzz": "fizz.buzz"
}
}

这_不会_转译为 factory(global.fizz.buzz),而是根据 toIdentifier 的逻辑转译为 factory(global.fizzBuzz)

第三,无法覆盖导出的全局变量名。

使用 exactGlobals: true 获得更灵活的语义

以上行为可能限制 globals 映射的灵活性。要消除这些限制,可将 exactGlobals 选项设为 true,这将指示插件:

  1. 生成全局名称时始终使用完整导入路径而非基本名

  2. 跳过将 globals 覆盖值传递给 toIdentifier 函数,而是直接按原文字面使用。因此如果使用无效标识符或无效的非计算式(点号)成员表达式,将会报错

  3. 允许通过 globals 映射覆盖导出的全局名称,覆盖值必须是有效的标识符或成员表达式

因此,若将 exactGlobals 设置为 true 且不传递任何覆盖值,则以下首个示例:

JavaScript
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";

将转译为:

JavaScript
factory(global.fooBar, global.mylibFooBar);

若设置插件选项为:

JSON
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
},
"exactGlobals": true
}

则将转译为:

JavaScript
factory(global.fooBAR, global.mylib.fooBar);

最后,当插件选项设置为:

babel.config.json
{
"plugins": [
"@babel/plugin-external-helpers",
[
"@babel/plugin-transform-modules-umd",
{
"globals": {
"my/custom/module/name": "My.Custom.Module.Name"
},
"exactGlobals": true
}
]
],
"moduleId": "my/custom/module/name"
}

将转译为:

JavaScript
factory(mod.exports);
global.My = global.My || {};
global.My.Custom = global.My.Custom || {};
global.My.Custom.Module = global.My.Custom.Module || {};
global.My.Custom.Module.Name = mod.exports;

通过命令行

Shell
babel --plugins @babel/plugin-transform-modules-umd script.js

通过 Node API

JavaScript
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-modules-umd"],
});

配置选项

moduleIds

boolean 默认值:!!moduleId

添加于:v7.9.0

启用模块 ID 生成功能。

moduleId

string

添加于:v7.9.0

用于模块的硬编码 ID。不可与 getModuleId 同时使用。

getModuleId

(name: string) => string

添加于:v7.9.0

接收 Babel 生成的模块名,返回要使用的名称。返回假值将保留原始 name

moduleRoot

string

添加于:v7.9.0

要包含在生成模块名称中的根路径。

未列出的选项请参阅 @babel/plugin-transform-modules-commonjs 的选项