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 JSON
oxc-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()
しようとしてコケるという問題がある。