OxcのParserを、JavaScriptで使う | Memory ice cubes https://leaysgur.github.io/posts/2024/01/18/165645/
続きです。
あらすじ
- npmに公開されてるoxc-parserは、Node.js専用だった
- ならOxcのWebサイトにあるPlaygroundはどうやって動いてる?
という謎を解き明かす回。
Webサイトの構造
土台としては、それ用のリポジトリがある。
oxc-project/oxc-project.github.io: Website https://github.com/oxc-project/oxc-project.github.io
けど、Playgroundのページはハードな外部リンクになってて、ここを探しても何も見つからない。
実は、Playgroundの部分のコードは、Oxcの本体リポジトリに間借りしてる。
で、肝心のOxcのWASMポートはどこにあるのかというと。
- ここにはwasm-packによるビルドコマンドだけがあり- --target webが指定されていて
 
- コードはcrates/oxc_wasmにある
そして@oxc/wasm-webというパッケージ名で内部的に利用されてるけど、まだ公開はされてない。
OxcのWASMポートの状況
そのためのIssueがこちら。
Publish wasm · Issue #301 · oxc-project/oxc https://github.com/oxc-project/oxc/issues/301
ざっくりまとめると・・・、
- Playgroundの例みたく、WASMにして使うこと自体は現状でも可能
- ただAPIはもとより、プロジェクトのスコープとしてWASMに手を出すべきかも決めかねてる状況
- TSの型もまだないし、ビジター側の仕組みもない
という感じらしい。
で、とりあえず型つけてみるぜ!っていうPRが立てられたのが、ここ最近のお話。
feat(ast): TypeScript definition for wasm / napi target by H-Plus-Time · Pull Request #2158 · oxc-project/oxc https://github.com/oxc-project/oxc/pull/2158
という話でした。
crates/oxc_wasm
(外部公開されてないので、記事はもう終わりにしてもよかったけど、ちょっとだけ書いておく。)
https://github.com/oxc-project/oxc/tree/main/crates/oxc_wasm
コードはココにあり、現状は先述のとおりPlayground用途に特化したAPIを公開してある。
っても、ASTが欲しいだけなら、こうすればよい。
// Need to build and alias by myself
import initWasm, {
  Oxc,
  OxcRunOptions,
  OxcParserOptions,
  OxcLinterOptions,
  OxcCodegenOptions,
  OxcMinifierOptions,
} from "@oxc/wasm-web";
await initWasm();
const oxc = new Oxc();
oxc.sourceText = "// YOUR CODE HERE";
oxc.run(
  new OxcRunOptions(),
  new OxcParserOptions(),
  new OxcLinterOptions(),
  new OxcCodegenOptions(),
  new OxcMinifierOptions(),
);
oxc.ast; // ESTree AST by JSONoxc-parserと違って、こっちはもうJSONになってる。
中では安心と実績のwasm-bindgenとconsole_error_panic_hookが使われてた。
とか言ってたら
勢いがあるのでnpmからインストールできるようになった。
Publish wasm · Issue #301 · oxc-project/oxc https://github.com/oxc-project/oxc/issues/301#issuecomment-1916951538
@oxc-parser/wasmというパッケージ名になってて微妙に違うところに注意。
ただ書いてあるように、今はビルドがwasmpack build --target webしか対応してないので、Node.jsからは使えない。
いちおうメモしておくと、package.jsonの指定が甘くNode.jsのネイティブESMでロードできないのと、.wasmをfile://でfetch()しようとしてコケるという問題がある。