-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Synthesize namespace records for proper esm interop #19675
Conversation
Can we opt-out of this change in emit via a compiler flag? |
@cspotcode: Opting out of the emit change should be as simple as using |
@DanielRosenwasser As you suggested, I've added the same changes to the AMD emit (babel does also do this for their AMD emit, so it certainly makes us more consistent). |
After a bit of discussion, we've decided that even with the quickfix available, we'd like this to be behind a flag for a release, then made into the default but still opt-out, then finally made the only option in a 3rd release (also known as a proper deprecation cycle). As such, I've gone ahead and updated the checker behavior -
Right now everything in this PR is still on by default, however I should have it behind a flag in short order - without that it's still likely ready for initial review and iteration. |
…ood error recovery with a quickfix
e5747dd
to
e84b051
Compare
Thanks for working on this. Excited for babel & typescript to behave in similar fashion when importing non es6 modules. |
src/compiler/commandLineParser.ts
Outdated
@@ -391,6 +391,12 @@ namespace ts { | |||
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking | |||
}, | |||
{ | |||
name: "strictESM", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a strict option per se.. this is an interop flag.. i would not use strict
prefix since we have already given it a different meaning with --strict
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚲 🏠 🕐 Alright, --standardESM
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spoke with daniel, gunna try --ESMInterop
@mhegazy Changed the option to the name we discussed at today's design meeting, and set it to output as |
Hi, I created a demo repository for ESM using your When using weswigham@7ff11bb I get the correct output for cjs: "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
}
exports.__esModule = true;
var hybrid_1 = require("hybrid");
var path_1 = __importDefault(require("path"));
function run() {
console.log("ESM is getting real");
console.log(path_1["default"].posix.join("i", "can", "use", "cjs", "modules"));
console.log("And hybrid modules:");
console.log(hybrid_1.sayHello());
}
run(); But when I use weswigham@bcafdba with
It seems that the rename caused the option to no longer be applied. |
@mhegazy Done! |
Having read the description, it's not fully clear to me whether this is a breaking change or not. If it is, it probably has a very large impact. Could someone clarify? |
This does not affect TS without the But we would like to make this behavior the default in the future (to align our default emit with babel), so you should check if this flag breaks you. If it does, you have a future problem that needs fixing - likely invalid usage of the |
how to work with when globby is a export = function like module
TypeError: globby is not a function |
Use a default import for export= modules that aren't namespace like: |
no option disable importStar only? |
I don't think so, no. But a default import aught to work for you in this case; since it's not a module it's top level exported object becomes it's default. You shouldn't need to wrap the library or anything; simply using the other import syntax should suffice. |
thx, feel sad, looks like esModuleInterop is not good for me i hope can import * is old way ( make sure everything is expected ) lookes like i should keep use old option lol |
@bluelovers as far as I can tell, you shouldn't see bad runtime behavior without getting a build time error anyway, and import star is less correct: import default is not really correct either, but import star is not used to get a commonjs export object outside of the typescript world. @weswigham TS has a logically correct |
anthor question why we need |
In both node's current esm environment and in the browser's esm environment, there's no concept for an
If you didn't need it, than you wouldn't have to use the |
@weswigham Pretty sure node esm can require() commonjs modules? It's just a function, after all. They call out the other way around, not being able to require a mjs file, which makes some sense. And you do have a definition for your environment: if The use would mostly be clarity about behavior, but with this it also allows skipping the interop cost. |
It can't. |
Not that node's esm mode is stable in the least, so that's still got the potential to change. |
oh I thought there has something we need use ?
|
That same default import needs to be available on the namespace and named imports, too. |
Fixes #16093
This PR updates our commonJS and AMD (thus by extension UMD) module emit to synthesize namespace records based on the presence of an
__esModule
indicator, or lack thereof, bringing our emit in line with babel's. (Modules which are not babel-compiled will finally be uncallable and unconstructable unless you use the synthetic-default-import version of the module.)This changes:
Will break. The correct way to write this code (with
allowSyntheticDefaultImports
to handle the type changes) is:This also:
--esModuleInterop
, which will default tofalse
for a release before to becomestrue
making it the default behavior - it will be set totrue
for config files generated withtsc --init
allowSyntheticDefaultExports
totrue
by default for commonjs and AMD modulesallowSyntheticDefaultExports
for javascript files and automatically infer if the module will bedefault
or not based on the presence or lack thereof of an__esModule
indicator.allowSyntheticDefaultExports
for TS files to never create a synthetic default, unless the file usesexport =
.Module '"name"' resolves to a non-module entity and cannot be imported using this construct.
by removing call and construct signatures from namespace imports and closing thenamespace
-merging hack gap (this should break everyone broken by the emit update in a very loud way).tslib
once their implementation is reviewed