RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

次世代ゼロランタイムCSS-in-JS「macaron」の導入方法を調べてみた

はじめに

こんにちは!hy094です。
今回はZero-Runtime CSS-in-JSである「macaron」(macaron-css)の使い方を調べてみたので、
それをまとめたいと思います。

※本記事は大部分が公式のGitHub公式ドキュメントの和訳で構成されています。
※英語がとても苦手なので翻訳アプリを駆使して書いています。誤りがあったらこっそり教えていただけると嬉しいです。

macaron(macaron-css)って結局どうなの?

Vanilla-Extractの辛い部分である

  • 動的なスタイルがやや当てにくい
  • 同じファイル内でスタイルとコンポーネントの両方を記載できない

といった問題が解決されていて、とてもよかったです。
(1点目は私の問題、2点目は好みの問題かもしれませんが・・・)

感覚的にはstyled-componentsStitchesVanilla-Extract
いいとこ取りをしたライブラリといった印象ですね。

macaron(macaron-css)って何?

一言で言うと

CSS-in-JS with zero runtime, type safety and colocation

github.com

和訳すると「ゼロランタイム・型安全・コロケーションを実現するCSS-in-JS」です。

アイコンから察するに、おそらくお菓子のマカロンで合っていると思います。
また、1.0.0のリリースが2022/12/06とかなり新しいライブラリとなっています。

正式名称がmacaron-cssなのかmacaronなのか迷いどころですが、
本記事では公式サイトのmacaron.js.orgを信じて以降はmacaronと呼称します。

公式サイトは以下を参照してください。

macaron.js.org

どんな特徴があるの?

macaronの特徴として、以下のようなものがあります。

  • ビルド時にスタイルを抽出する(ゼロランタイムである)
  • スタイルとコンポーネントのコロケーション(繋がりが強くなる)
  • TypeScriptのサポート
  • styled-componentsとvanillaの両方のAPIをサポート
  • Stitchesのようなvariants APIが利用できる
  • 追加の設定など不要でReact,Solidで使用可能
  • esbuild,viteのサポート

どうやってインストールするの?

npm/yarnからインストールできます。

Reactの場合は以下のコマンドを実行します。

# npm
npm install @macaron-css/core @macaron-css/react

# yarn
yarn add @macaron-css/core @macaron-css/react

Solidの場合は以下のコマンドを実行します。

# npm
npm install @macaron-css/core @macaron-css/solid

# yarn
yarn add @macaron-css/core @macaron-css/solid

この後は yarn x React x Vite での環境を想定して記載します。

そのほかの書き方などは公式ドキュメント)を参照してください。

バンドラの設定は?

viteのプラグインをインストールします。

yarn add @macaron-css/vite

vite.config.jsに以下のように記載します。

import { macaronVitePlugin } from '@macaron-css/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    macaronVitePlugin(),
    // other plugins
  ],
});

macaronVitePlugin()は他のプラグインの設定よりも前に記載する必要があるとのことです。

どうやって使うの?

1. styled componentを作成する

@macaron-css/reactからstyledをインポートし、styled componentを作成します。

import { styled } from '@macaron-css/react';

const Button = styled('button', {});

2. スタイルを追加する

コンポーネントに適用される基本スタイル(base styles)を追記します。

hoverやメディアクエリ、ネストされたセレクタなどを含めることが可能です。

macaronの全てのstyling APIは入力としてstyle objectを受け取り、型安全です。 その恩恵としてオートコンプリートもされます。

import { styled } from '@macaron-css/react';

const Button = styled('button', {
  // --- ↓add↓ ---
  base: {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
   padding: '10px 15px',
    ':hover': {
      backgroundColor: 'lightgray',
    },
  },
  // --- ↑add↑ ---
});

3. variantsを追加する

variantsとは、可変のスタイルを実装しやすくするための機能です。

例えば以下のようなものです。

// Buttonコンポーネントでvariantsを設定
const Button = styled("button", {
  variants: {
    color: {
      violet: { color: "blueviolet" },
      gray: { color: "gainsboro" },
    },
  },
});

// 利用側でこう使える
() => <Button color={"violet"}>hello!</Button>

macaronでもvariantsキーを利用し、variantsを追加できます。

また、追加できる数に制限ありません。

そしてもちろん、基本スタイルと同様にstyle objectを受け取ります。

これを活用することで、動的なスタイル変更が容易になります。

import { styled } from '@macaron-css/react';

