Aller au contenu principal

@babel/plugin-proposal-decorators

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

Exemple

Décorateur de classe simple

JavaScript
@annotation
class MyClass {}

function annotation(target) {
target.annotated = true;
}

Décorateur de classe

JavaScript
@isTestable(true)
class MyClass {}

function isTestable(value) {
return function decorator(target) {
target.isTestable = value;
};
}

Décorateur de méthode de classe

JavaScript
class C {
message = "hello!";

@bound
m() {
console.log(this.message);
}
}

function bound(value, { name, addInitializer }) {
addInitializer(function () {
this[name] = this[name].bind(this);
});
}

Installation

npm install --save-dev @babel/plugin-proposal-decorators

Utilisation

Avec un fichier de configuration (Recommandé)

babel.config.json
{
"plugins": [
["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
]
}

Via l'API Node

JavaScript
require("@babel/core").transformSync("code", {
plugins: [
["@babel/plugin-proposal-decorators", { version: "2023-11" }],
]
});

Options

History
VersionChanges
v7.24.0Added support for version: "2023-11"
v7.22.0Added support for version: "2023-05"
v7.21.0Added support for version: "2023-01"
v7.19.0Added support for version: "2022-03"
v7.17.0Added 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, integrating pzuraq/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 at tc39/proposal-decorators@8ca65c046d.
  • "2021-12" is the proposal version as it was presented to TC39 in Dec 2021. You can read more about it at tc39/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 at tc39/proposal-decorators@7fa580b40f.
  • legacy is the legacy Stage 1 proposal, defined at wycats/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.
attention

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" or version: "2023-11";
  • is required when using version: "2018-09";
  • is optional and defaults to false when using version: "2021-12".

boolean

JavaScript
// 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

Deprecated

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.

babel.config.json
{
"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:

babel.config.json
{
"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:

babel.config.json
{
"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.

astuce

You can read more about configuring plugin options here

Notes sur Symbol.metadata

Lorsque vous utilisez des décorateurs qui accèdent ou modifient les métadonnées dans le contexte du décorateur, vous devez utiliser Symbol.metadata. Lorsque Symbol.metadata n'est pas disponible, Babel utilise par défaut Symbol.for("Symbol.metadata") : ceci peut être incompatible avec d'autres paquets utilisant un substitut différent.

Pour garantir que Symbol.metadata soit disponible globalement et corresponde au symbole utilisé par le plugin de décorateurs de Babel pendant la transpilation, vous devrez soit inclure un polyfill le définissant, soit le définir vous-même :

symbol-metadata-polyfill.js
Symbol.metadata = Symbol.for("Symbol.metadata");

Vous pouvez également utiliser un polyfill tiers, tel que core-js/proposals/decorator-metadata-v2.js. Assurez-vous que le polyfill est exécuté avant tout code utilisant des décorateurs ou accédant à Symbol.metadata.

Références