Skip to content

Instantly share code, notes, and snippets.

@javascripter
Created November 26, 2024 12:10
Show Gist options
  • Save javascripter/17f0fe9cc54cca0087c273aecc4412a6 to your computer and use it in GitHub Desktop.
Save javascripter/17f0fe9cc54cca0087c273aecc4412a6 to your computer and use it in GitHub Desktop.
Next.js + Turbopack + PostCSS example
// next.config.mjs
import type { NextConfig } from 'next'
function getBabelLoader() {
return {
loader: 'babel-loader',
options: {
presets: [
[
'next/dist/compiled/babel/preset-typescript',
{
allowNamespaces: true,
},
],
[
'react-strict-dom/babel-preset',
{
debug: true,
dev: process.env.NODE_ENV === 'development',
rootDir: process.cwd(),
},
],
],
},
}
}
const nextConfig: NextConfig = {
transpilePackages: ['react-strict-dom'],
webpack: (config) => {
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
use: [getBabelLoader()],
})
return config
},
experimental: {
turbo: {
rules: {
'*.{js,jsx,ts,tsx}': {
loaders: [getBabelLoader()],
},
},
},
},
}
export default nextConfig
export default {
plugins: {
'postcss-react-strict-dom': {
include: ['src/**/*.{js,jsx,ts,tsx}'],
babelConfig: {
babelrc: false,
presets: [
[
'next/dist/compiled/babel/preset-typescript',
{
allowNamespaces: true,
},
],
[
'react-strict-dom/babel-preset',
{
debug: true,
dev: process.env.NODE_ENV === 'development',
rootDir: process.cwd(),
},
],
],
},
},
autoprefixer: {},
},
}
@MoOx
Copy link

MoOx commented Apr 12, 2025

@javascripter I am trying to setup a new project with nextjs +react-strict-dom and found your gist. I am curious to understand why you need to pass babelconfig to postcss plugin.
Also, why do you need to use "next compiled babel preset ts" ? Thanks !

@javascripter
Copy link
Author

javascripter commented Apr 12, 2025

@MoOx

I am curious to understand why you need to pass babelconfig to postcss plugin.

StyleX Babel Plugin essentially does two things:

  • It transforms your source code and replaces your style declarations to a set of minified class names
  • It collects styles used in your application for plugins. Plugins will generate CSS using information collected by StyleX Babel Plugin.

PostCSS Plugin runs StyleX Babel Plugin and uses the extracted style information to generate CSS and replaces your placeholder @stylex directive. However, PostCSS is a CSS transformer and cannot affect your source code transformation.
Therefore, you must run StyleX Babel Plugin again in babel.config.js to transform your source code.

PostCSS and babel run by application run independently from each other, which is why you need to provide babel config for both.
More details in this comment:
facebook/stylex#842 (comment)

Also, why do you need to use "next compiled babel preset ts" ? Thanks !

Unlike babel-loader in webpack, which runs other nextjs preset transformations automatically, when using turbo.rules, files that match the rule do not run anything else other than the loader config you specify. Therefore, you need to run the Next.js default preset as well manually, which does framework transformations like converting RSC, Server Actions, use cache handling etc.

You can learn more about it from this article:
https://holocron.so/blog/migrate-next.js-plugins-to-turbopack-with-this-weird-little-trick

@MoOx
Copy link

MoOx commented Apr 16, 2025

Thank you so much for all the explanations ! Some of this should be in RSD doc for sure !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment