つい2週間前12/1にMeta社よりStyleXという新しいCSS-in-JSライブラリが公開されました。
StyleX is a JavaScript library for defining styles for optimized user interfaces.
StyleXの特徴としてはここの公式ドキュメントに記載されています。要するに早くて最適化されていてtype safeと書かれています。
まだ新しいライブラリのため、公式ドキュメントがうまく動作しなかったため記事にしました。しかし、今後仕様は変わる可能性があります。
使ってみた
本番環境で使用する
今回はNext.jsに組み込んでみます。基本的には公式ドキュメント通りに実行します。
ちなみに公式のサンプルもあります。
早速既存のプロジェクトに導入だ!と言いたところですが、動きません。動かすためにいくつか手伝ってあげましょう。
インストール
この5つを入れてください。
yarn add @stylexjs/stylex
yarn add -D @stylexjs/nextjs-plugin
yarn add -D @stylexjs/babel-plugin
yarn add -D @stylexjs/eslint-plugin # eslintを使っている場合
yarn add -D @stylexjs/dev-runtime # 開発環境でも使用したい場合
TypeScriptのバージョンを上げる
どこから動くかは調べていませんが、5以上なら動きます。
next.config.jsの修正
公式ドキュメントと違いますが、公式サンプルと似たコードになっています。
/** @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;
const stylexConfig = stylexPlugin({
rootDir,
useCSSLayers: true,
})({});
module.exports = {
...stylexConfig,
output: "export", // Static Site Generateする場合のみ
};
babelの設定
公式ドキュメントに書かれているbabel.config.jsは不要でした。代わりに.babelrc.jsは必要です。
これは基本的にドキュメントの通りで問題ありませんが、後述の「開発環境で使用する」を実施する場合はコメントの通り 1 行だけ変えてください。
module.exports = {
presets: ["next/babel"],
plugins: [
[
"@stylexjs/babel-plugin",
{
dev: process.env.NODE_ENV === "development",
runtimeInjection: true, // ここだけ変えた
genConditionalClasses: true,
treeshakeCompensation: true,
unstable_moduleResolution: {
type: "commonJS",
rootDir: __dirname,
},
},
],
],
};
.eslintrc.jsonの設定
公式ドキュメントの通りで大丈夫です。
module.exports = {
plugins: ["@stylexjs"],
rules: {
"@stylexjs/valid-styles": ["error", {...options}],
},
};
開発環境で使用する
先ほどまでのコードは環境変数にNODE_ENV=production
が入った場合のみスタイルを適用するようになっています。そのため、next dev
で開発している際にもスタイリングしてあげましょう。
ちなみにこれは公式ドキュメント通りでは動かないので注意です。
import "../styles/globals.css";
import type { AppProps } from "next/app";
import inject from "@stylexjs/dev-runtime";
if (process.env.NODE_ENV !== "production") {
inject({
classNamePrefix: "x",
dev: true,
test: false,
useRemForFontSize: false,
runtimeInjection: false,
styleResolution: "application-order",
});
}
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
スタイルを適用する
こんな感じでかけます。
import { NextPage } from "next";
import stylex from "@stylexjs/stylex";
export const s = stylex.create({
redOrBlueText: {
color: {
default: 'red',
":hover": 'blue'
}
},
backYellow: {
backgroundColor: 'yellow'
}
})
const Home: NextPage = () => {
return <div {...stylex.props(s.redOrBlueText, s.backYellow)}>ABC</div>
}
🎉🎉🎉
おわり
多分数日後にはこの記事が動かなくなっていますが、その時はすみません。