Open3

WebGL-Native: 脱Node.jsの作戦を考える会

okuokuokuoku

prev: https://zenn.dev/okuoku/scraps/fdfaff96dbf16f
next: https://zenn.dev/okuoku/scraps/efa3e214ee8348

脱Node.jsの残件とは..?

前回までで、Node.jsやnpmモジュールへの require() をほぼなくすことができた。つまりJavaScriptエンジンに NCCC の呼出し機能があれば、 wasm2c と自前のWebGL実装を駆使してWebGLゲームが遊べる状態になっている。

ただ、今でも、

  1. NCCC実装はNode.jsというかN-APIで実装しているため、N-APIをサポートしたJavaScriptエンジンでなければならない
  2. ローカルのモジュールの参照には依然 require を使っている

という点がある。とりあえず、ECMAScript 5の実装であるDuktapeに移植することを考えてみよう。。Rollupか何かでバンドルして、BabelでES6機能を削ってしまえば行けるんじゃないだろうか。

okuokuokuoku

前準備

とりあえず、excludeするモジュールを指定しやすいように、最終的に残ったNode.js依存部分を port-std.js (Node.jsの標準ライブラリ) と port-native.js (NCCC実装) に分割した。

https://github.com/okuoku/cwgl-proto/commit/b2f6dccafbc2a645841f0be9c068ae49f7edc1c9#diff-5662b9a9a5a1020472e924891a4fff4d4438286e829df79ef21c718a263c88ef

https://github.com/okuoku/cwgl-proto/commit/1c2896cf23589503a213c229f00b57599b93bc3c#diff-4f54bd43f37e68705dbb91fe556b5a79310a02c8773a0a7fcd086cd261d48958

const fs = require("fs");
const crypto = require("crypto");
const perf_hooks = require("perf_hooks");

module.exports = {
    performance_now: perf_hooks.performance.now,
    fs_readFileSync: fs.readFileSync,
    crypto_randomFillSync: crypto.randomFillSync,
};

スッカリ忘れてたけど、randomとか performance.now が依存部として有ったね。。まぁ大した機能じゃないし後まわし。

適当にrollup.jsの設定を書いてexclude。

https://github.com/okuoku/cwgl-proto/commit/53c43eb24c4b60f82719c7f58807add9e663075e#diff-860dc910730733c765ed6ccedc651ddb164015f943cfc0475ba9e2c8188faca2R12

okuokuokuoku

変換後のを実行してみる

file:///C:/cygwin64/home/oku/repos/cwgl/jstestapp/duk.mjs:4354
        var _instantiate = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(obj, imports) {
                                                           ^

ReferenceError: regeneratorRuntime is not defined

... Babel が変換する async って勝手にランタイムをimportしてくれたりはしないのか。。手動で

import "regenerator-runtime/runtime.js";

を書いておいて、かつ、 Rollupjsの @rollup/plugin-node-resolve プラグインでResolveした上で挿入してやる必要がある。

https://rollupjs.org/guide/en/#rollupplugin-node-resolve

今回は rollup.config.js でNode.js専用のモジュールはexcludeしているので、変換後のスクリプトをNode.jsで実行するには

import PortStd from "./port-std.js";
import PortNative from "./port-native.js";

のような import を変換後のスクリプトの先頭に追加する。