CRSJSとは?
「CRSJS」はviteのプラグインで、クロームの拡張機能を作るときにいい感じに環境を整えてくれる!(らしい!)
こちらの記事が非常にわかりやすかったです。
https://zenn.dev/7oh/scraps/98d5cdcceb9bd8
環境(抜粋)
{
"typescript": "^5.2.2",
"vite": "^5.0.8",
"@crxjs/vite-plugin": "^2.0.0-beta.21",
(後略)
content_scriptsを追記すると、build時にエラー
が、manifest.jsonにcontent_scriptsを書き、buildした時点でエラーとなったので原因を探りました。
manifest.jsonの中身
※viteでは、vite.config.jsにmanifestの内容をtypescriptで書くことができます。
import { crx, defineManifest } from "@crxjs/vite-plugin";
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
const manifest = defineManifest({
manifest_version: 3,
name: "web_memo",
version: "1.0.0",
content_scripts:[
{
matches: ['http://*/*', 'https://*/*', 'file:///*'],
js:["src/content_scripts.js"],
},
],
action: {
default_popup: "src/popup/popup.html",
},
});
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),crx({manifest})
],
})
エラーの内容
[crx:web-accessible-resources] TypeError: OutputBundle["manifest.json"] is undefined.
at parseJsonAsset (file:///Users/xxxxx/Desktop/hoge/node_modules/@crxjs/vite-plugin/dist/index.mjs:105:11)
at Object.renderCrxManifest (file:///Users/xxxxx/Desktop/hoge/node_modules/@crxjs/vite-plugin/dist/index.mjs:1887:32)
at Object.generateBundle (file:///Users/xxxxx/Desktop/hoge/node_modules/@crxjs/vite-plugin/dist/index.mjs:1670:60)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Bundle.generate (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:17006:9)
at async file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:19552:27
at async catchUnfinishedHookActions (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:18983:16)
at async build (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/dist/node/chunks/dep-R0I0XnyH.js:66815:22)
at async CAC.<anonymous> (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/dist/node/cli.js:845:9)
[crx:manifest-post] Error in crx:web-accessible-resources.renderCrxManifest
✓ built in 458ms
error during build:
Error: Error in crx:web-accessible-resources.renderCrxManifest
at Object.generateBundle (file:///Users/xxxxx/Desktop/hoge/node_modules/@crxjs/vite-plugin/dist/index.mjs:1683:19)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Bundle.generate (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:17006:9)
at async file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:19552:27
at async catchUnfinishedHookActions (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:18983:16)
at async build (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/dist/node/chunks/dep-R0I0XnyH.js:66815:22)
at async CAC.<anonymous> (file:///Users/xxxxx/Desktop/hoge/node_modules/vite/dist/node/cli.js:845:9)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
xxxxのとこはユーザー名です。プロジェクト名はhogeです。
対処方法
ひとまずエラーのうち、「TypeError: OutputBundle["manifest.json"] is undefined.」でググると以下の記事がhitしました。
https://github.com/crxjs/chrome-extension-tools/issues/836
割と最近issueとして上がっています。
で、どうすればいいか?というと、
node_modules/@crxjs/vite-plugin/dist/index.mjs
上記のファイルの、
const asset = bundle[key];
を、以下に書き換えます。
const asset = bundle[key] || bundle[`.vite/${key}`];
するとbuildでのエラーは発生せず、無事完了しました!
原因
これだけだとさっぱり原因がわからないのできちんとissue、コードを読み込んでみました。
ヒント1:issueにあるコメント
Stumbled on this today with Vite 5: they introduced a .vite directory where the manifest.json file is stored. They have a section about that in the migration docs for v5: https://vitejs.dev/guide/migration#manifest-files-are-now-generated-in-vite-directory-by-default
vite5では、manifest.jsonが.vite directoryの中に保存されているように変わったっぽい。。
これによりこの事象が起きている。というコメントです。
なんでだろう?
ヒント2: エラーメッセージを読みんさい
build中のエラーはメッセージでググると解決に至ることが多いので、つい慣れずに読むのを飛ばしてしまいました。
ちゃんと2行目にヒントがあります。
at parseJsonAsset (file:///Users/xxxxx/Desktop/hoge/node_modules/@crxjs/vite-plugin/dist/index.mjs:105:11)
index.mjsの105行目あたり、parseJsonAssetでエラーが出ていると。
該当の関数です。
function parseJsonAsset(bundle, key) {
const asset = bundle[key]
if (typeof asset === "undefined")
throw new TypeError(`OutputBundle["${key}"] is undefined.`);
if (asset.type !== "asset")
throw new Error(`OutputBundle["${key}"] is not an OutputAsset.`);
if (typeof asset.source !== "string")
throw new TypeError(`OutputBundle["${key}"].source is not a string.`);
return JSON.parse(asset.source);
}
で、気づいたのですが、
エラーの一行目。「throw new TypeError(OutputBundle["${key}"] is undefined.
);」で投げられていますね。
つまり、 if (typeof asset === "undefined") に入っていると言うことです。
ヒント3
ではここでparseJsonAssetを使っているところを見てみます。
検索すると。。定義とは別にhitしたのは1箇所だけ。1箇所でだけ使われているのでした。
同じファイルの以下の部分です。
if (contentScripts.size > 0) {
const viteManifest = parseJsonAsset(
bundle,
"manifest.json"
);
(後略)
contentScriptsがあるときにこの関数が実行されるようです。
なんとなくゴールが近くなってきた気がしますね。
取り急ぎの結論
この関数はbudleの中のkeyを取得して動作してます。keyはヒント3のコードにあるように"manifest.json"ですね。
つまりconst assets = bundle["manifest.json"]ということになります。
が、bundleをconsole.logを仕込んでからbuildしてみると、確かに["manifest.json"]がありません。
代わりに、.vite/manifest.jsonはありました!
ここの部分が、ヒント1で書いた「vite5でmanifest.jsonの位置が.vite配下に変わった」ことががエラーの原因になる、ということになります。
つまり
bundle["manifest.json"]
はないけど、
bundle[".vite/manifest.json"]
はあるので、「対処方法」に書いた内容で解消した、という状態でした。
まとめ
エラーで検索するのも大事ですが、エラーを読んでいくのも大事だなと改めて実感しました。
プラグインとかライブラリの中まで読んで、理解できていくと楽しいですね!(ほんの一部だけですが!)