Skip to content

Rename js/run.mjs to js/run.js to survive strict MIME checking#217

Merged
znz merged 1 commit into
rurema:masterfrom
znz:run-js-mime-type
Jul 10, 2026
Merged

Rename js/run.mjs to js/run.js to survive strict MIME checking#217
znz merged 1 commit into
rurema:masterfrom
znz:run-js-mime-type

Conversation

@znz

@znz znz commented Jul 10, 2026

Copy link
Copy Markdown
Member

問題

#216 の RUN ボタンが本番 docs.ruby-lang.org で動きません。ブラウザコンソールに:

Failed to load module script: Expected a JavaScript-or-Wasm module script
but the server responded with a MIME type of "application/octet-stream".
Strict MIME type checking is enforced for module scripts per HTML spec.

原因は配信側の MIME 設定です。.mjs 拡張子が nginx の mime.types に
入ったのは 1.21.4(2021-11)からで、本番サーバーの MIME テーブルには
mjs のエントリがなく application/octet-stream で配信されます。
通常の <script> なら MIME が多少おかしくても実行されますが、
<script type="module"> は HTML 仕様で厳格な MIME チェックが必須のため、
ロードが拒否されます。

方針

js/run.mjsjs/run.js にリネームします。

  • モジュールかどうかを決めるのは <script type="module"> 属性であって
    拡張子ではないため、.js にしても ES モジュールとしての動作は不変です
  • .js はどのサーバーの MIME テーブルでも JavaScript にマップされるため、
    docs.ruby-lang.org に限らず、statichtml の出力をどこでホストしても
    動作します(サーバー側の nginx 設定変更や Fastly のキャッシュパージに
    依存しない、bitclust 内で完結する修正です)
  • ファイル名が変わるので、CDN に application/octet-stream
    キャッシュされた旧 URL の影響も受けません

QuickJS テストランナー test/js/test_run.mjs.mjs のままです
(qjs がトップレベルファイルをモジュールとして実行するのに拡張子が必要。
import されるファイルは常にモジュールとしてコンパイルされるため、
run.js の import は問題なく動きます)。

テスト

  • test/test_run_ruby_wasm.rb / test/test_statichtml_command.rb
    run.js 期待に更新(先に red を確認してからリネーム)
  • 全スイート 17554 tests, 0 failures
  • qjs test/js/test_run.mjs パス

デプロイ

マージ後、generated-documents の daily build で 3.2〜4.1 の全ページが
js/run.js 参照で再生成され、copy_run_ruby_wasm_script が新ファイルを
配置します。ビルド側(doctree Rakefile / generated-documents)は
--run-ruby-wasm フラグしか参照しておらず、ファイル名には依存していない
ため変更不要です。

🤖 Generated with Claude Code

docs.ruby-lang.org serves .mjs as application/octet-stream (its nginx
MIME table predates the mjs entry added in nginx 1.21.4), and browsers
enforce strict MIME checking for module scripts, so the RUN button
failed to load in production. What makes the script a module is the
<script type="module"> attribute, not the file extension, so ship the
file as .js, which every MIME table maps to a JavaScript type.

The QuickJS test file keeps its .mjs name (qjs needs it to pick module
mode for the top-level file); imported files are always compiled as
modules, so importing run.js works unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@znz znz merged commit caeda4c into rurema:master Jul 10, 2026
9 checks passed
@znz znz deleted the run-js-mime-type branch July 10, 2026 23:09
znz added a commit that referenced this pull request Jul 13, 2026
RUN ボタンは ruby.wasm をメインスレッドで同期実行しており、無限ループや
長い sleep を含むサンプルではタブの UI が完全に固まっていた(fix #239)。

- 実行を新設の theme/default/js/run-worker.js (module Worker) に移動。
  wasm のコンパイルはこれまでどおりメインスレッド側で一度だけ行いキャッシュ
  し、WebAssembly.Module を実行ごとに使い捨ての Worker へ postMessage で
  渡す。VM は実行のたびに作り直すので、terminate() 後の再実行やコンパイル
  やり直しの問題は生じない
- 実行中は RUN ボタンを STOP に切り替え、クリックで Worker.terminate()
  して中断できるようにした。30 秒(RUN_TIMEOUT_MS)経過でも自動的に
  terminate し、出力欄にその旨を追記する
- $stdout/$stderr を StringIO に溜めて eval 完了後に一括取得していたのを
  やめ、Worker 内で書き込みのたびに JS.global.call(:postOutput, text) で
  メインスレッドへ逐次 postMessage するようにした。表示側の 64KB 打ち切り
  (旧 truncateOutput 相当)は accumulateOutput として維持しつつ、打ち切り
  後の追加チャンクは即座に捨てるようにして無限出力ループでも O(1) で済む
  ようにした
- Worker スクリプトの URL は new URL('run-worker.js', import.meta.url) で
  run.js 自身の URL から解決し、ページの階層やテンプレート側の
  custom_js_url() の実装に依存しないようにした
- run-worker.js も run.js 同様に .mjs ではなく .js 命名にした(#217 と同じ
  MIME 判定の理由)。statichtml のテーマファイルコピー処理
  (copy_run_ruby_wasm_script)を RUN_RUBY_WASM_JS_FILES 経由で2ファイルとも
  コピーするよう拡張し、片方だけ欠けているテーマも許容する
- test/js/test_run.mjs に純粋関数のテスト(accumulateOutput・
  STOPPED_NOTE・timeoutNote・run-worker.js の PRELUDE/formatRunError)を
  追加。Worker/DOM は QuickJS では扱えないため、テストはこれまでどおり
  純粋関数部分のみを対象にしている

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant