孅いエンジニアブログ

Viteで複数のtsをそれぞれ1つのjsにバンドルしたい時

ViteでChrome拡張機能を作ってた時に、誰かが作ったモジュールをimportして使ってたら1つのファイルにできずに分割されました。

その時のコンフィグ設定です。

import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
	root: "./src/",
	build: {
		outDir: "../dist/",
		rollupOptions: {
			output: {
				entryFileNames: "[name].js",
				chunkFileNames: "[name].js",
				assetFileNames: "[name].[ext]"
			},
			input: {
				content: "./src/content.ts",
				background: "./src/background.ts"
			}
		}
	}
});

これでbackground.jsとcontent.jsが生成されるんやろなぁってアホな顔して考えてたら、import使われた上で別のファイルも生まれてしまいました。

Chrome拡張機能のcontent scriptsはimport使えないので、これだと困ります。

調べてみるとinlineDynamicImportsなるオプションがある様子。これを使うとimportを使わずにバンドルしてくれるっぽいけど、複数inputを指定してるとできないっぽい。困ったものです!

じゃあ複数回ビルドすればええやんって話で、ビルドコマンドを複数回実行するコマンドをどっかで見つけてきて、アレンジして作りました。

rm -rf ./dist/* && tsc && printf './src/content.ts ./src/background.ts' | xargs -d ' ' -P0 -I % vite build -- --input=%

xargsで並列実行しています。スペースで区切ってファイルを探す感じです。

'./src/content.ts ./src/background.ts'

ここで指定しているように、content.tsとbackground.tsを並列的に個別でビルドしています。

でコンフィグがこれです。

import { defineConfig } from "vite";

const input = process.argv[4]?.split("=")?.[1];
if (input) {
	console.log("Single building: " + input);
}

// https://vitejs.dev/config/
export default defineConfig({
	server: {
		host: "0.0.0.0"
	},
	root: "./src/",
	build: {
		outDir: "../dist/",
		emptyOutDir: false,
		rollupOptions: {
			output: {
				entryFileNames: "[name].js",
				chunkFileNames: "[name].js",
				assetFileNames: "[name].[ext]",
				inlineDynamicImports: true
			},
			input: input
		}
	}
});

並列実行する必要があるから、ビルドごとにdistを消されると困ります。なのでemptyOutDirをfalseにしています。

良いんじゃないでしょうか!