sucrase icon indicating copy to clipboard operation
sucrase copied to clipboard

Standard class fields

Open LarsDenBakker opened this issue 4 years ago • 3 comments

Class fields are currently compiled using assignment:

This:

class Foo {
  x = 'foo'; 
}

Becomes

class Foo {
  constructor() {
    this.x = 'foo';
  }
}

This is not correct, according to the class field spec it should be assignment: https://github.com/tc39/proposal-class-fields#public-fields-created-with-objectdefineproperty

This is how babel compiles them: https://babeljs.io/repl#?browsers=chrome%2070&build=&builtIns=false&spec=false&loose=false&code_lz=MYGwhgzhAEBiD29oG8BQ1oA9oF5oHIAzRfAbmlQF8g&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Cenv&prettier=false&targets=&version=7.9.6&externalPlugins=%40babel%2Fplugin-proposal-class-properties%407.8.3

Is this something we can do in sucrase?

LarsDenBakker avatar May 17 '20 08:05 LarsDenBakker

Hi @LarsDenBakker, thanks for the request.

Makes sense. The Sucrase behavior matches TypeScript's default, but TypeScript added a useDefineForClassFields mode to handle this nuance as well: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier

I was actually thinking of removing class field transpile in Sucrase in an upcoming breaking change, which would of course make the behavior spec compliant because it's using the JS engine's implementation, and it would also simplify Sucrase quite a bit. The syntax is supported natively by node >= 12, latest Chrome, and latest Firefox, so it feels like it's getting to a point where transpiling isn't needed anymore for Sucrase's use case. Do you think that would work for you, or do you need it to be transpiled?

alangpierce avatar May 17 '20 22:05 alangpierce

I'm actually investigating using sucrase in https://github.com/open-wc/open-wc/tree/master/packages/es-dev-server to compile very modern JS to not so modern JS, so that your code works on the latest few of the modern browsers.

For instance Safari doesn't support class fields or optional chaining yet. I'm using babel for this now, but it would be great to have something that's faster. I'm not sure if it aligns with the project goals now that I read into it a bit more :)

LarsDenBakker avatar May 18 '20 05:05 LarsDenBakker

Got it. Keeping support for the latest version of all modern browsers does seem reasonable, and Safari Technology Preview has class field support (so hopefully stable Safari will get it soon enough), so it may make sense to just wait a bit longer before dropping transpile for it in Sucrase. The original goal (and what we use at my work) was a "sucrase for development, babel for production" use case, with Safari as a lower priority since my team tends to use Chrome and Firefox for development. But there are certainly some valid "sucrase for production" use cases, and Safari for development also seems useful to keep support for if there's enough interest.

alangpierce avatar May 18 '20 06:05 alangpierce