@babel/helper-compilation-targets
@babel/helper-compilation-targets
は、コンパイルターゲット(ブラウザやNode.jsなどの他の環境)と互換性テーブル(特定の構文をサポートするバージョンを知る)を扱うヘルパーパッケージです。 @babel/preset-env
で使用され、targets
オプションに基づいて、どのプラグインを有効にするかを決定します。
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
が与えられた場合、必要なプラグインのセットを返します。
例
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
には構文プラグインが必要です。
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
を、サポートされているターゲットのリストに正規化します。 GetTargetsOption
については、(@babel/preset-env
)[preset-env.md#options] も参照してください。
例
// Return the default compilation targets
// returns {}
getTargets();
空のコンパイルターゲットは、すべての変換を強制することと同等です。 デフォルトのコンパイルターゲットは、Babel 8でbrowserslistのクエリdefaults, not IE 11
に変更されます。
@vue/babel-preset-app
のように、ESモジュールをサポートするコンパイルターゲットをクエリして、最新のターゲットセットを提供することもできます。
/* 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モジュールの互換性データは、MDNから生成されます。
isRequired
function isRequired(
name: string,
targets: Targets,
{
compatData = pluginsCompatData,
includes,
excludes,
}: {
compatData?: { [feature: string]: Targets };
includes?: Set<string>;
excludes?: Set<string>;
} = {}
): boolean;
ブラウザターゲット targets
が与えられた場合、コンパイルにプラグイン name
が必要かどうかを compatData
に問い合わせます。 compatData
が指定されていない場合、デフォルトのデータソースは @babel/compat-data
です。
例
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
に基づいてプラグインの出力を最適化できます。
// 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
を既にサポートしているかどうかを判断します。