AstroとLessのcssClassを同期する方法
Astroで個人ブログを開発するとき、CSSのクラスやIDを変更する際にAstroファイルとLessファイルの両方を変更する必要があった。複数個所でCSSクラスを使っている場合、変更漏れがないか確認するのに時間がかかる。この記事では、確認にかかる時間を減らすために、AstroとLessファイルのCSSクラスを同期する方法を紹介する。
Astroの設定ファイルであるastro.config.mjs
と、内部で利用されているViteの機能を組み合わせることで、AstroとLessの間でCSSクラスを同期できる。
関連するファイルと初期値
body要素にcontainerというクラスを指定していると想定する。
関係するファイルは以下の通り。
astro.config.mjs
env.d.ts
Body.astro
style.less
import { defineConfig } from "astro/config";
export default defineConfig({…});
// …
---
---
<body class="container"> <slot /></body>
.container { position: relative;}
AstroとLessのCSSクラスを同期する方法
同期するには、astro.config.mjs
で、vite.define
とvite.css.preprocessorOptions.less.modifyVars
に共通の値を設定する。
import { defineConfig } from "astro/config";
// 共通する定数を定義const CONSTANTS = { CSS_CLASS_CONTAINER: "container", OTHER_CONSTANTS: "/icon.svg",};
function mapForDefine() { return Object.entries(CONSTANTS).reduce((pre, [key, value]) => { // vite.defineでは文字列の場合JSON.stringify()する必要がある pre[key] = JSON.stringify(value); return pre; }, {});}
export default defineConfig({ vite: { define: { ...mapForDefine(), }, css: { preprocessorOptions: { less: { modifyVars: { ...CONSTANTS, }, }, }, }, },});
vite.define
で定義した定数はビルド時に指定した値で置き換えてくれる。詳しくは、Astroで定数管理をするならvite.defineを設定するの記事を参照してほしい。
modifyVars
で定義した変数はimport
などは不要で、Lessファイル内で通常のLess変数として利用できる。modifyVars
オブジェクトのキーが変数名になる。
declare const CSS_CLASS_CONTAINER: string;declare const OTHER_CONSTANTS: string;
env.d.tsに型を定義して型エラーをなくし、インテリセンスに表示させる
---
---
<body class="container"><body class={CSS_CLASS_CONTAINER}> <slot /></body>
.container {.@{CSS_CLASS_CONTAINER} { position: relative;}
以上でastro.config.mjs
のCONSTANTSオブジェクトに定数を一元管理できるようになった。
定数をCSSの文字列として扱いたい場合
Less内で[class$="container"]
のように文字列として扱いたい場合は、[class$="@{CSS_CLASS_CONTAINER}"]
のように書く。
同様に、content: url("/icon.svg");
は、content: url("@{OTHER_CONSTANTS}");
と書く。
まとめ
文字列やCSSクラスを一元管理できるとコードの保守・変更がしやすくなる。Viteの設定とLessの機能を組み合わせることで、HTMLとCSSのclassを同期できた。
色の変数も定義できるが、個人的にLessのColor Operation Functionsを用いてプログラマーっぽく定義したい。なので色変数はcolor.less
という変数用ファイルに定義している。