preactjs / next-plugin-preact

Next.js plugin for preact X
395 stars 9 forks source link

Using next-plugin-preact with emotion #16

Closed nickrttn closed 3 years ago

nickrttn commented 3 years ago

I'm trying to get Next.js working with both next-plugin-react and emotion.

In the with-emotion an example babel configuration is provided that overrides the @babel/preset-react importSource with @emotion/react which points to a patched version for the new jsx-runtime to work with Emotion.

When I try to combine that Babel configuration with the using-preact example that uses this plugin, I get the following error in the console: Module not found: Can't resolve 'react/jsx-dev-runtime'. This is imported in @emotion/react/jsx-runtime and @emotion/react/jsx-dev-runtime.

I would have expected the react aliases from next-plugin-preact to pick up on this and resolve correctly but that doesn't seem to be the case. What would be good way to make sure Emotion and Preact can be used together in Next.js?

jesster2k10 commented 3 years ago

Hey, I had this exact issue so my workaround was just using the babel-preset-css-prop preset. My .babelrc.js file looks like this:

module.exports = {
  presets: ['next/babel', '@emotion/babel-preset-css-prop'],
  plugins: ['@emotion/babel-plugin', 'babel-plugin-macros'],
};

that was the only way I could get it to work. Of course this means you won't be able to use the JSX runtimes, but it's a decent workaround for now.

You might want to look into this library: https://www.npmjs.com/package/preact-jsx-runtime I'll take a look at it also and see if it works.

nickrttn commented 3 years ago

I've been using the JSX pragma that's included with @emotion/react. It works, but I'm not entirely sure what the effect is on the JSX runtime used for those files.

sventschui commented 3 years ago

Looks like emotion is looking for a jsx-dev-runtime that's currently not included in preact. Could you try to copy node_modules/preact/compat/jsx-runtime.js to node_modules/preact/compat/jsx-dev-runtime.js and give it another go?

sventschui commented 3 years ago

This will be fixed with https://github.com/preactjs/preact/pull/2920. Until this is released, you can add the following snippet to your next.config.js:

require("fs").copyFileSync(
  "./node_modules/preact/compat/jsx-runtime.js",
  "./node_modules/preact/compat/jsx-dev-runtime.js"
);
nickrttn commented 3 years ago

@sventschui Applying that advice strangely leads to the following error when trying to build:

> Build error occurred
Error: `pages/404` can not have getInitialProps/getServerSideProps, https://err.sh/next.js/404-get-initial-props
    at /Users/nickrutten/dev/emotion-preact-404/node_modules/next/dist/build/index.js:15:5061
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Promise.all (index 0)
    at async /Users/nickrutten/dev/emotion-preact-404/node_modules/next/dist/build/index.js:15:2667
    at async /Users/nickrutten/dev/emotion-preact-404/node_modules/next/dist/build/tracer.js:1:525
error Command failed with exit code 1.

This only occurs when you have pages/404.[js/tsx]. I've made a reduced test case here where the same behavior occurs:

https://github.com/nickrttn/emotion-preact-404

sventschui commented 3 years ago

Fix will land with https://github.com/preactjs/compat-alias-package/pull/1

Until this is released you can work around this by adding another bunch of copy statements to your next.config.js:

require("fs").copyFileSync(
  "./node_modules/preact/compat/jsx-runtime.js",
  "./node_modules/react/jsx-runtime.js"
);
require("fs").copyFileSync(
  "./node_modules/preact/compat/jsx-runtime.js",
  "./node_modules/react/jsx-dev-runtime.js"
);

Sorry for these weird workarounds 🙃

sventschui commented 3 years ago

The second issue should now be fixed if you upgrade to @preact/compat@0.0.4. The first issue needs a fresh release of preact that will be published soon I guess.

nickrttn commented 3 years ago

Sorry for these weird workarounds 🙃

It's fine, to be expected when you use a slightly unusual setup. I really appreciate the help!

It works now, upgrading preact/compat to 0.0.4 (what's up with that version number? It says 4.0.0 in the package.json) and adding the initial hack to the next.config.js.

nickrttn commented 3 years ago

If I read the release notes of preact@10.5.10 correctly, I should have been able to remove the fs.fileCopySync statement after upgrading to that version, correct?

I'm asking because I'm still seeing the error after the upgrade (and removing the fs.fileCopySync). I've reported it here: https://github.com/preactjs/preact/issues/2930

sventschui commented 3 years ago

Forgot to add the runtime to published files. @marvinhagemeister did so now and next release should be fine