🧊

続・OxcのParserを、JavaScriptで使う

OxcのParserを、JavaScriptで使う | Memory ice cubes https://leaysgur.github.io/posts/2024/01/18/165645/

続きです。

あらすじ

という謎を解き明かす回。

Webサイトの構造

土台としては、それ用のリポジトリがある。

oxc-project/oxc-project.github.io: Website https://github.com/oxc-project/oxc-project.github.io

けど、Playgroundのページはハードな外部リンクになってて、ここを探しても何も見つからない。

実は、Playgroundの部分のコードは、Oxcの本体リポジトリに間借りしてる。

https://github.com/oxc-project/oxc/tree/main/website

で、肝心の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-bindgenconsole_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でロードできないのと、.wasmfile://fetch()しようとしてコケるという問題がある。