const Button = styled('button', {
  base: {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
    padding: '10px 15px',
    ':hover': {
      backgroundColor: 'lightgray',
    },
  },
  // --- ↓add↓ ---
  variants: {
    color: {
      violet: {
        backgroundColor: 'blueviolet',
        color: 'white',
        ':hover': {
          backgroundColor: 'darkviolet',
        },
      },
      gray: {
        backgroundColor: 'gainsboro',
        ':hover': {
          backgroundColor: 'lightgray',
        },
      },
    },
  },
  // --- ↑add↑ ---
});

4. デフォルトのvariantsを設定する

defaultVariantsを利用して、デフォルトのvariantsを設定できます。

この例の場合、何も指定しなければcolor='violet'となります。

import { styled } from '@macaron-css/react';

const Button = styled('button', {
  base: {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
    padding: '10px 15px',
    ':hover': {
      backgroundColor: 'lightgray',
    },
  },
  variants: {
    color: {
      violet: {
        backgroundColor: 'blueviolet',
        color: 'white',
        ':hover': {
          backgroundColor: 'darkviolet',
        },
      },
      gray: {
        backgroundColor: 'gainsboro',
        ':hover': {
          backgroundColor: 'lightgray',
        },
      },
    },
  },
  // --- ↓add↓ ---
  defaultVariants: {
    color: 'violet',
  },
  // --- ↑add↑ ---
});

5. コンポーネントレンダリングする

通常のReactコンポーネントと同じように使用できます。

macaronではstyled-componentsのようにコンポーネントと同じファイル内でスタイルを宣言できるため、より繋がりが強くなります。

これをmacaronは真のコロケーション(true colocation)と表現しています。

import { styled } from '@macaron-css/react';

const Button = styled('button', {
  base: {
    backgroundColor: 'gainsboro',
    borderRadius: '9999px',
    fontSize: '13px',
    padding: '10px 15px',
    ':hover': {
      backgroundColor: 'lightgray',
    },
  },
  variants: {
    color: {
      violet: {
        backgroundColor: 'blueviolet',
        color: 'white',
        ':hover': {
          backgroundColor: 'darkviolet',
        },
      },
      gray: {
        backgroundColor: 'gainsboro',
        ':hover': {
          backgroundColor: 'lightgray',
        },
      },
    },
  },
  defaultVariants: {
    color: 'violet',
  },
});

// --- ↓add↓ ---
() => <Button color="gray">Click me!</Button>;
// --- ↑add↑ ---

6. サンプルコードを見てみる

最後に、公式のgithubに記載されているサンプルコードです。

今までの1~5に記載した内容で概ね理解できるかと思います。

import { styled } from '@macaron-css/react';

const Button = styled('button', {
  base: {
    borderRadius: 6,
  },
  variants: {
    color: {
      neutral: { background: 'whitesmoke' },
      brand: { background: 'blueviolet' },
      accent: { background: 'slateblue' },
    },
    size: {
      small: { padding: 12 },
      medium: { padding: 16 },
      large: { padding: 24 },
    },
    rounded: {
      true: { borderRadius: 999 },
    },
  },
  compoundVariants: [
    {
      variants: {
        color: 'neutral',
        size: 'large',
      },
      style: {
        background: 'ghostwhite',
      },
    },
  ],

  defaultVariants: {
    color: 'accent',
    size: 'medium',
  },
});

// Use it like a regular solidjs/react component
function App() {
  return (
    <Button color="accent" size="small" rounded>
      Click me!
    </Button>
  );
}

compoundVariantsは組み合わせのvariantsです。

このサンプルコードでは、color={'neutral'}かつsize={'large'}の場合に、
background: 'ghostwhite'が反映されます。

おわりに

新しく出てきたばかりでこれから伸びていく感をひしひしと感じるmacaron、いかがでしたでしょうか?

新しすぎることや日本語のドキュメント・記事が全くないこともあり業務で使うにはまだ早いと思いますが、
個人開発ではどんどん使っていきたいポテンシャルを感じました。

macaronは次に来るCSS-in-JSかもしれません。興味が湧いた方はぜひ使ってみてください。
そして日本語の記事を書いてくれると僕が喜びます笑

それでは、ご覧いただきありがとうございました!


エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
20210916153018
https://career-recruit.rakus.co.jp/career_engineer/

カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.com

ラクスDevelopers登録フォーム
20220701175429
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/

イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!

◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.