I'm unable to build code using TypeScript containing classes with properties.
test.ts
export class Foo {
bar = 'qux'
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext"
}
}
npx parcel build test.ts
(no special parcel configuration, plain package.json with non-parcel specific fields)
The build should succeed without error.
The build crashes with the following error:
SyntaxError: project/test.ts: Missing class properties transform.
1 | export class Foo {
> 2 | bar = 'qux'
| ^^^^^^^^^^^
3 | }
4 |
at File.buildCodeFrameError (project/node_modules/@babel/core/lib/transformation/file/file.js:267:12)
at NodePath.buildCodeFrameError (project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/index.js:144:21)
at pushBody (project/node_modules/@babel/plugin-transform-classes/lib/transformClass.js:156:20)
at buildBody (project/node_modules/@babel/plugin-transform-classes/lib/transformClass.js:130:5)
at classTransformer (project/node_modules/@babel/plugin-transform-classes/lib/transformClass.js:527:5)
at transformClass (project/node_modules/@babel/plugin-transform-classes/lib/transformClass.js:563:10)
at PluginPass.ClassExpression (project/node_modules/@babel/plugin-transform-classes/lib/index.js:63:54)
at newFn (project/node_modules/@babel/core/node_modules/@babel/traverse/lib/visitors.js:179:21)
at NodePath._call (project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:55:20)
at NodePath.call (project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:42:17)
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 2.0.0-nightly.77+287ac639
| Node | v12.13.1
| npm/Yarn | 1.12.1
| Operating System | macOS
You'll need to add @babel/plugin-proposal-class-properties in a babelrc (together with preset-env and preset-typescript, but I find it quite strange that this isn't part of the typescript preset.
(This is also recommended in the "official" starter: https://github.com/microsoft/TypeScript-Babel-Starter)
Maybe we should add it by default together with the typescript preset (because this works without any configuration when using tsc), or ask babel about this. @devongovett
cc. @nicolo-ribaudo. Should this be part of @babel/preset-typescript? How about other transforms that tsc enables by default (e.g. optional chaining).
We don't add them to the TypeScript preset because they are not actually part of TypeScript itself: they are part of JavaScript, on top of which TypeScript adds other features.
This is harder to see with class fields because they have actually been supported by TypeScript for a long time, and until recently the implemented version was different from the proposal.
However, optional chaining is a good example: TS implemented it not as a new TS feature, but because the proposal reached stage 3 and thus is almost part of the standard.
If we transpiled this features, then why shouldn't we transpile (for example) classes? They are also transpiled by TS by default.
They're part of JS, yes, but TS sometimes enables features by default before JS does, and advertises them in the TS docs and release notes as TS features. I'm kinda wondering if maybe preset-typescript should include all of the features that TSC includes. Otherwise we'll continue to get questions about why features that people perceive to be part of TS aren't working.
Classes is a good question though because sometimes you don't want to compile them, e.g. for modern browsers. TSC uses tsconfig to decide this but Babel probably shouldn't start reading that...
Maybe Babel should only include the features not already handled by preset-env? So if you add preset-env and preset-typescript together you'd always get all of the features supported by TSC. Over time these would move into preset-env and be removed from preset-typescript.
They can't be removed from @babel/preset-typescript: it would be a breaking change. If the typescript preset starts transpiling something, it can't stop doing so assuming that it's handled by @babel/preset-env. If we add the optional chaining transform to the TypeScript preset, it would always be transpiled regardless of @babel/preset-env.
However, I wouldn't be opposed to adding the syntax plugin: we already did it for object spread.
Sure, I wouldn't imagine it would happen very often, so doing it in the next major version of Babel makes sense to me.
Alternatively, typescript could become an option to preset-env? That way, you'd get TS (types and any other features they enable by default), and when support is added natively to browsers, it would stop being transpiled.
Just trying to come up with ways that would be less confusing for users in regards to what babel offers for ts vs what tsc offers and Microsoft documents in the TS docs.
Tiny note, this also seems to happen if my browserslist config is on last 1 chrome versions which should support class properties and no "real" transpilation would be necessary (I assume the transform is still needed to correctly strip property type annotations?).
Edit: Nvm I just realized that class properties are not yet stage 4, I guess then it should not yet be handled by the preset-env anyways.
We can add it to preset-env's shippedProposals option.
Tiny note, this also seems to happen if my browserslist config is on last 1 chrome versions which should support class properties and no "real" transpilation would be necessary
This is exactly why I don't think that the TypeScript preset should transpile ECMAScript features or proposals!
What's the correct way to use Parcel 2 without babel? I have a current Typescript setup without babel and I want to upgrade to use Parcel 2, and things just not working.
parcel 2.0.0-alpha.3.2
parcel index.html works fine.parcel build index.html throws: Missing class properties transform.{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
}
}
Throws whenever parcel index.html or parcel build index.html:
/node_modules/@parcel/ts-utils/src/index.js:2
export * from './FSHost';
^^^^^^
SyntaxError: Unexpected token export
at Module._compile (internal/modules/cjs/loader.js:721:23)
None working, so I HAVE to learn and use babel, right?
SyntaxError: Unexpected token export
You'll have to use parcel@nightly for now, there was a build issue when the last alpha was released.
without babel
This will completely disable Babel:
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"],
"*.{js,mjs,jsm,jsx,es6,cjs}": ["@parcel/transformer-js"],
}
}
FYI, since class properties are starting to be supported by engines, starting from Babel 7.10 they will be transpiled by @babel/preset-env when the shippedProposals option is enabled.
Babel 7.10 was just released, meaning @babel/plugin-proposal-class-properties is included in @babel/preset-env.
Most helpful comment
FYI, since class properties are starting to be supported by engines, starting from Babel 7.10 they will be transpiled by
@babel/preset-envwhen theshippedProposalsoption is enabled.