-
-
Notifications
You must be signed in to change notification settings - Fork 433
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
Enum values from d.ts files cause exception when build with transpileOnly=true #331
Comments
Any news on this one? |
We don't have a way to reproduce this issue and there's nothing we can look into at present... |
@johnnyreilly I just stumbled across this issue today, as we have just started using the I have prepared a repro repo, please have a look: https://github.com/schmuli/ts-loader-enum As I mention in the readme, I noticed that typescript will also throw an error when using |
I think this comes down to There's also a suggested solution mentioned by @piotr-oles. All we need is someone to implement it 😉 FWIW I suspect it makes more sense for this to be implemented in ts-loader rather than the fork checker. Up until now the fork-ts-checker-webpack-plugin hasn't emitted anything whereas ts-loader has. I can imagine having an option that emits |
I thought it was the Again, this is probably a result of using |
Here is an (open) issue from TypeScript: microsoft/TypeScript#16671. And another comment on |
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. |
Currently have the same issue. Commenting for this not to be closed |
Same as @dark-monst |
@schmuli repo is spot on. Experiencing all same issues here, including using the |
Quickly reading the source code I can see that I'm guessing that |
I think you can control There's also some useful content here: https://www.typescriptlang.org/docs/handbook/compiler-options.html |
Indeed you can, but that compiler flag has no effect in |
https://github.com/TypeStrong/ts-loader/search?utf8=%E2%9C%93&q=isolatedModules&type= Are you sure? Doesn't look like ts-loader is doing anything in that space... |
I'm not sure at all!!! But I've tried disabling Looking again, I can see in here that However, in my mind, it's a process of elimination. I'm not really that familiar with the compiler's api sorry 😊 |
Just got the same problem. Read the whole issue, but haven't got the idea of why it happens. What's wrong with transpiling |
any updates? |
Ran into the same issue, any solution? Would love to be able to use |
any updates on this ? @johnnyreilly |
FWIW I ran into this same issue but with a .d.ts file that didn't have any enums in it. It was a typedef for a module that had a broken typedef, that I wanted to fix as per (https://stackoverflow.com/a/41641001/103395). I first had it in Then, when I did the suggested change more literally, i.e. I made a Sharing this just in case other people find this issue with non-enum-related causes. Maybe messing around with where your .d.ts is and what it's named helps you as well. |
I've been taking a look at this thread as quite a few people still seem to be coming up against issues around this. I see several different issues mentioned here:
I investigated what is happening in ts-loader, typescript and webpack and have detailed my thoughts below. The summary is:
I assume some people may be disappointed that this is not a bug in ts-loader which can be fixed, or that isolatedModules cannot simply be switched off. transpileOnly is a great feature which greatly reduces compile time in large projects but it is mutually exclusive with exported const enums. I hope that with this understanding people will be able to adapt their code to be able to use transpileOnly and enums. The fact that the compiler allows const enums but converts them to functions may be surprising but it means large codebases with many const enums can be compiled using transpileOnly. It does mean there is a subtle difference between the code generated normally and with transpileOnly. If you must use const enums and cannot accept them being included in the output bundle I suggest turning off transpileOnly and using project references for that part of the code. Project references allow a part of the codebase to be pre-compiled. In this way, you only need to compile it once so that the time penalty of compiling without transpileOnly is less relevant. Here is what I found to reach these conclusions: When transpileOnly is set to true ts-loader uses typescript's transpileModule function to perform the transpilation. The code for transpileModule forces several compiler options to undefined or fixed values: Option values are forced if they have a transpileOptionValue field, which for isolatedModules is true: So no setting in ts-loader will override isolatedModules when transpileOnly is true. This is not something which can, or should be, fixed. Without transpileOnly the compiler needs to open up every file being imported to check the types so it can see if there is an error. In transpileOnly mode it just looks at the one file it is working on and changes it from typescript to plain js. This is why transpileOnly is so fast but it also means the compiler cannot use information from other files. When you put a const enum in an ambient declaration file this is fine when not using transpileOnly. The compiler knows about the enum because it has read the declaration file, so it can substitute the value of the enum fields in the file it is compiling. In transpileOnly mode this is not possible. We would not want to change this behaviour otherwise the compiler would need to check all files which might contain information relevant to the file it is compiling, which would essentially disable transpileOnly mode. I looked at the repo kindly provided by @schmuli: https://github.com/schmuli/ts-loader-enum. Here, the const enum is in With transpileOnly disabled, the compiler reads When transpileOnly is true, the compiler does not read When you include a statement such as
the compiler will check for the existence of The error can be fixed, as @schmuli noted, by changing the When using transpileOnly, exported const enums are always emitted as an inline function and not removed as you might expect a const enum to be. If you take a look at shouldEmitEnumDeclaration in the link below you can see that the enum code will be emitted if either preserveConstEnums or isolated modules is true: This makes sense because with isolatedModules the compiler is only looking at one file at a time. It cannot open the file the const enum is defined in to use that definition to remove the enum. So exporting a const enum will never work with isolatedModules, which is why the compiler automatically exports it as an inline function. This means the compiler generates code when you might not expect it to, leading to the issue above. The issue is also discussed at the link below: microsoft/TypeScript#16671 (comment)
To be clear, I believe you can use const enums and transpileOnly, but if you export the const enums they will be converted to normal enums and included in the output bundle. |
Thanks for a really clear and helpful write up Nick! |
when you use transpileOnly:true you can try this plugin https://www.npmjs.com/package/babel-plugin-typescript-hardcoded-enum |
I tried to speed up build process. And transpileOnly=true works amazing!
Until I use any enum value in my code.
Example:
Definition file: definitions.d.ts
TS file: example.ts
In runtime I get error: "MyModule is not defined"
Is there any way to force ts-loader NOT to ignore some specific *.d.ts files when I use transpileOnly=true? (something like transpileOnlyExcept...)
The text was updated successfully, but these errors were encountered: