Skip to main content

@babel/helper-compilation-targets

@babel/helper-compilation-targets 是一个辅助程序包,适用于编译目标(浏览器或其他环境,如节点)和兼容表(知道哪个版本支持特定语法)。@babel/preset-env 使用它来根据 targets 选项确定应该启用哪个插件。

¥@babel/helper-compilation-targets is a helper package that works with compilation targets (browsers or other environments like node) and compat tables (knowing what version supports a specific syntax). It is used by @babel/preset-env to determine which plugin should be enabled based on the targets option.

JavaScript
import {
filterItems,
default as getTargets,
isRequired,
} from "@babel/helper-compilation-targets";

filterItems

function filterItems(
list: { [feature: string]: Targets },

// A set of plugins that should always be included
includes: Set<string>,

// A set of plugins that should always be excluded
excludes: Set<string>,
targets: Targets,

// A set of plugins that should always be included if `includes` is empty
defaultIncludes: Array<string> | null,

// A set of plugins that should always be excluded if `excludes` is empty
defaultExcludes?: Array<string> | null,

// A map from transform plugin to syntax plugin for backward compatibility with older `@babel/parser` versions
pluginSyntaxMap?: Map<string, string | null>
): Set<string>; // A set of enabled plugins

给定一个兼容数据表 list(即 @babel/compat-data)和 浏览器目标 targets,返回一组必需的插件。

¥Given a compat data table list (i.e. @babel/compat-data) and browser targets targets, return a set of required plugins.

示例

¥Example

JavaScript
const compatData = {
"transform-feature-1": {
chrome: "1",
firefox: "1",
},
"transform-feature-2": {
chrome: "2",
firefox: "2",
},
"transform-feature-3": {
chrome: "3",
firefox: "3",
},
"transform-feature-4": {
chrome: "4",
firefox: "4",
},
};

// filter a set of plugins required when compiled to chrome 2
// returns new Set(["transform-feature-3", "transform-feature-4"])
filterItems(compatData, new Set(), new Set(), {
chrome: 2,
});

// filter a set of plugins required when compiled to chrome 2 and firefox 1
// returns new Set(["transform-feature-2", "transform-feature-3", "transform-feature-4"])
filterItems(compatData, new Set(), new Set(), {
chrome: 2,
firefox: 1,
});

// always include "transform-feature-2" and exclude "transform-feature-4"
// returns new Set(["transform-feature-2", "transform-feature-3"])
filterItems(
compatData,
new Set(["transform-feature-2"]),
new Set(["transform-feature-4"]),
{
chrome: 2,
}
);

// syntax-feature-2 is required to allow older @babel/parser to parse
// the feature-2 syntax supported in chrome 2

// returns new Set(["syntax-feature-2", "transform-feature-3", "transform-feature-4"])
filterItems(
compatData,
new Set(),
new Set(),
{
chrome: 2,
},
null,
null,
new Map([["transform-feature-2", "syntax-feature-2"]])
);
注意

当一个新的 ES 特性达到 stage-4 时,它将在 @babel/parser 中成熟,这意味着无论插件如何,它都会被解析。但是我们需要旧 @babel/parser 的语法插件。

¥When a new ES feature reaches stage-4, it will be matured in @babel/parser, which means it will always be parsed regardless of the plugin. However we need the syntax plugin for older @babel/parser.

getTargets

type GetTargetsOption = {
// This is not the path of the config file, but the path where start searching it from
configPath?: string;

// The path of the config file
configFile?: string;

// The env to pass to browserslist
browserslistEnv?: string;

// true to disable config loading
ignoreBrowserslistConfig?: boolean;
};

type InputTargets = {
...Targets,

browsers?: Browsers,

// When `true`, this completely replaces the `browsers` option.
// When `intersect`, this is intersected with the `browsers`
// option (giving the higher browsers as the result).
esmodules?: boolean | "intersect",
};

function getTargets(
inputTargets: InputTargets = {},
options: GetTargetsOption = {}
): Targets;

将用户指定的 targets 规范化为支持的目标列表。另请参阅 (@babel/preset-env)[preset-env.md#options] 的 GetTargetsOption

¥Normalize user specified targets to a list of supported targets. See also (@babel/preset-env)[preset-env.md#options] for GetTargetsOption

示例

¥Example

JavaScript
// Return the default compilation targets
// returns {}
getTargets();

一个空的编译目标相当于 强制所有转换。Babel 8 中的默认编译目标将更改为 browserlists query defaults, not IE 11

¥An empty compilation target is equivalent to force all transforms. The default compilation targets will be changed to browserlists query defaults, not IE 11 in Babel 8.

还可以使用 ES 模块支持查询编译目标,就像 @vue/babel-preset-app 所做的那样,以提供一组现代目标。

¥One can also query the compilation targets with ES Module support, like @vue/babel-preset-app did in order to provide a set of modern targets.

JavaScript
/* returns {
"android": "61.0.0",
"chrome": "61.0.0",
"edge": "16.0.0",
"firefox": "60.0.0",
"ios": "10.3.0",
"node": "13.2.0",
"opera": "48.0.0",
"safari": "10.1.0",
"samsung": "8.2.0",
} */
getTargets({
esmodules: true,
});

注意:ES Module 兼容数据是从 MDN 生成的。

¥Note: The ES Module compat data is generated from MDN.

isRequired

function isRequired(
name: string,
targets: Targets,
{
compatData = pluginsCompatData,
includes,
excludes,
}: {
compatData?: { [feature: string]: Targets };
includes?: Set<string>;
excludes?: Set<string>;
} = {}
): boolean;

给定浏览器目标 targets,查询 compatData 是否需要插件 name 进行编译。不指定 compatData 时,默认数据源为 @babel/compat-data

¥Given browser targets targets, query the compatData whether plugin name is required for compilation. When compatData is not specified, the default data source is @babel/compat-data

示例

¥Example

babel.config.js
module.exports = api => {
const targets = api.targets();
// The targets have native optional chaining support
// if `transform-optional-chaining` is _not_ required
const optionalChainingSupported = !isRequired(
"transform-optional-chaining",
targets
);
};

插件作者可以使用 isRequired 来优化给定不同 targets 的插件输出:

¥Plugin authors can use isRequired to optimize plugin output given different targets:

example-babel-plugin.js
// a naive plugin replace `a.b` to `a != null && a.b`
module.exports = api => {
const targets = api.targets();
// The targets have native optional chaining support
// if `transform-optional-chaining` is _not_ required
const optionalChainingSupported = !isRequired(
"transform-optional-chaining",
targets
);
const visited = new WeakSet();
return {
visitor: {
MemberExpression(path) {
if (path.matchesPattern("a.b")) {
if (visited.has(path.node)) return;
visited.add(path.node);
if (optionalChainingSupported) {
// When optional chaining is supported,
// output `a?.b` instead of `a != null && a.b`
path.replaceWith(api.templates`a?.b`);
} else {
path.replaceWith(api.templates`a != null && ${path.node}`);
}
}
},
},
};
};

@babel/plugin-transform-object-rest-spread 使用 isRequired 来确定目标是否已经具有原生 Object.assign 支持。

¥@babel/plugin-transform-object-rest-spread uses isRequired to determine whether targets already have native Object.assign support.