ということを学んだ。
こういうケース
// index.ts
import { type ParserOptions } from "oxc-parser";
const myFunc = async (opts: ParserOptions) => {
const { parseSync } = await import("oxc-parser");
return parseSync("test", "let a =1;", opts);
};
// Later...
myFunc({}).then((result) => console.log(result));
parseSync()
は必要になるまでロードしたくないという意味で、Dynamic importをしてるとする。(ViteはDynamic importもtree-shakeしてくれて偉い)
同時に、型だけ使いたいからimport { type A }
というtype
を内側に書くやり方をしてる。
一見、なにも問題ないように見える。が、実際にはそうではないらしかった。
問題
parseSync()
の実装が、index.ts
側にバンドルされちゃうみたいな出力結果になる。
vite v6.3.5 building for production...
✓ 9 modules transformed.
dist/index.html 0.38 kB │ gzip: 0.27 kB
dist/assets/wasi-worker-browser-DSdL8bZF.js 165.13 kB
dist/assets/parser.wasm32-wasi-DPiy-7BD.wasm 1,620.11 kB │ gzip: 471.17 kB
dist/assets/wasm-BTSMSx_C.js 0.53 kB │ gzip: 0.33 kB
dist/assets/index-C0RdaAXH.js 187.21 kB │ gzip: 43.73 kB
✓ built in 488ms
エントリーであるindex.js
が重たくなってるところが問題。
というわけで
// index.ts
import type { ParserOptions } from "oxc-parser";
const myFunc = async (opts: ParserOptions) => {
const { parseSync } = await import("oxc-parser");
return parseSync("test", "let a =1;", opts);
};
// Later...
myFunc({}).then((result) => console.log(result));
import type { A }
方式にすると、想定した通りの結果になった。
vite v6.3.5 building for production...
✓ 9 modules transformed.
dist/index.html 0.38 kB │ gzip: 0.27 kB
dist/assets/wasi-worker-browser-DSdL8bZF.js 165.13 kB
dist/assets/parser.wasm32-wasi-DPiy-7BD.wasm 1,620.11 kB │ gzip: 471.17 kB
dist/assets/wasm-DBfLOrs_.js 185.68 kB │ gzip: 43.00 kB
dist/assets/index-CeYCIOMS.js 2.00 kB │ gzip: 1.02 kB
✓ built in 491ms
oxc-parser
は現状CJSで書かれてる(つまりtree-shakeされない・・・)ので、もしかしたらそれのせいもあるかもしれない。
けど、まあこういうこともあるのだなあと。
個人的にはもともとimport type {}
で分けて書け派なので気にしたことなかったけど、試しにAIに書かせてみたらこれに気付いたという話。