signals icon indicating copy to clipboard operation
signals copied to clipboard

signals/react: 'default' is not exported by react/jsx-runtime

Open cafreeman opened this issue 3 years ago • 11 comments
trafficstars

When trying to generate a production build in a Vite react app, we get the following error:

'default' is not exported by react/jsx-runtime, imported by node_modules/@preact/signals-react/dist/signals.module.js

It appears this error originates from these lines https://github.com/preactjs/signals/blob/main/packages/react/src/index.ts#L9-L10, where it's using default imports for the two runtimes, while the jsx-runtime package appears to only provide named exports?

cafreeman avatar Nov 08 '22 19:11 cafreeman

Running into the same issue while building a Vite TypeScript React application.

Edit: @cafreeman - I changed the version to 1.1.1 on my package.json and it has fixed the issue with the build. Although, probably need to take a deeper look to fix in future.

govindg312 avatar Nov 10 '22 11:11 govindg312

I have the same problem, it happens only with the version ^1.2.1, i'm also building a vite typescript react app. i'll go back to 1.1.1 temporarily.

gregorip02 avatar Nov 11 '22 22:11 gregorip02

Update on this, it looks like there is an issue with how @preact/signals-react incorporates with the JSX runtime. You can circumvent this by updating vite react plugin to use the classic jsxRuntime, though I'm unsure what the tradeoffs are there, e.g.:

export default defineConfig({
  plugins: [
    react({
      jsxRuntime: "classic",
    }),
  ],
});

cafreeman avatar Nov 14 '22 17:11 cafreeman

Update on this, it looks like there is an issue with how @preact/signals-react incorporates with the JSX runtime. You can circumvent this by updating vite react plugin to use the classic jsxRuntime, though I'm unsure what the tradeoffs are there, e.g.:

export default defineConfig({
  plugins: [
    react({
      jsxRuntime: "classic",
    }),
  ],
});

@cafreeman thanks for this solution. Where is this file supposed to be created and named? I am using a create-react-app project

MMolieleng avatar Nov 21 '22 04:11 MMolieleng

Update on this, it looks like there is an issue with how @preact/signals-react incorporates with the JSX runtime. You can circumvent this by updating vite react plugin to use the classic jsxRuntime, though I'm unsure what the tradeoffs are there, e.g.:

export default defineConfig({
  plugins: [
    react({
      jsxRuntime: "classic",
    }),
  ],
});

It doesn't help me to fix the issue, unfortunately.

cedeber avatar Nov 21 '22 17:11 cedeber

@eddyw maybe you can quickly chime in here? You created #219 which introduced importing the jsx runtime. Could we import import { jsx } from 'react/jsx-runtime' and call the WrapJsx on that?

If you need a solution right now there are two possibilities:

  • Set allowSyntheticDefaultImports to true in tsconfig.json which allows import jsxRuntime from 'react/jsx-runtime' to be transformed as import * as jsxRuntime from 'react/jsx-runtime'
  • Patch dist/signals.mjs and dist/signals.module.js with patch-package and rewrite all the statements with import * as u from"react/jsx-runtime

Also try rebuilding with the above using vite --force to bypass build cache.

maybe this is also related to microbundle https://github.com/developit/microbundle/pull/988? not too familiar.

queckezz avatar Jan 11 '23 09:01 queckezz

maybe this is also related to microbundle developit/microbundle#988? not too familiar.

That PR and the options it fixes are only for TS's transformation of JSX, which these packages do not contain. It's unrelated.

rschristian avatar Jan 11 '23 18:01 rschristian

Any updates?

MrCookiez avatar May 22 '23 15:05 MrCookiez

I have the same problem, it happens only with the version ^1.2.1, i'm also building a vite typescript react app. i'll go back to 1.1.1 temporarily.

That worked for me. Still getting this error on 1.3.6 (for my use case at least, @storybook/react-vite + @preact/signals-react).

josantana avatar Nov 09 '23 14:11 josantana

In case anyone else is struggling with this when they go to build Storybook v7.6 with Vite, here’s our viteFinal:

  viteFinal: async (config, { configType }) => {
    return mergeConfig(
      configType === 'PRODUCTION'
        ? {
            ...config,
            // TODO(thure): build fails for @preact/signals-react: https://github.com/preactjs/signals/issues/269
            plugins: flatten(config.plugins).map((plugin: any) => {
              return plugin.name === 'vite:react-babel'
                ? ReactPlugin({
                    jsxRuntime: 'classic',
                  })
                : plugin.name === 'vite:react-jsx'
                ? undefined
                : plugin;
            }),
          }
        : config,
      {
        // When `jsxRuntime` is set to 'classic', top-level awaits are rejected unless build.target is 'esnext'
        ...(configType === 'PRODUCTION' && { build: { target: 'esnext' } }),
        plugins: [
          ThemePlugin({
            root: __dirname,
            content: [resolve(__dirname, '../../../packages/*/*/src') + '/**/*.{ts,tsx,js,jsx}'],
          }),
          turbosnap({ rootDir: config.root ?? __dirname }),
        ],
      },
    );
  },

Looking forward to not needing all this special logic, will watch this issue. Please let me know if a PR would be welcome, maybe we can arrange some bandwidth to help out.

thure avatar Dec 08 '23 01:12 thure

Thank you SO MUCH @thure for sharing your Storybook config. I was tearing my hair out with this issue, and with the config you posted I finally made it work. I ended up with a slightly different config in the end, sharing it here as well in case it helps anyone:

import { mergeConfig } from "vite";
import type { StorybookConfig } from "@storybook/react-vite";
import _ from "lodash";
import ReactPlugin from "@vitejs/plugin-react";

const config = {
  // ...
  async viteFinal({ plugins, ...config }, { configType }) {
    // Replace the react plugin with the classic runtime, otherwise we get build errors due to @preact/signals-react
    // see: build fails for @preact/signals-react: https://github.com/preactjs/signals/issues/269
    let baseConfig = {
      ...config,
      plugins:
        configType === "PRODUCTION"
          ? _.flatten(plugins).map((plugin: any) => {
              return plugin.name === "vite:react-babel"
                ? ReactPlugin({
                    jsxRuntime: "classic",
                  })
                : plugin.name === "vite:react-jsx"
                ? undefined
                : plugin;
            })
          : plugins,
    };
    return mergeConfig(baseConfig, {
      ...(configType === "PRODUCTION"
        ? {
            esbuild: {
              jsxInject: `import * as React from 'react'`,
            },
          }
        : {}),
    });
  },

} satisfies StorybookConfig;
export default config;

jnicklas avatar Dec 13 '23 18:12 jnicklas