wyw-in-js icon indicating copy to clipboard operation
wyw-in-js copied to clipboard

feat(nextjs): Add package for nextjs plugin

Open brijeshb42 opened this issue 1 year ago • 7 comments
trafficstars

Motivation

Using WyW (Linaria) with Next.js, in the absence of official integration, has been a big pain so far. People have been relying on next-linaria (not maintained anymore) or next-with-linaria (has it's own issue of not being able to write global and local css in the same file). Mainly the issue is that these are not official. This change opens the way to having an official plugin that others can also contribute to and fix issues (whenever found).

Summary

  • There is an important change in the webpack-loader package that specifically handles nextjs integration. The support for virtual modules is not the best when it comes to Next.js. That's why, the current webpack-loader package does not work directly with Next. There is also an issue with custom css loader that gets removed during one of the three phases of Next.js build process. This change allows the nextjs plugin package to then hook into the usual webpack loader process.
  • 2nd change is the plugin itself which is the new @wyw-in-js/nextjs package. It handles stuff like adding the two loaders (the webpack loader and the css injector loader) to the existing webpack configuration. It also handles resolving some of the next.js modules that are part of it's compile time like next/image or next/font.
  • 3rd change adds a Next.js demo app in the examples directory that uses @linaria/core with the @wyw-in-js/nextjs plugin integration.

What this PR does not cover is support for Turbopack which has some key APIs missing as of now for us to support it.

Test plan

Since it'll be hard to test the Next.js plugin itself, I was planning on using the nextjs-demo app as the testing playground by adding various combinations of the @linaria/core or @linaria/react usage and try to build the app.

There is an issue right now in the new package that only allows apps with ESM files, ie, you can have next.config.mjs or next.config.js with "type": "module" in package.json. Commonjs doesn't work. This is something that I am debugging and will make the PR ready to review once that is done.

This code has been extracted out of Pigment CSS's Next.js implementation for the community.

To test the Next.js integration, go into the examples/nextjs-demo app and run pnpm build to build the app. The review can be done commit-wise since each commit builds on top of the previous one.

brijeshb42 avatar May 14 '24 16:05 brijeshb42

🦋 Changeset detected

Latest commit: 6e672555d264e586a8659807f42370561243f54b

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar May 14 '24 16:05 changeset-bot[bot]

Note that there is an issue when using :global(). Seems related to https://github.com/callstack/linaria/issues/1388

brijeshb42 avatar May 15 '24 07:05 brijeshb42

Is there anything I can do to help move this forward? We provide an official Linaria integration for Pages router on https://github.com/10up/headstartwp and we're now adding support to app router, I'd love to stick with Linaria as the default styling solution.

nicholasio avatar Jul 24 '24 17:07 nicholasio

Is there anything I can do to help move this forward?

I second this; I'd love to help push this along. 🙂

austinbiggs avatar Aug 08 '24 22:08 austinbiggs

Hi @brijeshb42! Is it ready? I want to merge it before https://github.com/Anber/wyw-in-js/pull/96 because #96 has some breaking changes in the transform API.

Anber avatar Aug 19 '24 08:08 Anber

I wasn't able to build the example app

> next build

  ▲ Next.js 14.2.3

   Creating an optimized production build ...
Failed to compile.

../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/next/dist/api/image.js
Module parse failed: Duplicate export 'default' (2:9)
File was processed with these loaders:
 * ../../packages/webpack-loader/lib/index.js
 * ../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js
 * ../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js
You may need an additional loader to handle the result of these loaders.
| export { default } from "../shared/lib/image-external";
> export { default, getImageProps } from "../shared/lib/image-external"; //# sourceMappingURL=image.js.map

Import trace for requested module:
../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/next/dist/api/image.js
./src/app/page.tsx

nicholasio avatar Aug 27 '24 21:08 nicholasio

Ignoring node_modules paths in the loader test works but that seems more like a bandaid than a fix. I'd be happy to dive deeper, are you guys still looking to integrate this? (asking because the last comment was in August last year)

GriffinSauce avatar Jan 28 '25 09:01 GriffinSauce