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
JSX runtime appends .js to importSource leading to broken import paths #12210
Comments
Hey @marvinhagemeister! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly. If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite." |
Idea: what if instead of doing all that magic that the plugin is doing now we could let users specify the full import specifier: That way everybody could set it to whatever they need. This would avoid the weird scenarios we are in right now and would drop a bit of code from babel's repo. Would be easier to maintain too. I think in general having babel do module resolution is a slippery slope. There are too many configurations, tools and environments to take care of and with custom user resolvers on top. What do you think? |
This is a tough one...
Since there are multiple entry points, it would look more like this: "importSource": {
"jsx-runtime": "preact/jsx-runtime", // for jsx
"jsx-dev-runtime": "preact/jsx-dev-runtime", // for jsxDEV
"/": "preact", // for createElement
} However, I don't know how it would look like when set using the inline comment pragma. Hidden because I don't think that it can work with the "root" import for `createElement`WDYT about something like `"importSource": "preact/[module]"`, and we do `importSource.replace("[module]", "jsx-runtime")` (or `"jsx-dev-runtime"`) in the plugin?If (cc @lunaruan / @gaearon / @sebmarkbage ) |
This comment has been minimized.
This comment has been minimized.
The ideal solution would be that we revert the commit that introduced the regression, and React adds If someone really needs to further customize the import path (for example, because using a CDN that doesn't resolve the |
Oh, React + webpack 5 is not a concern because:
|
Oh and for the original issue (facebook/react#19905), it seems that some CDNs correctly support extension-less imports if they are declared as |
@nicolas-marien Thanks for the quick response! Using the export field avoids some of the complexities around resolution. All modern CDNs that I know of support it and will resolve it to an extension. Strange about webpack 5 + type "module", I would've expected it to work regardless. cc @sokra |
I am good to revert d6b0822 but we should coordinate with the React team. As for react team, I suggest specifying "exports" and those two runtime: {
"exports": {
"./jsx-runtime": "./jsx-runtime.js",
"./jsx-dev-runtime": "./jsx-dev-runtime.js",
"./": "./"
}
} So both |
Fixed in |
It is fine to revert, but I don't think it solves the problem. We can't just ask any package maintainer out there to update their package.json, and some legacy version of these packages could never be updated. Anyway, I agree with @marvinhagemeister
I think it is important to take the right path on this issue, because the TypeScript team is matching the Babel behaviour and wrong assumptions for the sake of "auto-magic-features" damage the entire ecosystem. For reference, same issue on the TypeScript project: |
@daniele-orlando could u describe in more detail what problem do u see here? The inserted import statements allow the standard node’s resolution algorithm to resolve final paths through different means - trying the |
This is being also discussed in the React repository: facebook/react#20235. I would be fine with both the conclusion (extension or not), but:
|
@Andarist As said
And Webpack (v5) follows strict rules on resolving imports, which means that a missing '.js' breaks Webpack. Of course we could use hacks like remapping inside Webpack.config.js Please check these for more details. |
Note that React already added
Indeed. But |
Ok, thank you for the explanation - the gist of it is that exports map are required for ESM in node to support extensionless imports and webpack matches their behavior (only for As mentioned here and in other issues - adding extensions in the emitted code is being problematic for a couple of reasons and I believe that it should be avoided. I understand that it's unfortunate that things break right now because of it - but node's semantics are very new. The ESM support in node has been released just this month - so it's understandable that some packages are not yet ready in full for it.
I partially agree with that. It was already a great gesture from the React team to ship runtimes for all~ React versions. I suppose they could add exports map in a similar fashion to all of them, just to avoid confusion etc. It makes sense given how many users they have. As to other packages - As to the current webpack's situation - just don't use |
We weren’t sure if we could include the exports field safely in 17 because it’s so complicated to predict all possible outcomes. But it seems plausible that we could just publish a minor with it. |
Yeah, super hard to predict everything but if u stick to CJS only then things get easier significantly - most issues come from trying to support both ESM and CJS in a single package. Your setup looks safe-ish but Ive already seen so many things breaking in relation to node’s ESM support (i consider exports field to be a part of that) that i wouldnt bet any money on that 😅 It still seems worth trying though |
@sebmarkbage We got some experience by adding If you'll want a review, feel free to ping me. |
Same thing here - feel ping me any time regarding this craziness |
Bug Report
Current behavior
For some reason an extension is appended to the end of the import source string. This is very unexpected as it breaks module resolution in node. It doesn't play well with the recently established
export
map feature. One of our Preact users traced the error back to this commit: d6b0822Here is a full repro case: https://github.com/marvinhagemeister/babel-jsx-runtime-bug
Input Code
Expected behavior
I expected babel to not add a
.js
extension to the import path. It breaks node's export map feature. With export map's thepackage.json
of the consuming package will look something like this:This worked fine with recent versions of babel before the mentioned commit was added.
Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)
babel.config.js
Output:
Environment
Possible Solution
Revert this commit:
d6b0822
Additional context
preactjs/preact#2801
The text was updated successfully, but these errors were encountered: