Open mulfyx opened 6 months ago
Is Next.js 13 or 12 supported?
@layershifter MUI is working on the zero-runtime engine (on top of linaria). Would you be able to share what's to be done for Next.js integration? I can submit a PR once the plan is clear.
@siriwatknp first, I would check if setup the existing Webpack loader & plugin works with Next.js 13/14 and debug what breaks. So far, I was not able to do that, but Next.js must be supported, so I appreciate if somebody will at least trace the problem 🐱
Looks like the problem has repro https://github.com/callstack/linaria/issues/1387.
Needs to be debugged to get understanding what went wrong.
As we still don't have official plugin for Next.js, and I've tried different solutions mentioned in this and other threads, none of them works for me (wyw-in-js + Next.js v14), so I chose another approach and works pretty good for us: Extracting stylesheet in a different process via esbuild
, and esbuild
is already super fast
babel.config.js
, we still need the babel plugin to compile wyw-in-js to classNames
module.exports = {
presets: ['next/babel', '@wyw-in-js'],
}
create script (e.g. extract-styles.mjs
) to extract style via esbuild
import wyw from '@wyw-in-js/esbuild'
import * as esbuild from 'esbuild'
import fs from 'fs'
import wywConfig from './wyw-in-js.config.js'
const args = process.argv.slice(2)
/** @type {import('esbuild').Plugin} */
const myPlugin = {
name: 'my-plugin',
setup(build) {
build.onEnd(() => {
const cssText = fs.readFileSync('./dist/index.css', 'utf-8')
fs.writeFileSync('./styles.css', cssText, 'utf-8')
fs.rmSync('./dist', { recursive: true })
})
},
}
/** @type {import('esbuild').BuildOptions} */
const options = {
entryPoints: ['src/index.ts'],
outdir: 'dist',
bundle: true,
minify: false,
logOverride: {
'ignored-bare-import': 'silent',
},
plugins: [
wyw({
filter: wywConfig.include,
...wywConfig,
}),
myPlugin,
],
}
if (args.includes('-w') || args.includes('--watch')) {
const context = await esbuild.context(options)
await context.watch()
// eslint-disable-next-line no-console
console.log('👀 watching changes to generate styles.css')
} else {
await esbuild.build(options)
// eslint-disable-next-line no-console
console.log('✅ styles.css generated')
}
styles.css
in _app.tsx
of Next.js app"dev": "node extract-styles.mjs & next dev
Note, if you are using Linaria
in a different folder as us, you will need to do some trick to make sure babel plugin and esbuild plugin generate the same classNames, overriding classNameSlug
in wyw.config.js
const { slugify } = require('@wyw-in-js/shared')
const { toValidCSSIdentifier } = require('@wyw-in-js/processor-utils')
module.exports = {
...
// TODO: we can remove this once https://github.com/Anber/wyw-in-js/pull/63 been merged, and only override it in website
classNameSlug: (hash, title, args) => {
const slug = toValidCSSIdentifier(
`${title.charAt(0).toLowerCase()}${slugify(
args.file.replace(/(.*\/ui-kit\/)src/, 'src'),
)}`,
)
const className = `${toValidCSSIdentifier(title)}_${slug}`
return className
},
}
You can try and use @pigment-css/nextjs-plugin
with linaria
and it should work. It has some MUI specific handling as well but that should not affect the usage of linaria
.
The current version of wyw-in-js does not provide compatibility with Next.js 14.