question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JSX runtime appends .js to importSource leading to broken import paths

See original GitHub issue

Bug Report

  • I would like to work on a fix!

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: https://github.com/babel/babel/commit/d6b0822ee9e95321a417b321a6687048faf1c3a1

Here is a full repro case: https://github.com/marvinhagemeister/babel-jsx-runtime-bug

Input Code

export const foo = <div />;

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 the package.json of the consuming package will look something like this:

{
  "name": "my-package",
  "exports": {
    "jsx-runtime": {
      "require": "./path/to/browser.jsx-runtime.js",
      "import": "./path/to/import.jsx-runtime.mjs"
    },
    "jsx-dev-runtime": {
      "require": "./path/to/browser.jsx-dev-runtime.js",
      "import": "./path/to/import.jsx-dev-runtime.mjs"
    }
  }
}

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)

  • Filename: babel.config.js
// babel.config.js
module.exports = {
  plugins: [
    [
      "@babel/plugin-transform-react-jsx",
      { runtime: "automatic", importSource: "preact" }
    ]
  ]
}

Output:

import { jsx as _jsx } from "preact/jsx-runtime";
export const foo = _jsx("div", {});

Environment

  System:
    OS: Linux 5.8 Arch Linux
  Binaries:
    Node: 14.13.0 - ~/.nvm/versions/node/v14.13.0/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 6.14.8 - ~/.nvm/versions/node/v14.13.0/bin/npm
  npmPackages:
    @babel/cli: ^7.12.1 => 7.12.1 
    @babel/core: ^7.12.3 => 7.12.3 
    @babel/plugin-transform-react-jsx: ^7.12.1 => 7.12.1 

Possible Solution

Revert this commit: https://github.com/babel/babel/commit/d6b0822ee9e95321a417b321a6687048faf1c3a1

Additional context

https://github.com/preactjs/preact/issues/2801

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:20 (16 by maintainers)

github_iconTop GitHub Comments

6reactions
marvinhagemeistercommented, Oct 18, 2020

Idea: what if instead of doing all that magic that the plugin is doing now we could let users specify the full import specifier: preact -> preact/jsx.-runtime.

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?

3reactions
nicolo-ribaudocommented, Oct 19, 2020

Fixed in @babel/helper-builder-react-jsx-experimental@7.12.4

Read more comments on GitHub >

github_iconTop Results From Across the Web

got Can't resolve 'react/jsx-runtime' error while use try to create ...
What the React version of the project you import the component? I got the same error and found 2 solutions. Use React <...
Read more >
API - ESBuild
Bundling with esbuild only works with statically-defined imports (i.e. when the import path is a string literal). Imports that are defined at run-time...
Read more >
Introducing the New JSX Transform – React Blog
With the new transform, you can use JSX without importing React. ... Under the hood, the old JSX transform turns it into regular...
Read more >
esbuild-wasm | Yarn - Package Manager
Node has a feature called subpath imports where special import paths that start with # are resolved using the imports field in the...
Read more >
bun-cli-linux-x64 - npm Package Health Analysis | Snyk
Today, bun's primary focus is bun.js: bun's JavaScript runtime. ... CommonJS-style import paths without the file extension work.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found