Closed thekevinbrown closed 4 years ago
It looks like I can work around this by changing:
"typings": "src/index.ts",
to
"typings": "lib",
in the package.json
files.
I should probably explain that we don't intend to publish these packages, so the reason for specifying the src
directory as typings is so that we don't have to rebuild on every change to see things update across packages in VSCode as we work.
If there's a better way to achieve this I'm all ears, and I'm still interested as to why ts-loader
doesn't work in this scenario while tsc
does. I'll work around this in the meantime though.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Closing as stale. Please reopen if you'd like to work on this further.
I'd like to reopen this as there's been no movement.
Hi,
I looked at your repo and think projectReferences might be the way to achieve what you are looking for. I forked your repo and added project references. Take a look at:
https://github.com/appzuka/webpack-typescript-TS2305-reproduction.git
Now the error does not occur when building using webpack but VS code knows about changes to the referenced project without the need to rebuild it.
Hi @appzuka,
Thanks for that. I guess the question I have is why does TypeScript work in this scenario but not ts-loader
?
I'd really rather not maintain lists of all the other projects inside each project's tsconfig.json
if possible.
From what I can see in the documentation, the typings field in package.json is intended to point to a .d.ts file containing type definitions. Is there any documentation to say that this can point to a ts file?
Nevertheless, pointing to index.ts does seem to work when using tsc. It correctly gets the type definitions by looking at src/index.ts and all of its dependencies. This seems to me to be defeating the purpose of importing a pre-transpiled library with a .d.ts file for the definitions - you may be increasing your build time by doing this. If you are doing this you may as well point your main field to src/index.ts. Everything will then work as you wish at the cost of rebuilding your entire project on every build. I note that if you run
npx lerna run --scope '@reproduction/b' build
before building project a there are no errors, showing tsc is not using the pre-built package.
The error goes away if you use transpileOnly: true. If you then re-enable error checking with fork-ts-checker-webpack-plugin the error does not come back. The documentation for fork-ts-checker-webpack-plugin mentions that it uses Typescript's module resolution, not webpack's so there can be some differences. If you don't want to use project references this could be a solution for you.
You could use the decarationMap option to emit map files so that VSCode knows where the source code is from the .d.ts files. This seems to work in VSCode so that 'go to definition' takes you to the source code, not the .d.ts file. It is worth adding this option even if you use project references to get this feature. However, it does not seem to show an error in VSCode when a change is made to one of the package sources.
It is strange that it works with tsc but not with webpack and ts-loader. It seems that when package a is imported by tsc it looks in a/src/index.ts, as specified in package.json, and finds the type definitions. When the same package is imported by ts-loader it notices that the file specified in typings is not a .d.ts file and ignores it.
Although ts-loader is meant to be a drop-in replacement for tsc, the documentation does say there can be differences between ts and ts-loader if there is no tsconfig.json in the root of the project. That is not the case here but this is a complex setup with multiple tsconfig.json files.
If it is documented that typings can point to a .ts file then this may be a bug, otherwise, it may not be worth tracking down what the difference is.
In any case, project references seems to be the way to go here. The cost of listing your referenced projects is outweighed by the benefits of using a workflow which tsc, ts-loader and VSCode have all be designed to work with.
Fair enough, I had tried setting composite: true
before and couldn't get it to work.
Having fully reviewed the docs and walking step by step I got it working this time, and incremental builds are a huge win for us. Thank you for taking the time to explain, it now works with ts-loader
as well. Really appreciate it!
I'm only just spotting this now, but from the looks of it @thekevinbrown opened up an issue which the very generous @appzuka was able to solve by providing a guide to using project references! (support of which in ts-loader
is down to the wonderful @andrewbranch and @sheetalkamat )
Thanks all! 🥰🌴
I am kind of hitting the similar issue on my project, reproduction here (not minimal however): https://github.com/VulcanJS/vulcan-npm/tree/bugfix/build-ts-loader
I don't really get how project reference scales to a huge number of packages. You have to write for each packages all valid references, in addition to having them in package.json
? This seems weird to me, all the more that building the project is actually building each package. Project references looks more like it is meant for monolithic project that may have a few independant package, not a huge package base.
If you have example of existing open source project using webpack + ts-loader + lerna that could help greatly, I struggle to find one.
Edit: specifically, it does not work if I build the dependent module first. So if "foo" is using "bar", "foo" is building ok, but if I build "bar" first, then "foo" doesn't build anymore. I think when I build "foo" alone, it uses "bar/index.ts" instead of "bar/dist/index.js" which doesn't exist yet.
Edit 2: I think I am progressing, the missing export are all coming from .js
files. And when I open the dist/index.d.ts
file, it indeed indicates that it misses file definition from "myFile.js", which is not included in the dist
folder
Edit 3: it seems that disallowing .js file and convert them to .ts fixes my issue. I still have problems with window
in an isomorphic context but that's unrelated.
Expected Behaviour
I'm building my project using Webpack and ts-loader. My expectation was that if
tsc
was able to compile a set of files, thents-loader
should be able to as well.Actual Behaviour
Building with tsc works.
But building with webpack doesn't.
I'm not sure why, as when I go to
packages/a/lib
there's anindex.d.ts
file which exports *, etc etc until you get toTest
, whichtsc
recognises, butts-loader
doesn't seem to.Steps to Reproduce the Problem
I've created a reproduction repo here: https://github.com/thekevinbrown/webpack-typescript-TS2305-reproduction
Steps
yarn
yarn build:tsc
=> Successyarn build:webpack
=> ErrorLocation of a Minimal Repository that Demonstrates the Issue.
https://github.com/thekevinbrown/webpack-typescript-TS2305-reproduction
Thanks for your help!