- ⚠️ THIS PROJECT IS NO LONGER MAINTAINED ⚠️ -
TL;DR: You are encouraged to use the styled-jsx/webpack
loader built styled-jsx v3+ (also with Next.js v7+) in instead of styled-jsx/css loader.
styled-jsx/css loader was a loader for webpack that let you import CSS files as a styled-jsx css
-tagged template literal.
This was pretty useful back when styled-jsx v2 was in fashion.
In August 2018, styled-jsx v3 was released, coming with its own styled-jsx/webpack
loader. This is essentially a full built-in replacement for styled-jsx/css loader. One month later, it was also included in Next.js v7, further reducing the need of an external styled-jsx/css loader.
Since version 2.0.1, styled-jsx allows styles to be defined in separate JavaScript modules, by tagging with css
any template literal that contain CSS.
This loader allows to go one step further and define styles in separate CSS files, which will be loaded as modules exporting the style sheet as a css
-tagged template literal.
In practice, you are now able to write:
import styles from './styles.css';
<style jsx>{styles}</style>
It is assumed that your application already depends on styled-jsx, either directly or through Next.js 4.
The loader is typically added as a dependency (or development dependency) to your application using npm or Yarn.
npm install --save-dev styled-jsx-css-loader
The loaded module is intended to be Babel-transformed by styled-jsx.
In order to properly configure this, you will need to define webpack rules for the type of files you want to load (typically, the CSS files of your project and/or external modules).
These rules must:
- first, use styled-jsx-css-loader
- then, pass its output to babel-loader, ensuring that it is configured to:
- transform ES2015 modules (typically using transform-es2015-modules-commonjs or another Modules plugin)
- use the styled-jsx/babel plugin
- not let any other Babel configuration interfere (typically setting the
babelrc
option tofalse
) — this is especially important if you import styles from third-party modules
The simplest way to implement this configuration is to stuff it in a single rule of your webpack configuration file:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'babel-loader',
options: {
babelrc: false,
plugins: [
require.resolve('babel-plugin-transform-es2015-modules-commonjs'),
require.resolve('styled-jsx/babel'),
]
}
},
'styled-jsx-css-loader'
]
}
]
}
};
With this setup, your project must depend on:
If you are using Next.js, there are a few more requirements and caveats.
You must configure webpack to emit loaded files as JavaScript modules in the .next/dist
build directory, by using Next.js’ built-in emit-file-loader.
It is easier to use Babel presets exclusively (rather than a mix of presets and plugins) in your project’s configuration. Therefore it is recommended to leverage the next/babel preset that is shipped with Next.js:
- to transform ES2015 modules, using the modules setting of the babel-preset-env plugin, which is part of the next/babel preset
- to use styled-jsx using the styled-jsx/babel plugin, which is also part of the next/babel preset
Putting it all together, use the following preset in your project’s .babelrc
:
{
"presets": [
[
"next/babel",
{
"preset-env": {
"modules": "commonjs"
}
}
]
]
}
Then, customize Next.js’ webpack rules in your project’s next.config.js file, to use your project’s Babel configuration (and no other) for your CSS files:
module.exports = {
webpack: (config) => {
config.module.rules.push(
{
test: /\.css$/,
use: [
{
loader: 'emit-file-loader',
options: {
name: 'dist/[path][name].[ext].js',
},
},
{
loader: 'babel-loader',
options: {
babelrc: false,
extends: path.resolve(__dirname, './.babelrc'),
},
},
'styled-jsx-css-loader',
],
}
);
return config;
},
};
With this setup, your project must depend on:
This loader was inspired by raw-loader, and Next.js’ with-global-stylesheet example.
Many thanks to styled-jsx author Giuseppe Gurgone.
MIT