@babel/插件:装饰器提案
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
示例
简单的类装饰器
@annotation
class MyClass {}
function annotation(target) {
target.annotated = true;
}
类装饰器
@isTestable(true)
class MyClass {}
function isTestable(value) {
return function decorator(target) {
target.isTestable = value;
};
}
类方法装饰器
class C {
message = "hello!";
@bound
m() {
console.log(this.message);
}
}
function bound(value, { name, addInitializer }) {
addInitializer(function () {
this[name] = this[name].bind(this);
});
}
安装
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/plugin-proposal-decorators
yarn add --dev @babel/plugin-proposal-decorators
pnpm add --save-dev @babel/plugin-proposal-decorators
bun add --dev @babel/plugin-proposal-decorators
用法
通过配置文件(推荐)
{
"plugins": [
["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
]
}
通过 Node API
require("@babel/core").transformSync("code", {
plugins: [
["@babel/plugin-proposal-decorators", { version: "2023-11" }],
]
});
配置选项
History
| Version | Changes |
|---|---|
v7.24.0 | Added support for version: "2023-11" |
v7.22.0 | Added support for version: "2023-05" |
v7.21.0 | Added support for version: "2023-01" |
v7.19.0 | Added support for version: "2022-03" |
v7.17.0 | Added the version option with support for "2021-12", "2018-09" and "legacy" |
version
"2023-11", "2023-05", "2023-01", "2022-03", "2021-12", "2018-09" or "legacy".
Selects the decorators proposal to use:
"2023-11"is the proposal version after the updates that reached consensus in the November 2023 TC39 meetings, intergrating this change"2023-05"is the proposal version after the updates that reached consensus in the March and May 2023 TC39 meetings, integrating these changes."2023-01"is the proposal version after the updates that reached consensus in the January 2023 TC39 meeting, integratingpzuraq/ecma262#4."2022-03"is the proposal version that reached consensus for Stage 3 in the March 2022 TC39 meeting. You can read more about it attc39/proposal-decorators@8ca65c046d."2021-12"is the proposal version as it was presented to TC39 in Dec 2021. You can read more about it attc39/proposal-decorators@d6c056fa06."2018-09"is the proposal version that was initially promoted to Stage 2 presented to TC39 in Sept 2018. You can read more about it attc39/proposal-decorators@7fa580b40f.legacyis the legacy Stage 1 proposal, defined atwycats/javascript-decorators@e1bf8d41bf. The legacy mode will not have feature updates, and there are known discrepancies between Babel and TypeScript. It's recommended to migrate to the"2023-11"proposal.
Babel 8 will only support "2023-11" and "legacy". If you are using a different decorators version, it's recommended to migrate to "2023-11".
The spec repo provides a brief summary of the differences between these versions.
If you specify the decoratorsBeforeExport option, version defaults to "2018-09", otherwise it is a required option.
decoratorsBeforeExport
This option:
- is disallowed when using
version: "legacy",version: "2022-03",version: "2023-01",version: "2023-05"orversion: "2023-11"; - is required when using
version: "2018-09"; - is optional and defaults to
falsewhen usingversion: "2021-12".
boolean
// decoratorsBeforeExport: false
export @decorator class Bar {}
// decoratorsBeforeExport: true
@decorator
export class Foo {}
This option was originally added to help tc39 collect feedback from the community by allowing experimentation with the proposed syntaxes. The proposal has now settled on allowing decorators either before or after export.
legacy
Use version: "legacy" instead. This option is a legacy alias.
boolean, defaults to false.
Use the legacy (stage 1) decorators syntax and behavior.
NOTE: Compatibility with @babel/plugin-transform-class-properties
If you are including your plugins manually and using class elements transforms such as
@babel/plugin-transform-class-properties@babel/plugin-transform-private-methods@babel/plugin-transform-private-property-in-object@babel/plugin-transform-class-static-block
make sure that @babel/plugin-proposal-decorators comes before them.
{
"plugins": [
- "@babel/plugin-transform-class-properties",
["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
+ "@babel/plugin-transform-class-properties"
]
}
If you are already using @babel/preset-env and Stage 3 decorators, you can safely remove the
class elements transform, Babel will automatically apply decorators transform before any presets:
{
"presets": [
["@babel/preset-env"],
],
"plugins": [
- "@babel/plugin-transform-class-properties",
["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
]
}
If you are using @babel/preset-env and legacy decorators, you must ensure the class elements transform is enabled regardless of your targets, because Babel only supports compiling legacy decorators when also compiling class properties:
{
"presets": [
["@babel/preset-env", {
+ "include": [
+ "@babel/plugin-transform-class-properties"
+ ]
}],
],
"plugins": [
- "@babel/plugin-transform-class-properties",
["@babel/plugin-proposal-decorators", { "version": "legacy" }]
]
}
The include option will enable the transforms included in @babel/preset-env so you can safely remove them from your package.json.
You can read more about configuring plugin options here
Symbol.metadata注意事项
当使用需要访问或修改装饰器上下文中元数据的装饰器时,您需要使用Symbol.metadata。如果Symbol.metadata不可用,Babel会默认使用Symbol.for("Symbol.metadata"):这可能导致与使用不同回退机制的其他包不兼容
为确保Symbol.metadata全局可用,并与Babel装饰器插件在转译过程中使用的符号匹配,您需要引入定义该符号的polyfill或自行定义:
Symbol.metadata = Symbol.for("Symbol.metadata");
您也可以使用第三方polyfill,例如core-js/proposals/decorator-metadata-v2.js。请确保该polyfill在使用装饰器或访问Symbol.metadata的任何代码之前执行