-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
Apply same ESM/CJS interop in .mts
/.ts
files as in .mjs
/.js
files
#17288
Comments
Sorry, we can't, it was dicussed a lot of time and you can found a lot of issues about it (in 2020, 2021, 2022), people still have mix of esm and commonjs code, it will be big breaking change for webpack v5 |
This is not possible, because the TypeScript-specific file extensions I’m referring to were first created one year ago, in 2022.
Can you say more about this? It sounds like what I’m proposing, but I couldn’t find anything about it in the docs. https://webpack.js.org/guides/ecma-script-modules/#flagging-modules-as-esm doesn’t give much info on how a loader would interact with this. |
I mean other developers ask this question (not you 😄 )
const path = require("path");
module.exports = {
mode: "production",
devtool: "source-map",
entry: {
main: "./src/entry.mjs",
},
module: {
rules: [
{
test: /main1\.js$/,
type: "javascript/esm",
}
],
},
}; output:
|
Yeah, that doesn’t look like something we can expect every user to set up in their own ts-loader config. Also, it doesn’t seem like it allows the |
@andrewbranch esbuild and webpack do the same:
output:
webpack
output:
I think without additional options on typescript level it is impossible to solve, look at other bundlers, they have the same problem and provide option(s) to change logic (some of them are broken by default 😄 ), so developers can setup any configuration and you will not work out of the box.
Webpack knows nothing about ts-loader (other loaders). So you can ask about it Technically you are right and I agree that |
This is very much not what I’m proposing. What we need is for
I am the person trying to make additional options in TypeScript; that’s why I opened this issue 😄 Additional options are impossible for us to make for bundlers that can’t treat TS extensions the same as JS extensions.
Please see https://andrewbranch.github.io/interop-test/#synthesizing-default-exports-for-cjs-modules again—esbuild differs between |
Hm, can you provide an example with webpack configuration and code? I may be confused because it should work identically, if not, I want to say it is a bug on ts-loader side, but I want to investigate |
And what output do you expect, just to clarify |
https://github.com/andrewbranch/example-webpack-ts-extensions I would be thrilled if it were a ts-loader bug, but I didn’t think loaders had a way of controlling this. |
Thank you, I will look soon, webpack doesn't know when source code is stricky ESM, so I am afraid we can't do this without loader API, But I will provide more feedback later |
@andrewbranch I looked at code and yeah,
I think the last solution is better because only ts-loader and typescript know when the source code is ESM (I think typescript can have API to get it, at the least there is Also I can implement public API to change And yes - updating ts-loader docs for ESM will be great too. Also my concern is that if we add |
I agree that a loader would be a good place to set the module kind. It’s great that there’s a (private API?) way to do it already!
Only under unsupported combinations of tsconfig options. I’m looking into making those combinations illegal.
I think this would be great. Please keep me posted on these discussions. Thanks for looking into this! |
Yeah, it will be good
Theoretically, we can fix it right now 😄 Also if we will use |
Yeah. I’ll plan to open a PR on ts-loader (maybe some others?), but a public API would be good, just so I can be sure the functionality will be available in future Webpack versions. |
@andrewbranch I agree, maybe we should just add test cases to avoid regression in future, I will do it when we shipped it to |
This issue had no activity for at least three months. It's subject to automatic issue closing if there is no activity in the next 15 days. |
TypeStrong/ts-loader#1614 seems to be stalled in the ts-loader side, so I'm going to be "that guy" to keep the thread alive for a little longer until the official public API for this makes its way into webpack 😄 |
The root of the stalling is actually my part on TypeScript itself 😅 |
Issue was closed because of inactivity. If you think this is still a valid issue, please file a new issue with additional information. |
Still valid for ts-loader |
Yes, a small update: I’m finally unblocked to work on the TS side of this issue and hope it will land in 5.5. Thanks for the patience! |
@andrewbranch Friendly ping, any news? Do you need a help? |
This is a prerequisite: microsoft/TypeScript#57896 If this lands within a week or two, I probably have time to do the second part in TS in time to ship in 5.5. |
Feature request
Webpack changes the behavior of imports of CJS files with
__esModule
to be more compatible with Node when the importing file extension is.mjs
, or.js
in scope of a package.json with"type": "module"
:For TypeScript to offer checking behavior that reflects this, the behavior of
.ts
files needs to match the behavior of.js
files, and the behavior of.mts
files needs to match the behavior of.mjs
files. However, Webpack doesn’t know what these extensions are, so they don’t get considered for Webpack’s Node-like ESM/CJS interop layer. If I addmain3.mts
with identical content, I get:The fact that a default import behavior is different in a
.mjs
and.mts
file makes it impossible for TypeScript to implement a module checking mode for Webpack.What is the expected behavior?
.ts
and.js
,.mts
and.mjs
, or.cts
and.cjs
..js
/.mjs
files based on their extension or package.json"type"
are also applied to their TypeScript counterparts. For example, whenever it’s an error torequire
an ESM file or to useimport
/export
syntax in a file in Webpack, that error should persist when renaming the file to its equivalent TypeScript file extension. (This is less important to us than (1).)What is motivation or use case for adding/changing the behavior?
I’m trying to implement better support for bundlers in TypeScript, and this behavior of differentiating module interop based on file extension, but not including TS file extensions in that differentiation, is a blocker. (I can explain why if necessary, but I don’t think it’s super relevant here.) We’re tracking at microsoft/TypeScript#54102
How should this be implemented in your opinion?
I’m not a Webpack expert, but it seems like there could be advantages to letting the loader API set the module format:
The goal for us would be that TypeScript/Webpack users get consistent behavior between .ts/.js files by default in the near future.
Are you willing to work on this yourself?
Happy to discuss solutions, and can potentially put up a PR with guidance if necessary
Additional info
I forked Tobias’s interop-test repo while researching this issue, and have changed quite a bit to show how various bundlers handle TS extensions and what they do with this issue in particular. Notably, esbuild exhibits the behavior we’re advocating for. Take a look at https://andrewbranch.github.io/interop-test/#synthesizing-default-exports-for-cjs-modules if interested.
The text was updated successfully, but these errors were encountered: