Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial implementation of the decorators proposal #3754

Merged
merged 1 commit into from
May 7, 2024
Merged

initial implementation of the decorators proposal #3754

merged 1 commit into from
May 7, 2024

Conversation

evanw
Copy link
Owner

@evanw evanw commented May 7, 2024

With this PR, esbuild now contains an implementation of the upcoming JavaScript decorators proposal. This is the same feature that shipped in TypeScript 5.0. You can read more about them in that blog post and in this other (now slightly outdated) extensive blog post here: https://2ality.com/2022/10/javascript-decorators.html. Here's a quick example:

const log = (fn, context) => function() {
  console.log(`before ${context.name}`)
  const it = fn.apply(this, arguments)
  console.log(`after ${context.name}`)
  return it
}

class Foo {
  @log static foo() {
    console.log('in foo')
  }
}

// Logs "before foo", "in foo", "after foo"
Foo.foo()

Note that this feature is different than the existing "TypeScript experimental decorators" feature that esbuild already implements. It uses similar syntax but behaves very differently, and the two are not compatible (although it's sometimes possible to write decorators that work with both). TypeScript experimental decorators will still be supported by esbuild going forward as they have been around for a long time, are very widely used, and let you do certain things that are not possible with JavaScript decorators (such as decorating function parameters). By default esbuild will parse and transform JavaScript decorators, but you can tell esbuild to parse and transform TypeScript experimental decorators instead by setting "experimentalDecorators": true in your tsconfig.json file.

Probably at least half of the work for this feature went into creating a test suite that exercises many of the proposal's edge cases: https://github.com/evanw/decorator-tests. It has given me a reasonable level of confidence that esbuild's initial implementation is acceptable. However, I don't have access to a significant sample of real code that uses JavaScript decorators. If you're currently using JavaScript decorators in a real code base, please try out esbuild's implementation and let me know if anything seems off.

⚠️ WARNING ⚠️

This proposal has been in the works for a very long time (work began around 10 years ago in 2014) and it is finally getting close to becoming part of the JavaScript language. However, it's still a work in progress and isn't a part of JavaScript yet, so keep in mind that any code that uses JavaScript decorators may need to be updated as the feature continues to evolve. The decorators proposal is pretty close to its final form but it can and likely will undergo some small behavioral adjustments before it ends up becoming a part of the standard. If/when that happens, I will update esbuild's implementation to match the specification. I will not be supporting old versions of the specification.

Fixes #104

@evanw evanw merged commit 4bc834c into main May 7, 2024
16 checks passed
@evanw evanw deleted the decorators branch May 7, 2024 02:37
@ghost
Copy link

ghost commented May 7, 2024

Thanks for all of you hard work @evanw !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Decorators support
1 participant