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

Proposal: add --hoistImports to compiler options #22178

Closed
ericanderson opened this issue Feb 25, 2018 · 10 comments
Closed

Proposal: add --hoistImports to compiler options #22178

ericanderson opened this issue Feb 25, 2018 · 10 comments
Labels
Duplicate An existing issue was already created

Comments

@ericanderson
Copy link
Contributor

In ES6, imports are hoisted and evaluated before code within the same file. Webpack definitely already does this and I think rollup might too (or certainly it would be legal for them to do so).

Example:

import installPolyfills from "ie-polyfills";
installPolyfills();
import Foo from "other-code";

In ES6, your code will be evaluated as

import installPolyfills from "ie-polyfills";
import Foo from "other-code";
installPolyfills();

and cause an unexpected error (polyfills aren't available for Foo) since in an ES5 engine it still behaves as the example.

Unfortunately, this allows us to write code that doesn't behave the same depending on the output module type (if TS hoisted imports when module: "es6") nor when running ES6 style code through other tools (like webpack or rollup).

This flag would instruct TS to hoist imports in generated code, regardless of the output module format. Thus one can write code that can be sure to behave the same in node 6, webpack, and engines that natively support es6 modules.

Thus, with hostImports: true and module: "cjs", your output code would be:

var installPolyfills = require("ie-polyfills");
var Foo = require("other-code");
installPolyfills();

I think that ideally this flag would default to true when module: "es6" however that would likely be considered a breaking change. So perhaps that change (or always defaulting it to true, since TS looks like ES6) could happen in TS3.

Thanks
CC @mhegazy

@weswigham
Copy link
Member

module: "es6" doesn't downlevel any imports - what starts as an import statement ends as an import statement. Do you mean target?

@ericanderson
Copy link
Contributor Author

Thanks Wesley. Good catch. Updating

@weswigham
Copy link
Member

It's also probably worth noting that is is the behavior for all module formats other than cjs.

@ericanderson
Copy link
Contributor Author

ericanderson commented Feb 26, 2018

Sorry, now that I am rereading what I wrote. When using webpack with module: "es6", your imports are hoisted (in webpack) because it looks like es6 code.

@weswigham
Copy link
Member

Right, but your point is that our behavior differs from spec when module: "commonjs" is set, yeah?

@ericanderson
Copy link
Contributor Author

If TypeScript is a strict superset of es6, then the code generated when module: “cjs” is not to spec.

Whether or not that’s what TypeScript is, I would like to ensure that my fellow engineers do not accidentally introduce bugs due to side effects when testing via node vs runtime environments.

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript In Discussion Not yet reached consensus Domain: ES Modules The issue relates to import/export style module behavior labels Feb 26, 2018
@DanielRosenwasser
Copy link
Member

Wait, is this #16166?

@DanielRosenwasser DanielRosenwasser added Duplicate An existing issue was already created and removed Domain: ES Modules The issue relates to import/export style module behavior In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Feb 26, 2018
@ericanderson
Copy link
Contributor Author

Yeah I guess it’s very similar. That’s more about having an error for out of order and this is an option to force hoisted imports even in cjs

@weswigham
Copy link
Member

The resolution on the other issue was to commit to changing our cjs emit to hoist imports (not to issue some warning), which would is what we'd do here, too. As I said, it is already how it behaves for every other target.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants