-
Notifications
You must be signed in to change notification settings - Fork 70
fix: handle all type-only imports by piping TS imports #406
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
fix: handle all type-only imports by piping TS imports #406
Conversation
I happened to stumble upon this yesterday -- it turns out that So doing the same as |
3f1dfd8 to
dd9ce35
Compare
|
There is a conflict with previous PR, but otherwise looks good |
- `result.references` is populated by `ts.preProcessFile`; i.e. this is TS discovering all imports, instead of Rollup
- TS's imports include type-only files as TS understands those (whereas they aren't emitted in the JS for Rollup to see, since, well, they produce no JS)
- so we can pipe all these through Rollup's `this.resolve` and `this.load` to make them go through Rollup's `resolveId` -> `load` -> `transform` hooks
- this makes sure that other plugins on the chain get to resolve/transform them as well
- and it makes sure that we run the same code that we run on all other files on type-only ones too
- for instance: adding declarations, type-checking, setting them as deps in the cache graph, etc
- yay recursion!
- also add check for circular references b/c of this recursion (which Rollup docs confirm is necessary, per in-line comment)
- and Rollup ensures that there is no perf penalty if a regular file is processed this way either, as it won't save the hook results when it appears in JS (i.e. Rollup's module graph)
- we are checking more files though, so that in and of itself means potential slowdown for better correctness
- add a test for this that uses a `tsconfig` `files` array, ensuring that the `include` workaround won't cover these type-only files
- this test fails without the new code added to `index` in this commit
- also add another file, `type-only-import-import`, to the `no-errors` fixture to ensure that we're not just checking imports one level deep, and actually going through type-only imports of type-only imports as well
- the declaration check for this will fail if type-only imports are not handled recursively
- an initial version of this fix that I had that didn't call `this.load` failed this check
- refactor(test): make the integration tests more resilient to output ordering changes
- due to the eager calls to `this.load`, the ordering of declaration and declaration map outputs in the bundle changed
- and bc TS's default ordering of imports seems to differ from Rollup's
- note that this only changed the order of the "bundle output" object -- which Rollup doesn't guarantee ordering of anyway
- all files are still in the bundle output and are still written to disk
- for example, the `watch` tests did not rely on this ordering and as such did not need to change due to the ordering change
- create a `findName` helper that will search the `output` array instead, ensuring that most ordering does not matter
- we do still rely on `output[0]` being the bundled JS (ESM) file, however
- refactor(test): go through a `files` array for tests that check for multiple files instead of listing out each individual check
- this makes the tests more resilient to fixture changes as well (i.e. addition / deletion of files)
- create `no-errors.ts` that exports a list of files for this fixture
- didn't need to do the same for `errors.ts` as of yet; may do so in the future though
…arations` dict - preserve some ordering and simplify future debugging - also fix lint issue, `let modules` -> `const modules` - I previously changed it (while WIP), but now it's static/never reassigned, so can use `const`
- simpler to follow than `map` + `filter` + `Promise.all`
- might(?) be faster without `Promise.all` as well as more can happen async without waiting
- (I'm not totally sure of the low-level implementation of async to know for sure though)
dd9ce35 to
4cde289
Compare
|
Fixed the conflict 👍 |
NOTE: this is built on top of #403 as it changes its code a bit. #403 is itself built on top of #386. As such, I've marked this PR as "Draft" until those PRs are merged.Rebased on top and marked as ready for review. (surprisingly clean rebase)
Also this might be the first time this repo has more open PRs than open issues 😮
Summary
Completely handle the long-standing issue of type-only imports
resolveIdhook now, which adds them to the cache (callscache().setDependency)tsconfig#211tsconfigfiles? #409included files missed bytransform(type-only files) #345failed to transpileerror --noEmitOnError: truebreaks rpt2 #254 for their specific use-cases as they happen to useincludeglobs, but this PR fixes it in all other scenarios as well (namely when usingfilesinstead ofincludeglobs)Details
result.referencesis populated byts.preProcessFile; i.e. this is TS discovering all imports, instead of Rollupthis.resolveandthis.loadto make them go through Rollup'sresolveId->load->transformhooksadd a test for this that uses a
tsconfigfilesarray, ensuring that theincludeworkaround won't cover these type-only filesindexin this committype-only-import-import, to theno-errorsfixture to ensure that we're not just checking imports one level deep, and actually going through type-only imports of type-only imports as wellthis.loadfailed this checkrefactor(test): make the integration tests more resilient to output ordering changes
this.load, the ordering of declaration and declaration map outputs in the bundle changedwatchtests did not rely on this ordering and as such did not need to change due to the ordering changefindNamehelper that will search theoutputarray instead, ensuring that most ordering does not matteroutput[0]being the bundled JS (ESM) file, howeverrefactor(test): go through a
filesarray for tests that check for multiple files instead of listing out each individual checkno-errors.tsthat exports a list of files for this fixtureerrors.tsas of yet; may do so in the future thoughReview Notes
I double-checked that the
transformhook could be async in the minimum Rollup version we support.v1.18.0as I couldn't find a mention of async in theCHANGELOG.md.This could be considered "breaking", but the bundle ordering should realistically not affect anyone (only tests that rely on ordering, which was never guaranteed by Rollup as
this.loadcould be called by any plugin at any time) and this should only be additive, in that it increases the number of files that are type-checked / generated declarations for.Related to that, I specifically did not touch the "missed" type-checking / declaration generation that uses
parsedConfig.fileNamesto partly workaround this issue (i.e. fix: type-checkincluded files missed bytransform(type-only files) #345 and the respective declaration generation block)included files missed bytransform(type-only files) #345tsconfig#211 says rpt2 shouldn't process those, I don't necessarily agree with that statement, becausetscwill process those. Not processingparsedConfig.fileNameswould mean only processing the Rollupinput, acting as if thetsconfighadfileswith only that single file from the Rollupinputin it. That behavior could make sense to some, but not others, so I'm not sure that that's ideal.The "Note" in fix: type-check
included files missed bytransform(type-only files) #345 mentions how users may useincludeglobs orfilesarrays to list other files they want type-checking and declarations. These files may not be considered part of the Rollup "bundle" however, so I could see an argument for either direction.References
This also fixes various downstream issues:
sourcefile specified inpackage.jsondevelopit/microbundle#826and probably (hard to tell without more details from issue author):