【Vite】CRAなasset-manifest.jsonを生成する

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Vite】CRAなasset-manifest.jsonを生成する

2024-9-10 | ,

ViteでもCRAスタイルなasset-manifest.jsonを生成したい!

概要

今回の記事では、ViteでもCRAスタイルなasset-manifest.jsonを生成する手順を掲載する。

CRAからViteに移行したんだけども、CRAが生成するasset-manifest.jsonに依存してるシステムがあって、Viteでもasset-manifest.jsonが出力されるようにしてみた。

仕様書

環境

  • Node.js 20.15.0
  • npm 10.8.1
  • vite 5.4.1

手順書

CRAがビルド時に生成するasset-manifest.jsonは下記のような感じ。

{
  "files": {
    "main.css": "/static/css/main.96f9c621.css",
    "main.js": "/static/js/main.fe9d14f9.js",
    "static/js/787.f16c1f56.chunk.js": "/static/js/787.f16c1f56.chunk.js",
    "index.html": "/index.html",
    "main.96f9c621.css.map": "/static/css/main.96f9c621.css.map",
    "main.fe9d14f9.js.map": "/static/js/main.fe9d14f9.js.map",
    "787.f16c1f56.chunk.js.map": "/static/js/787.f16c1f56.chunk.js.map"
  },
  "entrypoints": [
    "static/css/main.96f9c621.css",
    "static/js/main.fe9d14f9.js"
  ]
}

今回はこんな感じのjsonをViteでも生成できるようにする。

vite.config.tsにプラグイン処理を直接入力する。

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { writeFileSync } from 'fs';
import { resolve } from 'path';
import type { OutputBundle, OutputChunk } from 'rollup';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        react(),
    ],
    build: {
        rollupOptions: {
            plugins: [
                {
                    name: 'generate-asset-manifest',
                    generateBundle(_, bundle: OutputBundle) {
                        const files: Record<string, string> = {};
                        const entrypoints: string[] = [];
                        let entrypointCss: string = "";

                        for (const [, value] of Object.entries(bundle)) {
                            const fileName = value.fileName.split('/').pop() || '';
                            const [baseFileName, ...extParts] = fileName.split('.');
                            const extension = extParts.pop();
                            const cleanBaseFileName = baseFileName.replace(/-[\w-]{8}$/, '');

                            if ((value as OutputChunk).isEntry) {
                                entrypoints.push(value.fileName);
                                entrypointCss = `${cleanBaseFileName}.css`;
                            }

                            files[`${cleanBaseFileName}.${extension}`] = value.fileName;
                        }

                        if (entrypointCss in files) {
                            entrypoints.push(files[entrypointCss]);
                        }

                        const manifest = {
                            files,
                            entrypoints,
                        };

                        writeFileSync(resolve(__dirname, 'public/asset-manifest.json'), JSON.stringify(manifest, null, 2));
                    }
                }
            ],
        },
    }
})

ハッシュ値を消したりなんだりして、ファイルを登録してく。

npm run buildを実行するとpublic/asset-manifest.jsonが生成される。

まとめ(感想文)

asset-manifest.jsonを自分で作る日が来るとは思わなかった。