Skip to content
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

.ts files importing from npm module with provided .js and .ts sources do not resolve const enums #3645

Closed
erikroe opened this issue Oct 15, 2019 · 10 comments

Comments

@erikroe
Copy link

erikroe commented Oct 15, 2019

🐛 bug report

Given is the following example.ts file:

import {MyEnum} from 'my-module';

var example = MyEnum.Something;

And given is an npm module with the following files:

  • my-module.d.ts
  • my-module.d.ts.map
  • my-module.js
  • my-module.js.map
  • src/my-module.ts

my-module.ts:

export const enum MyEnum { Something = 'constantString' };

The module itself is working properly.

🎛 Configuration (.babelrc, package.json, cli command)

Everything default. tsconfig.json has preserveConstEnums: false (intentionally).

🤔 Expected Behavior

In the bundled code, the line from the example.ts should look like:

var example = "constantString";

😯 Current Behavior

Currently however, it bundles it to:

var example = MyEnum.Something;

Whereas MyEnum.Something must be resolved to the constant string behind it. Obviously, MyEnum is not existing at run time and thus gives me "undefined" errors.

💁 Possible Solution

I have tested the following:
First running tsc and then using parcel build on the outputted files. It worked correctly, as tsc does inline the constant enums correctly. tsc seems to process the provided .d.ts correct to use the constant strings given.

Without knowing on what exact way Parcel currently compiles TypeScript files, I would suggest tsc itself must run over the entire project, and then Parcel performs it's other processing.

🔦 Context

I created an own private npm module exporting .js but also the original .ts files, to provide maximum compatibility for those not using TypeScript.
However, now I see myself unable to use const enums from my own bundle in my TypeScript files.
The only solution would be to use preserveConstEnums, which however is only a work around and no desired fix. Alternatively I could use a const variable with a set of given strings. But that also is only a work around.

🌍 Your Environment

Software Version(s)
Parcel 1.12.4
TypeScript 3.6.4
Node 10.16.0
npm/Yarn 6.9.0
Operating System Windows 10 64bit
@mischnic
Copy link
Member

Related: #3624 (const enums aren't supported).

thus gives me "undefined" errors.

not sure if we can do something about that...

@erikroe
Copy link
Author

erikroe commented Oct 15, 2019

Is there potentially any downside to manually first executing tsc and then letting Parcel run over the outputted JS files? Other than possibly having HMR not usable?

@mischnic
Copy link
Member

I don't think so (but be sure that tsc emits modules with ES6 imports (not CommonJS) and also set the target to the newest value to leave the JS feature transpilation to Parcel)

@erikroe
Copy link
Author

erikroe commented Oct 15, 2019

A work-around for now:

I use tsc first and then let Parcel handle those files. Making sure TypeScript does it's thing properly.
A build script would look like this:

"build": "tsc && parcel build index.html"

And to keep Parcel's Hot Module Replacement working, the following watch-script can be used:

"watch": "tsc && npm-run-all -p watch:*",
"watch:ts": "tsc -w",
"watch:js": "parcel index.html",

It requires npm-run-all to be installed.

Initially the watching takes longer because tsc first must be executed to make sure Parcel does not run on work-in-progress files.

So far I have not seen any downsides to this approach, other than being an undesired work-around. I will keep this issue updated if I encounter anything problematic. Also, I will keep it open as the issue itself is not fixed by it, unless a Dev decides otherwise.

@rajyraman
Copy link

This is how I got it working in the end. Bit clunky but works for now.

@github-actions github-actions bot added the Stale Inactive issues label May 10, 2020
@cretz
Copy link

cretz commented May 21, 2020

Bump (to remove stale marking), unexpected differences between standard TypeScript compilation and Parcel TypeScript compilation should be considered an issue and left open until fixed (even if it's a downstream dependency that has to apply the fix).

@github-actions github-actions bot removed the Stale Inactive issues label May 21, 2020
@mischnic
Copy link
Member

Parcel 2's approach is to use isolatedModules with the tsc compiler and Babel doesn't support this at all.

This article sums up the reasons: https://ncjamieson.com/dont-export-const-enums/

standard TypeScript compilation

So isolatedModules is a non-standard tsc config?

@cretz
Copy link

cretz commented May 21, 2020

At the least, it can confuse people why tsc generates working code out of the box and parcel doesn't...maybe a blurb on https://parceljs.org/typeScript.html (or the parcel 2 equivalent) is enough saying const enums aren't supported (or that isolatedModules should be set to true in tsconfig.json or something).

@mischnic
Copy link
Member

It's already on the todo list for the new typescript docs: https://parcel2-docs.now.sh/recipes/typescript/

@rezonant
Copy link

This also breaks transformations that need to analyze multiple files in the project and ensures that Parcel cannot notify of any Typescript semantic errors (as ts.transpileModule does not output any semantic errors). Only syntactic errors can be observed in Parcel due to this design decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants