背景
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,
},
},
};