CSS-in-JS派がMeta社製CSS-in-JSのStyleXを使ってみた
導入
今までCSS-in-JS派だった私が、Next.jsのApp Routerで新プロジェクトを立ち上げるにあたってTailwind CSSを導入するしか選択肢がありませんでした。なぜかというとApp Routerの肝となるReact Server ComponentsではまだまだCSS-in-JSライブラリがサポートされておらず、クライアントコンポーネントでのみサポートされている状態だったからです。 [1]
Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React, including concurrent rendering.
公式でもTailwind CSSやCSS Modulesをお勧めしていました。
If you want to style Server Components, we recommend using CSS Modules or other solutions that output CSS files, like PostCSS or Tailwind CSS.
しかし、2023/12/06にMeta社製のCSS-in-JS、Stylexが発表されました🙌
そこで自分の備忘録がてら触ってみたいと思います。
StyleXとは
Meta社製のライブラリで、全てのスタイルに型がついており型安全なCSS-in-JSです。
また、同じくMeta社製のReactで最適に動くよう調整されているとのことです。 CSS-in-Reactではないとのことで、他のフレームワークでも動くようにはなっているとのことです。[2]
StyleX is a CSS-in-JS solution, not a CSS-in-React solution. Although StyleX has been tailored to work best with React today, it is designed to be used with any JavaScript framework that allows authoring markup in JavaScript. This includes frameworks that use JSX, template strings, etc.
また、コンポーネント数が増えてもCSSサイズが変わらないとのことなので、既存の大きめなプロジェクトなどのリプレイス候補などにもなってきそうですね!!
The CSS size plateaus even as the number of components grows
コンパイル時に静的なCSSに変換されるとのことで早さの方も期待できます!
CSSが静的なCSSに変換されるのでRSCでも動くんですね〜
All styles are bundled in a static CSS file at compile-time
実際に触ってみる
Next.jsのApp Routerで実際に触ってみます。
-
create-next-app
する[3]
npx create-next-app@latest
いろいろ聞かれるけど大体そのままエンターを押す。Typescriptだけはデフォルトで入れる選択になっているはずだけど確認する。
- StyleX関連のモジュールをインストール[4]
npm install --save @stylexjs/stylex
npm install --save-dev @stylexjs/nextjs-plugin
-
.babelrc.js
とnext.config.js
にプラグイン周りの設定を書く
module.exports = {
presets: ['next/babel'],
plugins: [
[
'@stylexjs/babel-plugin',
{
dev: process.env.NODE_ENV === 'development',
runtimeInjection: false,
genConditionalClasses: true,
unstable_moduleResolution: {
type: 'commonJS',
rootDir: __dirname,
},
},
],
],
};
/** @type {import('next').NextConfig} */
const stylexPlugin = require("@stylexjs/nextjs-plugin");
const babelrc = require("./.babelrc.js");
const plugins = babelrc.plugins;
const [_name, options] = plugins.find(
(plugin) => Array.isArray(plugin) && plugin[0] === "@stylexjs/babel-plugin"
);
const rootDir = options.unstable_moduleResolution.rootDir ?? __dirname;
module.exports = stylexPlugin({
rootDir,
})({});
- app.tsxに以下のプログラムを書いてみて赤い四角を表示する
import stylex from "@stylexjs/stylex";
const s = stylex.create({
redbox: {
backgroundColor: "red",
width: 100,
height: 100,
},
});
export default function Home() {
return (
<main>
<div className={stylex(s.redbox)}></div>
</main>
);
}
感想
結構簡単に導入できました。
サーバーサイドでレンダリングされているコンポーネントでCSS-in-JSを利用することができました!!!
babel周りが競合しなければ、部分的に導入するのもできそうだし、Next.jsのApprouterでCSS-in-JSを利用する選択肢の上位に入ってくるのではないでしょうか✨
Discussion