-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
V2: Typescript transform support through Babel (default) and tsc #3083
Conversation
0b7416d
to
5d83b02
Compare
packages/configs/tsc/index.json
Outdated
"transforms": { | ||
"*.{ts,tsx}": [ | ||
"@parcel/transformer-typescript-tsc", | ||
"@parcel/transformer-js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also run babel here? Might be surprising for TS users to always have their code run through babel, though it would be limited to preset-env
, flow-strip-types
(unnecessarily), and preset-react
(unnecessarily)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought we only added flow-strip-types
if we saw // @flow
and something similar for React? babel-preset-env
seems like it would still be valuable unless tsc is capable of something similar.
|
||
export default new Transformer({ | ||
async getConfig({asset}) { | ||
return asset.getConfig(['tsconfig.json']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use the compiler api rather than our own [0] like @fathyb's typescript plugin [1]
We should also make sure it resolves extends
fields present in configs -- the version here certainly won't.
[0] https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
[1] https://github.com/fathyb/parcel-plugin-typescript/blob/f3045b7823a01e69db9288676c7876e001182372/src/backend/config-loader.ts#L29
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @padmaia
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like Fathy's plugin resolves the initial config and passes it to the compiler options. Is there something keeping you from doing something similar right now? Also I wonder if the compiler tells us which files it extended. Probably not as most tools don't, but I wonder if it would be difficult to get that feature in. Otherwise we wouldn't be able to rebuild in watch mode if one of the extended files changed and would have to rerun loading the tsconfig for every file whose tsconfig had an extends on start up 😕 (Same as babel, @wbinnssmith you already know most of this, just commenting for posterity)
I wonder if we could avoid having a separate parcel config in order to use tsc. We could do this by separating the babel transformer for typescript into a separate parcel plugin from the babel transformer.
With this config, Because we have AST sharing, there shouldn't be a performance penalty for separating As an alternative to separating it out, perhaps |
@@ -18,7 +18,7 @@ import builtins from './builtins'; | |||
export default new Resolver({ | |||
async resolve({dependency, options}) { | |||
const resolved = await new NodeResolver({ | |||
extensions: ['js', 'json', 'css'], | |||
extensions: ['js', 'ts', 'tsx', 'json', 'css'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yeah... we'll need to derive this list from the config somehow...
I'm not sure if we should run tsc by detecting a |
This has been my experience too, and why I think unfortunately @devongovett's direction above might not work out. |
5d83b02
to
b84af3f
Compare
if (config) { | ||
transpilerOptions.compilerOptions = { | ||
...transpilerOptions.compilerOptions, | ||
...config.compilerOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compilerOptions.module
should not be overwritable by the user config if scope hoisting is enabled (has caused issues in the past)
f2390ff
to
52a2b61
Compare
What's needed here that's preventing this from landing? |
d498a56
to
510277d
Compare
How do you determine whether to use babel or tsc? |
My proposal is that we don't, because as @DeMoorJasper mentioned, we can't. We default to babel, and the user opts into tsc by using a different parcel configuration. |
Ah, I missed that in the changes somehow 👍 |
I just want to lend my support for the direction here. I think the flexibility is fantastic. It is super useful to be able to choose to run your TypeScript through either:
Keep it up. The ability for Parcel to show TS type errors would be pretty useful, as well. |
I get:
with the |
Weird, I don't get that at all. Can you send by a tarball of the transformed example you used? |
510277d
to
3203d69
Compare
Ah, got it. We don't run through scopehoisting outside builds, so I assume you ran a build too. Checking it out now. |
Yes diff --git a/packages/examples/simple/package.json b/packages/examples/simple/package.json
index 77ccef86..6c15a4ea 100644
--- a/packages/examples/simple/package.json
+++ b/packages/examples/simple/package.json
@@ -4,7 +4,7 @@
"license": "MIT",
"private": true,
"scripts": {
- "demo": "PARCEL_WORKERS=0 parcel2 src/index.js",
+ "demo": "PARCEL_WORKERS=0 parcel2 build src/index.ts",
"clean-demo": "rm -rf .parcel-cache dist && yarn demo"
},
"devDependencies": {
diff --git a/packages/examples/simple/src/foo.js b/packages/examples/simple/src/foo.ts
similarity index 100%
rename from packages/examples/simple/src/foo.js
rename to packages/examples/simple/src/foo.ts
diff --git a/packages/examples/simple/src/index.js b/packages/examples/simple/src/index.ts
similarity index 100%
rename from packages/examples/simple/src/index.js
rename to packages/examples/simple/src/index.ts |
packages/configs/tsc/index.json
Outdated
@@ -0,0 +1,9 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we need a whole config for this. It's overriding one transformer, and a user would need their own .parcelrc
to enable it anyway, so it wouldn't be hard for them to do it themselves.
packages/configs/tsc/index.json
Outdated
"transforms": { | ||
"*.{ts,tsx}": [ | ||
"@parcel/transformer-typescript-tsc", | ||
"@parcel/transformer-js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be needed as part of the .ts
config (and in fact will never run). The tsc transformer will output an asset of type js
, which will cause it to jump to another pipeline and never run the rest of the ts pipeline.
@@ -1,7 +1,7 @@ | |||
{ | |||
"bundler": "@parcel/bundler-default", | |||
"transforms": { | |||
"*.{js,mjs,jsm,jsx,es6}": [ | |||
"*.{js,mjs,jsm,jsx,es6,ts,tsx}": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think typescript should be a separate transformer plugin, even if it uses babel internally. We'll be able to share ASTs anyway, so shouldn't be a perf hit.
hasPlugin(babelrc.config.plugins, [ | ||
'@babel/transform-typescript', | ||
'@babel/plugin-transform-typescript' | ||
])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really think we should be doing this kind of searching for babel plugins and manipulation of user config anymore. It's not safe, and not possible to do fully correctly especially if we are supporting babel.config.js
, but also if someone used e.g. a forked version of the typescript preset or something. I think we should just pull this into a separate parcel transformer to just run babel-preset-typescript. If it happens to run again as part of the babel transformer later on, it shouldn't break anything (ts is already gone).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was also thinking of splitting the babel-preset-env and flow steps into their own parcel plugins too, and having the babel transformer only run if there is an explicit .babelrc
config... not sure yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really think we should be doing this kind of searching for babel plugins and manipulation of user config anymore
I agree with this, Jest does it and I've had to debug that behavior in Jest several times and it's been a complete nightmare that takes several days to work out every time.
let typescript = | ||
config == null | ||
? // $FlowFixMe | ||
require('typescript') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmmm... should we always require typescript be installed locally?
5428f04
to
8ab6497
Compare
8ab6497
to
f95db5c
Compare
This is good for another review in order to unblock @DeMoorJasper's work on diagnostics. As discussed with @padmaia and @devongovett , we're going to leave the inferring of and mutating babel config in place for now. We'll split up the babel transform and not modify the user's babel configuration going forward. |
830fe64
to
966361f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Merging this for now to unblock Jasper. It will become part of the babel preset we offer by default as discussed.
Closes #2627
Using @DeMoorJasper's work in #2627 as a base, this implements the ability for Parcel 2 to transform Typescript. It implements it by default using Babel rather than using tsc, but also implements a TSC transformer which uses TSC instead.
For tsc, a
config-tsc
is supplied with Parcel which runs typescript code through tsc but not through babel.Open questions:
Currently this isn't possible.Actually, it probably is! Though the babel transform would run with the flow-strip-types plugin enabled, but that shouldn't interfere once TS is compiled to JS.tsconfig
. Since it's possible to usetsc
without one, what should we do if the user has a local copy of typescript?tsc
'stranspileModule
is very loose and does not throw when it encounters unknown syntax.Typescript-powered resolving will follow in another PR.
Test Plan: The same integration tests test both Babel and
tsc
transformers.yarn test