🐕
Vite x React x CSSModules x TypeScript環境で型安全に開発する
はじめに
前回までの記事で、classnames-genericsを利用して、型安全にTypeScriptでstyleを実装する方法を紹介してきました。
続の方で締めくくっているように、styleの型定義を自前で用意するのが非常に面倒でした。今回は、自動でstyleの型定義ファイルを作成するvite-plugin-sass-dtsを紹介します。
準備
vite-plugin-sass-dts
をインストールする
npm i -D vite-plugin-sass-dts
vite.config.ts
にプラグインを設定する
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import sassDts from "vite-plugin-sass-dts";
import path from "path";
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles" as common;`,
importer(...args) {
if (args[0] !== "@/styles") {
return;
}
return {
file: `${path.resolve(
__dirname,
"./src/assets/styles"
)}`,
};
},
},
},
},
plugins: [
react(),
sassDts({
allGenerate: true,
global: {
generate: true,
outFile: path.resolve(__dirname, "./src/style.d.ts"),
},
}),
],
});
コンポーネントの実装
vite
を起動する
npm run dev
scss
ファイルを実装して、保存する
src/App.module.scss
.header-1 {
background-color: common.$primary;
.active {
background-color: black;
}
}
src/assets/styles/_index.scss
$primary: violet;
.row {
display: flex;
}
保存した scss
ファイルと同じディレクトリに型定義ファイルが自動で作成される
src/App.module.scss.d.ts
import globalClassNames from './style.d'
declare const classNames: typeof globalClassNames & {
readonly 'header-1': 'header-1';
readonly 'active': 'active';
};
export = classNames;
src/style.d.ts
declare const classNames: {
readonly 'row': 'row';
};
export = classNames;
型定義を利用してコンポーネントを実装する
src/App.tsx
import { VFC } from "react";
import styles from "./App.module.scss";
import { classNamesFunc } from "classnames-generics";
const classNames = classNamesFunc<keyof typeof styles>();
type Props = {
active: boolean;
};
export const App: VFC<Props> = (props) => {
return (
<header
className={classNames(
styles["header-1"],
{ [styles.active]: props.active },
styles.row
)}
>
vite-plugin-sass-dts-example
</header>
);
};
補完もきちんと効くようになっているので、開発速度の向上が期待できます。
Discussion