@babel/plugin-transform-modules-umd
历史
版本 | 变更 |
---|---|
v7.14.0 | 实现了 importInterop 选项 |
此插件包含在 @babel/preset-env
的 modules
选项下
此插件将 ES2015 模块转换为 UMD。请注意,只有导入/导出语句的*语法*(import "./mod.js"
)会被转换,因为 Babel 不知道 ES2015 模块和 UMD 实现之间不同的解析算法。
⚠️ 此插件不支持动态导入 (import('./lazy.js')
)。
示例
输入
export default 42;
输出
(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
- Yarn
- pnpm
npm install --save-dev @babel/plugin-transform-modules-umd
yarn add --dev @babel/plugin-transform-modules-umd
pnpm add --save-dev @babel/plugin-transform-modules-umd
用法
使用配置文件(推荐)
{
"plugins": ["@babel/plugin-transform-modules-umd"]
}
当此模块在浏览器中运行时,您还可以覆盖特定库的名称。例如,es6-promise
库将自身公开为 global.Promise
而不是 global.es6Promise
。这可以通过以下方式解决
{
"plugins": [
[
"@babel/plugin-transform-modules-umd",
{
"globals": {
"es6-promise": "Promise"
}
}
]
]
}
默认语义
关于默认语义,需要注意以下几点。
*首先*,此转换使用每个导入的 基名 来生成 UMD 输出中的全局名称。这意味着,如果您要导入多个具有相同基名的模块,例如
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
它将被转换为对同一个浏览器全局变量的两个引用
factory(global.fooBar, global.fooBar);
如果您将插件选项设置为
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
}
}
它仍然会将两者都转换为一个浏览器全局变量
factory(global.fooBAR, global.fooBAR);
因为转换仍然只使用导入的基名。
*其次*,指定的覆盖仍将传递给 babel-types/src/converters 中的 toIdentifier
函数。这意味着,如果您将覆盖指定为成员表达式,例如
{
"globals": {
"fizzbuzz": "fizz.buzz"
}
}
这将*不会*转换为 factory(global.fizz.buzz)
。相反,它将根据 toIdentifier
中的逻辑转换为 factory(global.fizzBuzz)
。
*第三*,您不能覆盖导出的全局名称。
使用 exactGlobals: true
实现更灵活的语义
所有这些行为都会限制 globals
映射的灵活性。要消除这些限制,您可以将 exactGlobals
选项设置为 true
。这样做会指示插件
- 在生成全局名称时始终使用完整的导入字符串,而不是基名
- 跳过将
globals
覆盖传递给toIdentifier
函数。相反,它们将按原样使用,因此如果您不使用有效的标识符或有效的非计算(点)成员表达式,则会出现错误。 - 允许通过
globals
映射覆盖导出的全局名称。任何覆盖都必须是有效的标识符或有效的成员表达式。
因此,如果您将 exactGlobals
设置为 true
并且不传递任何覆盖,则第一个示例
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
将被转换为
factory(global.fooBar, global.mylibFooBar);
如果您将插件选项设置为
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
},
"exactGlobals": true
}
那么它将被转换为
factory(global.fooBAR, global.mylib.fooBar);
最后,如果将插件选项设置为
{
"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"
}
它将被转换为
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;
通过 CLI
babel --plugins @babel/plugin-transform-modules-umd script.js
通过 Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-modules-umd"],
});
选项
moduleIds
boolean
默认为 !!moduleId
添加于:v7.9.0
启用模块 ID 生成。
moduleId
字符串
添加于:v7.9.0
要用于模块的硬编码 ID。不能与 getModuleId
一起使用。
getModuleId
(name: string) => string
添加于:v7.9.0
给定 babel 生成的模块名称,返回要使用的名称。返回假值将使用原始的 name
。
moduleRoot
字符串
添加于:v7.9.0
要包含在生成的模块名称上的根路径。
有关此处未列出的选项,请参阅 @babel/plugin-transform-modules-commonjs
的选项。