[Vite] CSSだけをビルドする方法
3 min read
背景
webpack の mini-css-extract-plugin のように CSS ファイルだけを Vite で出力したい。
Vite をインストール
まずは Vite 周辺の環境を構築する。
npm i -D vite postcss postcss-preset-env
npm create vite@latest
でも良いが、基本的に Vite しか使わないので個別で入れる。PostCSS は任意。
package.json については以下のような感じになる想定。
// package.json
{
"name": "vite-build-css",
"private": true,
"version": "0.0.0",
"scripts": {
"build": "vite build"
},
"devDependencies": {
"postcss": "^8.4.19",
"postcss-preset-env": "^7.8.2",
"vite": "^3.2.3"
}
}
仕様
CSS をビルドするときの仕様は以下を想定。
- CSS ファイルは、
src
ディレクトリに配置 - 出力ファイルは、
dist
ディレクトリに出力- ネスト階層も考慮
dist
はsrc
のディレクトリ構造を維持する
vite.config.js
// vite.config.js
import fs from "fs";
import path from "path";
import { defineConfig } from "vite";
const TARGET_DIRECTORY = "src";
const readdirRecursively = (dir, files = []) => {
const dirents = fs.readdirSync(dir, { withFileTypes: true });
const dirs = [];
for (const dirent of dirents) {
if (dirent.isDirectory()) dirs.push(`${dir}/${dirent.name}`);
if (dirent.isFile()) files.push(`${dir}/${dirent.name}`);
}
for (const d of dirs) {
files = readdirRecursively(d, files);
}
return files;
};
const getInputFiles = (extension = ".css") => {
const fileNames = readdirRecursively(TARGET_DIRECTORY).filter(
(file) => path.extname(file) === extension
);
const inputFiles = {};
for (let i = 0; i < fileNames.length; i++) {
const file = fileNames[i].replace(__dirname, "");
const fileName = file
.replace(extension, "")
.replace("..", "")
.replaceAll("/", "_");
inputFiles[fileName] = `${file}`;
}
return inputFiles;
};
// https://vitejs.dev/config/
export default defineConfig({
build: {
rollupOptions: {
output: {
assetFileNames: ({ name }) => {
return name.replace(`${TARGET_DIRECTORY}/`, "");
},
},
input: getInputFiles(),
},
},
});
Vite が PostCSS をサポートしているので、PostCSS が必要な場合は入れておく。postcss.config.js を追加しておけばいいので便利。
// postcss.config.js
module.exports = {
plugin: {
"postcss-preset-env": {
stage: 3,
},
},
};