ムキムキマッチョマン

心も体もムキムキマッチョマン

HTML Living Standard 1 introduction を読んでWeb標準に触れてみる

こんにちは。ムキムキマッチョマンになりたい人です。心も体もムキムキマッチョマン。 フロントエンド領域でのムキムキマッチョマン目指して頑張っています。 この記事は技術記事の皮を被った、IT知識トレーニングの記録です。

導入

我々フロントエンドエンジニアなら誰しも一度は記述するHyper Text Markup LanuageことHTMLですが、書き方やタグのルールはどのようにして決められているのでしょうか? HTMLの標準仕様における現行版「HTML Living Standard」を読み、Web標準について理解を深めるブログです。

Webを支える「標準」

HTMLのルールはブラウザ開発会社のエンジニア等が集まる団体がHTMLはこういうルールでいきましょう、と取り決めています。その取り決められたルールを標準と呼びます。実はこの標準、Webを支えるありとあらゆる技術に存在しています。ちなみに標準を決める団体を標準化団体と呼びます。例えばECMAIEEEW3Cなど様々な標準化団体が存在しています。

Web技術に使われている標準は、Web標準と呼ばれており、以下のような標準が存在しています。

ちなみにWeb標準におけるHTMLは画像において「This Specification」で示される領域に位置付けられます。

参照:HTML Living Standard(https://html.spec.whatwg.org/multipage/introduction.html#abstract)

私たちはなぜ標準を(あんまり)気にせずにWebで開発をしたり、ブラウジングしたりできているのか

この標準、Webにおいては至る所に存在していますが開発をしている時にHTMLのタグのルールについて細かく気にすることなく開発ができますし、ブラウザでWebサイトを開いているときHTMLの細かいルールについても気にしなくて良くなっています。例えばあるWebサイトを開くときにあるブラウザAだとサイトがみれるけど、ブラウザBではそもそも表示がめちゃくちゃ崩れていて見れないなんてことはありません。*1

それは各ブラウザやエディタ開発者(団体)が、HTMLや他のWeb標準に従ってブラウザやエディタを作っているからです。標準化団体が草案を作り、標準の検証を開発者各自がブラウザに実装する形で行い、標準を公開しブラウザが実装に取り入れる。なんて流れで私たちの手元に標準が届き、大体のWebサイトをどんなブラウザでもみることができるわけです。

仮にWeb標準を採用していないブラウザがあったとすると、それはHTMLを勝手に解釈して勝手に表示しているオレオレ仕様というわけです。

標準を公開しブラウザが実装に取り入れるということは、どこかに標準が公開されているはずです。 その公開されている標準と細かい実装や規則が書かれたものを標準仕様書なんて読んだりします。 英語だとspecificationとかで表現されたりします。

エンジニアなら誰しも読みたい標準仕様書

エンジニアとして開発をしていると、そういえばHTMLには俺の知らない仕様があるのかも....なんて思ったり、いや〜ブラウザ作りたいからHTMLの詳しいルール知りたいな〜なんて思ったりすることが一度や二度あるはずです。

そこで読むのが標準仕様書です。

HTML Livinig Standard

HTMLの標準仕様書はHTML Living Standardという名前で公開されており、WHATWGという団体が標準化〜管理を行なっています。HTMLの標準は一度決められるとそれが一生続くわけではなく、むしろ一生更新し続ける生きている (living)標準なんです。

全文はこちらのサイトから

なぜ「Introduction」?

HTML標準仕様書初めて読む方は、CとかC++のコードが載ってて詳しい実装が書いているんでしょ...?や、なんか細かい数式がいっぱい書いてて...みたいに思われるかもしれませんがそんなことはありません。

そもそも標準は実装に対して基本的には制約を設けませんあくまでも仕様です。実装まで具体化するとパフォーマンスに重大な問題があった際に変更しづらいなどがありますし、そこは抽象化した上で各ブラウザベンダにお任せで良いでしょう。

多くの標準仕様書のIntroduction(もしくは導入、もしくはabstract)にはとてもいいことが書いています。それは何かというと....

なぜ標準があるのか考えるための材料

標準仕様書のIntroductionの多くには、標準で定められた技術の歴史やなぜ今この団体が管理しているのか、どういう経緯で今開発され今後どうなっていくのか、技術のコンセプトなどが書かれています。 つまりちょっとメタ的な読み物なのです。HTMLをただのマークアップではなく、ちゃんと目的を持った技術であることが理解できます。

これの何が大事かというとわざわざコストをかけて標準化して公開するということはそれなりの理由が必ずあるということです。その理由は標準技術をどれだけ採用するか、そもそもそれを採用するかを判断していくための重要な軸になり得ます。まずは細かい実装を読むためにIntroductionを読んでみる。大事なアプローチです。

そしてIntroductionにはもう一つ、標準仕様書の詳しい読み方が書いていることが多いです。 というのも標準仕様書は相当な分量があるため、書き方や表現を統一することで余計な情報を省きその本質だけを記述する必要があるのです。というわけでそれを読むためのいわゆるお作法なども書いています。

読んでみよう。

ここまできたらまずは読んでみましょう。

英語版が読める方は公式版を、英語が読めないよ〜という方はmomdoさんという方が翻訳している日本語版があります。日本語版ではなるべく英語やカタカナを日本語に訳し、意図せず意味が重複しないよう分けて書かれているなど翻訳精度がかなり高いです。若干読み慣れないかもしれませんが理解の助けになっています。

1時間もあれば意外にさっと読めるはずです。

最後に

さて、Introductionを読んでみていかがですか?意外と読めますよね。あ、これってこうなんだってことありますよね?これってこんな書き方できるの?ってありますよね。それが醍醐味です。

これをきっかけにぜひ他の仕様書なども読んでみて私たちのWebを支える技術について詳しくなれると嬉しいです!

*1:これを書いている時に最近でも細かいところは結構あるなぁと........

PHPカンファレンス小田原2024参加レポ、大感謝祭!!!

こんにちは。ムキムキマッチョマンになりたいね。心も体もムキムキマッチョマン。 フロントエンドムキムキマッチョマン目指して頑張り中。 今回は番外編あっさりとしたブログ。全方位大感謝祭!!!!!

フロントエンドエンジニアだし札幌市民だけど #phpcon_odawara

フロントエンドエンジニアだけど

メインで触るのはTypescriptとかだけど、PHPはお仕事でまあちょろっとかくし、WordPressとかでちゃんとプラグイン書いてたから最低限の理解で臨んでる。 お仕事で使うなら深く知りたいし、困ったときの引き出しは多いといいよねってことでフロントエンド以外のイベントも参加したいと言うことで参加。やっぱり本職の方々の話を聞くとすごい楽しい、ワクワクできる。

あとPHPカンファレンス全体的にPHPに限らず、PHPの話でも横展開可能な話が多くて非常に助かる。特にアプリケーションバックエンドをしっかり作っている人の話はめちゃんこためになる。個人的には言語仕様とかのレイヤ低めの話が多かったのは嬉しかった。めもりーさんのASTの話とか、tadsanさんのPSRの話とか、nsfisisさんのJITの話とか、最近興味ある領域だったので非常に嬉しみだった。

スポンサーの話でいくと市川さんのVaddyの話非常に良かった。目頭激アツ、あの話を和気藹々と話している姿を見てハァ〜〜〜〜と思ってた記憶。資料上がってないのかな〜って探したらなさそう? そうして得たものをコミュニティ還元していく形、PHPカンファレンスどこで開催していてもスポンサーがコミュニティの中にしっかりと”いる”のが非常に良い。

超絶怒涛閑話休題

個人でfacebookが開発しているhack/hhvmを触ろうと思ってビルドしてる時に依存ライブラリとして出てきたbisonの正体が知れて嬉しかった。yacc→bisonらしい。GNUも牛だしね(by tadsan)

札幌市民だけど

面白そうだったので小田原来てみた。月刊制覇したかったけど関西は体調不良、phperkaigiは予定合わずで小田原から毎月行く予定。自分もイベント運営する人間なんだけどPHPカンファレンス北海道で感じたあすみさんと運営陣の熱量に当てられて参加決意。成田から車でGO。

北海道民まあ道外イベント結構ハードル高いんだけど、かなり良い。良かった。来月も香川行くけどめちゃくちゃ自信を持ってお勧めできる。北海道の人が気軽に本州のイベントに参加できるくらい稼げると色々いいんだろうなぁ。

超絶怒涛閑話休題

めっちゃ道混んでた。首都高も混んでた。京葉線も混んでた。飛行機乗り過ごした。 スカイメイト最高。JALありがとう大感謝祭!!!!!

かなり居心地の良いイベントだった(個人的感想)

自分が運営とかじゃないイベントも久しぶりで、割とのんびりしていた記憶。 前夜祭からゆるりとだけどしっかりと運営されていて、雰囲気は暖かいのに温いわけじゃないイベントの雰囲気が個人的ベストマッチでした。毎秒開催されていて欲しいなって。

街の雰囲気と合わさって非常にのんびり好きな感じで3日間過ごせたな〜という感覚。体力はまあ消耗してるはずなんだけどかなり満足度が高い。3日間バカンス行った気持ち。

あとは運営陣のもてなし力にただただ脱帽してた。自分でもイベントやるけどその辺がベストエフォートなりがちで、飯ブログとか駐車場ブログとか非常に助かるから本当にすごいなぁって。munoさんありがとうございました!!!!!大感謝祭!!!!!

非公式一次懇親会とか、2次会とかあすみさんの努力の結晶がいろんなところで生まれていてマジ運営お疲れ様でした(脱帽、土下座)みたいな感じだった。

あすみさんのぐっと引き込む力がすげえなぁ〜〜〜と感動。あとは前夜祭司会を「信頼してるで」で任せられる関係性と決断力となんとかする力。ちゃんとコミュニティ運営側にも還元されているイベントすごいな〜〜〜って。 司会初めてとは思えないし、全体通して準備されてるな〜〜〜感が非常に良かった。

ハンズオンイベントのアイスブレイクでIRTするのめっちゃいいかも〜〜〜〜とか考え中。

札幌のカンファレンスイベント未経験勢に参加者としてきて欲しいな〜〜〜とか思った。

小田原にはARUYOがARUYO、札幌にはNAIYO(号泣)

ARUYOめちゃくちゃいい施設だった。何がいいって前夜祭のお店(めちゃくちゃご飯美味しかったよね、カレーもオムレツもあれ最高)も受付応対してくれた施設の人も、みんな「PHPカンファレンス小田原」が何かを理解してた感じがあってあ〜〜受け入れられてるいい空間だ〜〜って。

NEさん全然知らなかったんだけどVery偉大カンパニーすぎる。もちろんHameeさんも。 ちゃんと経済活動があってそこを主体にコミュニティが形作られていて街がそれを受け入れているのが偉大。 それを維持するために地域の若手プレイヤーが引っ張っていってるのもすごい。 とみおさんと小田原の労働人口若い件についてちょろっと話したけど活気あったな〜〜〜

札幌に同じ場所がないの?って聞かれると難しい顔をしてしまうな〜と。 全くないわけじゃないし、歴史の中で類似する施設や場所はあっただろうけどな〜〜〜今はな〜〜〜というお気持ち。

ARUYOを作ると決めた人も運営している人もコミュニティに関わり続けている人もみんながあって偉い。大感謝祭!!!!!

小田原いい街だね〜

雰囲気最高。東京から1時間でこの立地手に入るのアドすぎる。 箱根や熱海も近くて、ご飯おいしくて雰囲気良いのがいいね。 関西圏よく行くし似たような街並みの雰囲気あるんだけど、なんだろう小田原優しい街な感じ。 二日酔いの日の味噌汁?

また行きたいな。来年いつだっけ同じ時期?開催楽しみにしてますね。 東京から1時間なら小田原行きたいかも。あ、いけそう。自分の中でいける確信が生まれて経験を獲得したのでいつでもいけますね。東京行く時はなるたけセットで行こ。

ロマンスカー乗りたい。

大感謝祭!!!!!

マジ、お疲れ様でした。最高!またきます!!!

ESLint職人の朝は早いーー。ESLint v9.0.0への移行とflat config対応

こんにちは。ムキムキマッチョマンになりたい人です。心も体もムキムキマッチョマン。 Webフロントエンド領域でのムキムキマッチョマン目指して頑張っています。 この記事は技術記事の皮を被った、IT知識トレーニングの記録です。

導入: ESLintとは何だったのか?

ESLintといえば、Node.js環境下においてスタンダードなルール=規則ベースのリンター(静的検査ツール)です。

特徴としてESLintの登場した2013年の他リンターになかった、その拡張性の高さが挙げられます。

pluginやごとのextendsといったプロパティに有志が作成したカスタムルールやルールの設定を組み合わせることで複雑なリンティングやが実現可能になり、よりコード全体を安全な状態に保つことができます。 また、rulesにリンティング規則を記述することで既存の設定を上書きできることなどその機能性の高さと柔軟さで多くのJSerに受け入れられてきました。 特にVS CodeのESLint拡張機能にある自動修正機能を利用することで、ファイル保存時にリンターに怒られが発生した箇所を削除させ余計な行や使わない変数、不要なインポートの削除などができることもその強みの1つとして挙げられます。

ですが、ESLintの問題の1つとしてその柔軟性・拡張性ゆえの設定ファイルの書きづらさ、書くことのめんどくささが挙げられます。従来は.eslintrc.jsといった名称の設定ファイルを作成しそこに様々なルールを書く必要がありました一度作られ、フレームワークやライブラリが変わったのに更新されなかったり、コーディング規約が変わったのにrulesが変更されていないなど放置された.eslintrc*はNode.jsプロジェクトのある種スタンダードとなってしまっています。

この記事ではムキムキマッチョマンへの道として、最新のESLint設定方式であるflat configへの理解と一歩進んだESLintの知識をキャッチアップすることを目的としています。

flat configとESLint v9.0.0の登場

2019年にESLintの作者であるNicholas C. Zakas氏より1つのRFCが提案されました。 それがConfig File Simplification(無理やり訳すると設定ファイルの単純化とか?)です。 従来の.eslintrcでは不可能な拡張への対応に向けて、設定ファイルの構造自体を変更し単純化するとともに柔軟性を高めることを目的とした提案でした。

例えば2017年に挙げられたissue、Extending rule options in derived configs? #994では、ユーザーカスタムの共有コンフィグ*1ですでに設定されたルールの値を上書きすることはできても、そのオブジェクトや配列の一部のみを変更または追加はできないことがissueとして挙げられています。

これら問題への対応として、既存の設定ファイル構造を変えるのではなく(影響範囲が大きいため)新しいファイル構造と設定システムを導入することにしたのがflat configでした。

flat configについて詳しいことは後述しますが、従来のextendsとpluginsの組み合わせによる1つのファイルに全て書き込む方式ではなく、extendsやrulesのグループを1つの設定=configとして捉え、それらを横並びで記述していくこと=flatflat configの基本になります。ここのflatJavaScriptのflatMapにおけるflatと同じ意味を持ち、設定を次元数1の配列に記述して行く方式とも捉えられます。(ここも後述しますが配列内の優先順位は後勝ちのため、詳細度の高いルールを後ろに記述する形になります)

2022年8月1日にリリースされたv8.21.0にて、APIが初期実装され、2023年10月10日にNicholas氏によるflat configへの移行プランが公開されました。この時点ではflat configは環境変数によるopt-in方式(利用を明示しないと使えない)機能として提供されていました。 段階的な移行としてv9.0.0でのデフォルト化、2024年末〜2025年にかけてリリースされるv10.0.0での.eslintrcの完全廃止が掲げられました。

そしてこの記事を書いている4月6日、現地時間だと4月5日にv9.0.0がリリースされました!偉業!おめでとうございます... というわけで7時おき現在、記事を執筆しています!頑張るぞ!

もちろんそれ以外にもBreaking ChangesがいっぱいあるのでよしなにMigration Guide読んでください。

eslint.org

.eslinrc時代に立ち返る

flat config への対応をして行く前段階としてESLintとはそもそも何なのか、その拡張性をどう保ってきたのか?を探ります。ここでは前述のsharable config(共有コンフィグ)が鍵を握ります。

ESLintの概観は以下の一言でまとめられると考えています。「膨大なルールベースによる静的検査と、ルールそのものの追加と設定ファイルの共有による拡張性の高さ」これを実現するための機能がsharable config(共有コンフィグ)です。

blog.ojisan.ioこと統合開発環境さんの以下の記事で詳しくまとめられていますので、この記事をしっかり読んでもらえるのがベストです。

blog.ojisan.io

かいつまんで本当にざっくりまとめると以下の通りで

  • ESLintは独立したルール1つ1つの組み合わせで静的検査を行っている
  • extendsで読み込んでいるのは、ESLintの設定オブジェクトそのもの(なのでプラグインとかも読み込んでいる)
  • pluginsはルールそのものを追加する実装

上記2行目がsharable configを指しています。

このsharable config1つ1つを一次元の配列に記述していくこと=flat configであるという認識で良いと思います。

ちなみにeslint-config-hogehogeという名前でもextendsではhogehogeと書くだけで設定が読み込めます。これはESLint側の命名規則としてeslint-config-hogehoge命名されていればhogehogeを参照して設定を読み込む機能があるからです。

ここでは触れないのですがflat config以降は開発者向けに、依存しているプラグイン等のパッケージ情報をpeerDependenciesではなく、dependenciesに記述してねみたいなことが書いていたりします。詳しい話は現段階だと理解不足なのでパス!すません!

flat config への対応

今回は最新のv9.0.0を利用する前提です。v8.xでは環境変数からopt-inする必要があったのですが面倒なのでパス! 変更点をまとめる形で対応を考えます。

ファイル名の変更とESModulesの採用

まずファイル名が変わります。.eslintrcではなく、eslint.config.(js|mjs|cjs)です。お好みのモジュール解決システムに合わせたファイル名を記述してください。v9.0.0以降は.estlinrcは読み込まれず、eslint.config.(js|mjs|cjs)が読み込まれます。そのため既存の.eslintrcを残したまま移行することが可能です。

従来 .eslintrc では ESModulesが使えませんでした。ですが、flat configからは対応しています。export defaultで記述できます。個人的にメチャクチャ嬉しいですね。*2

FlatConfigとFlatConfigArray

.eslintrc でexportしていたのはObjectでしたが、今後はFlatConfigArrayになります。 FlatConfig1つ1つがObjectで、そこにrulesfilesを記述していく形です。

/// オブジェクト
module.exports = {
}
export default [
  {
  /// 1つ1つが設定オブジェクト
 }
]

FlatConfigについて

FlatConfigオブジェクトの基本は以下の通りです。

{
  name: "eslint-config-hogehoge", // Errorメッセージなどに表示される名称、なくても良い
  files: [""], // 静的検査にかけるファイルを指定
  ignores: [""], // 静的検査をかけないファイルを指定
  languageOptions: {}, // JavaScript解釈のための設定を行う。ecmaVersionの指定や, tsconfigの設定などはこちら
  linterOptions: {}, // ESLintの細かい設定が可能。inline configをOKにするかどうかなど
  processor: "", // pluginなどで提供されるプロセッサを使いたい場合は名前を記述
  plugins: { // pluginをname-valueで記述する。従来の配列は使えない
    pluginName: pluginObject 
  },
  rules: {}, // 従来通りにrulesを指定可能
  settings: {} // name-valueで記述できるconfig向け設定。あんまり使わない
 }

詳細:Configuration Files - ESLint - Pluggable JavaScript Linter

ここで重要になってくるのがrulespluginsが、filesignoresにマッチしたファイルのみにしか適用されないということです。

つまり、jsxには適用させたいがtsxには適用させたくないルールや、*.test.tsには適用させたいが*.spec.tsには適用させたくないルールといった形で設定を分離して表現することが可能になります。

export default {
  jsCommonConfig,
  tsCommonConfig,
  {
    files: ["**/*.js","**/*.mjs"],
    ignores: ["**/*.test.*, **/*spec.*"],
    rules: {} // testファイル以外のjsファイルに適用させたいルールを記述
  }
}

新しいsharable config

flat configに対応しているconfigでは、ドキュメントに記載されている方法に従って、そのオブジェクトをflat configとして読み込むことが可能です。 従来一般的だったeslint:recommendedは公式パッケージ@eslintrc/jsよりrecommendedオブジェクトとして配布されます。*3

import js from "@eslint/js";

export default [
    js.configs.recommended, // これだけでrecommendedの読み込みが可能です
    {
        files: ["**/*.js"],
        rules: js.configs.recommended.rules // この記述自体意味を持ちませんが、こういった形でrulesだけを呼び出すことも可能です
    },

]

pluginsについて

"hogehoge"というプラグインがあった場合、従来は配列に格納していましたが、flat configに対応していればname-valueのオブジェクトに書き写すだけで問題なく動きそうです。

import hogehoge from "eslint-plugin-hogehoge";

...
   plugins: {
     "hogehoge":  hogehoge
   },
...

移行にあたって利用しているパッケージの公式ページもしくはリポジトリを「hogehoge flat config」といった形で検索し、移行状況を確認し対応方法が明記されている場合はそれに従って記述してください

@eslint/eslinrcFlatCompatによる後方互換

では対応していないconfig、pluginはどうすれば良いのでしょうか? 公式が後方互換のためのパッケージとFlatCompatを利用した方式を提供しています。

@eslint/eslinrcパッケージから提供されるFlatCompatクラスのインスタンスを利用して既存のextendsを利用する方法が推奨されています。*4

以下公式ドキュメントより抜粋。

import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";

// CommonJSで提供されている__dirnameの偽装。Node v20 移行であれば import.meta.dirnameも利用可能
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// ディレクトリ指定等
const compat = new FlatCompat({
    baseDirectory: __dirname
});

export default [
    // 以下のように従来と同様のextendsが可能。以下でFlatConfigと等価
    ...compat.extends("eslint-config-my-config"),
];

2023年時点での振る舞いについて検証してくださっている方がいました。大感謝

t28.dev

.eslintignoreの廃止

ignoresに書きましょう。

今後のESLint設計について

v9.0.0の登場により、詳細度ごとに設定を記述できるようになりました。rootオプションは全てにおいてtrueとなっており、モノレポへの対応なども変わってきます。 そこで現時点で筆者が把握している範囲でのベストプラクティスっぽい設計の提案です。これは公式ドキュメントに書かれているものではなく筆者個人の見解のため、誤りを含む場合があります。設計法の起点にできればとは思いますが、これがスタンダードとは考えていないためこれをもとに個々人が独自にベストな方式を生み出していただければ幸いです。

① ただ一つのeslint.config.js

以下のissueではflat configは1つのファイルで管理するのが良いのかどうかを議論しています。 これについて2023年3月9日時点でNicholas氏は開発メンバーの意見を引用する形で、公式では複数ファイルをサポートしておらず単一のファイルで書くことを推奨しています。 github.com

そのため、ディレクトリルートに1つファイルを置く形です。

② プロジェクト全体の設定と個々のフォルダの設定、テスト向けの設定などを適切に書き分ける

filesignoresを活用した設定が重要になると考えます。 特定のフォルダ内に適用したいものはfilesを詳細に記述、その中でもignoreしたいものはignoresに記述してく形が現時点ではベターな方式だと考えます。

また、今後の拡張を考えたときに汎用性の高い一般的な規則はjsCommonConfigsといった形でまとめ、各パッケージのルールはpackageAConfigのように管理し、記述して行くのが良いかもしれません。

となってくるとFlatConfigArray内の前半は汎用的な共通記述、後半は排他的な固有の記述といった形です。 先に汎用的なものを記述しつつ、後半はできる限り影響範囲が小さくなるようfilesignoresを追加するのが良意でしょう。

typescript-eslintが提供するtseslint.configを利用した型情報付の記述

typescript-eslintflat configに対応した際にtseslint.config関数を利用することでFlatConfigの型情報が適切に付与された状態で記述できるようになりました。以下の利用がベストでしょう。

以下公式ドキュメント抜粋です。

// @ts-check

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
);

github.com

最後に

ESLintは長く続くリンターであり、私たちJSerの開発において切っても切れない存在となってきています。 新興のリンター登場によりその立場が危ぶまれつつも、その拡張性による表現力の高さは他に類を見ません。 ぜひ本記事が今後のESLint活用の役に立つと幸いです。

間違いがあればコメントいただけるとありがたいです。

*1:eslint-config-** で表現されるnpmパッケージとして配布される設定群のことを指します。英語ではsharable configとして表記され、ESLintコミュニティの中では一般的な表現として使われているため日本語訳では共有コンフィグと表現します。

*2:デフォルトはCommonJSのため、.mjsファイルに記述するかpackage.jsonのtypeにmoduleを指定するかどちらかが必要です。

*3:npm install @eslint/js -D にてインストールが必要です

*4:npm install -D @eslint/eslinrc でインストール必須

Web考古学を通してフロントエンドへの迷いを断ち切ろうーNetscape 3 / IE4.5をMacOS 9.0.4 on macOS 14で動かすー

ムキムキマッチョマンになりたい人です。心も体もムキムキマッチョマン。 Webフロントエンド領域でのムキムキマッチョマン目指して頑張っています。 この記事は技術記事の皮を被った、IT知識トレーニングの記録です。

Web考古学

ちゃんとした名称がありそうですが、1989年にティムバーナーズリー氏によって提唱されたWorld Wide Webに端を発した「Web」そのものの歴史を辿る試みです。具体的にはWikipediaを起点に、W3CWHATWGの仕様書やドキュメント、果ては古のブログやニュース記事を漁り当時その技術や対象がどう捉えられどうなると考えられていて結果としてどうなったのかを探っています。その中では古い実装で動くブラウザやOSなどに触れていく必要もあるかもしれません。本記事ではNetscape Navigator 3.0とIE4.5をmacOS 14上で動かす試みに挑戦したことを記録しています。

そもそも、なぜ考古学をするのか

2024年現在、Webフロントエンド領域は混迷を極めています。さまざまなライブラリやフレームワークが台頭し、エコシステムですら時事刻々と変化しています。それらを否定的に感じる人もおり、Webフロントエンド領域は手を出すべきではない、なんて言われることもありますね。

ですが、それらが現在私たちITエンジニアだけでなく多くの人が使う「Web」の中で使われている技術であることは間違いありません。 であれば、Webフロントエンドの技術的・環境的・文化的な問題点・課題点を改善することはあっても否定することだけでは進歩がないのでは?目指すべき姿であるムキムキマッチョマンにはなれないのでは?と考えました。

そこで大事になるのが歴史に学ぶことだと。

ドイツのビスマルクはこう言いました「愚者は経験に学び、賢者は歴史に学ぶ」 歴史の流れと思想を捉え、次に「Web」がとるべき姿、変化していく姿を予測し、自分の技術へと活かすことが大事だと。

ですが、マッチョマンにはそれだけでは足りないのかもしれないと考えました。 マッチョマンとして愚者であり賢者でありたい、経験も歴史もどっちも学びたいです。

Web技術の多くは先人たちによってさまざまなアーカイブ活動が行われアクセスすることも可能です。歴史を学びその歴史を体感・経験し、過去と現在を反復横跳びし、未来を考えることが今のフロントエンド領域に取り組むエンジニアにとって重要だと考えたのがWeb考古学のきっかけでした。

本題「Netscape 3 / IE4.5をmacOS 14で動かす」

Netscape NavigatorNetscape Communicationsが開発した、NCSA Mosaicから派生したブラウザで、今のFirefoxの源流にあたります。 対してInternet ExplorerMicrosoftが開発した、こちらもNCSA Mosaic派生のブラウザです。

これらはどちらも標準化前のJavaScriptを採用しているブラウザです。2024年現在私たちが触れているブラウザで動くJavaScriptは正式名称ECMAScriptで標準化団体ECMAScriptが定めた仕様に沿って標準化されています。

ですが最初期のJavaScriptはこれら2つのブラウザが独自に実装した、誤解を恐れずにいうのであれば2つのJavaScriptが動いていました。 それらを実際に触って動かし、現在のJavaScriptとの乖離を確認することで、なぜ今のJavaScriptになったのかという経緯を探るための第一歩です。

macOS 14でNetscape 3 / IE4.5を動かすためには

残念ながらNetscape 3もIE4.5もそのままではmacOS 14で起動しません。 かつてmacOSにはClassic modeと呼ばれるMacOS 9.xまでのアプリケーション起動をサポートする仕組みがあったようなのですが現在それらは無効になっています。 逆に言えば、MacOS 9.xでは動くということです。

MacOS 9.xで動くのであれば、MacOS 9.xが動く環境を作りそこにインストールすればいいのでは????

幸い、Netscape 3は以下URLなどからインストーラーがダウンロードすることができました。

https://www.macintoshrepository.org/2712-netscape-navigator-3-x-standard-gold-edition-

あとは、MacoS 9.x が動く環境を用意するだけです。

MacOS 9.xをエミュレーターで動かす

世の中にはエミュレーターというものがあります。コンピューターや機械の動き、とりわけ動かしたいソフトウェアよりも1つ下のレイヤーにあるものを模倣し、ソフトウェアをある種騙す形で動いてもらう仕組みです。

最初調べている中で、 https://infinitemac.org/ と呼ばれるWebAssembly上でエミュレーターを起動させ、MacOSを動かすソフトウェアがありました。 これらはすごい!と思いつつ外部とのインターネットを介した通信ができず悩んでいたところ、infinite-macのGitリポジトリ にてMacOS上で動くエミュレーターの存在を知りました。

それが、SheepShaverでした。

SheepShaver とは? オープンソースソフトウェアであり、古いMacOSUnixWindowsを動かす事のできるエミュレーターです。

https://sheepshaver.cebix.net/

ですがSheepShaver本体はソースコードのみが公開されており、macOS向けに動くアプリケーションは提供されていない....と思ったところ有志がコミュニティサイト「E-malculation」のフォーラムにてmacOS14向けにビルドされたSheepShaverを提供していました。

これで光明が見えてきました

SheepShaverをインストールし動かすためには

ここから先は全て自己責任です

SheepShaverはOSイメージなどは同梱していません。そのため以下のものが必要になります

  • MacOSをインストールするためのROM
  • MacOSのOSイメージ(isoファイル)
  • SheepShaverの設定フォルダ
    • keycodesファイル
    • SheepShaver Scripts
  • SheepShaverの本体

上記を任意フォルダ上にダウンロード後展開していく流れです。 以下のようなフォルダ構成になれば正解です ※new.dskはマウントしているドライブであり、このあと作成するため現時点ではなくても問題ないです。

ISOとROM以外はRonald P. Regensburgさんが2024年2月28日に公開してくれており、今回は最新版であるVersion 2.5 Universal版20240228を利用します。Universal版のためIntel macでもM1 macでも動きます。

では実際にインストールしていきます

ダウンロードサイトから必要なものをインストールする

SheepShaver本体

Ronald P. Regensburgさんのフォーラムへの投稿からダウンロードできます。

• Version 2.5, 28 February 2024, universal (x86_64 and arm64) と書かれた下のDownload:から、zipファイルをダウンロードし、展開します。 この時点では起動しないでください。

SheepShaver Scripts

上記サイトの• For the above version 2.5 builds:と書かれた下のFor a new setup, also download the SheepShaver folder:から、zipファイルをダウンロードし、展開します。

MacOS ISO

本来であればDVD/CDにてISOイメージを取得する必要があるのですが、今回はこちらも有志のサイトよりISOイメージを拝借します。 今回はMacOS 9.0.4 のISOを利用します。以下サイトよりダウンロード可能です。

WinWorld: Mac OS 9 9.0

ページ下部、Downloadsの箇所にある、(ISO)と書かれたものをクリックし、遷移後のページでServer 1を選び(どちらでも良いです)クリックしてください。

すると7zファイルがダウンロードされるのでそれらを展開します。.isoと書かれたファイルが展開されればOKです。

MacOS ROM

以下サイトより、New World PPC ROMをダウンロード、展開します。名前はMacOS ROMに変更しましょう。 https://www.redundantrobot.com/sheepshaver

起動準備

上記ダウンロードしたものをApplicationsフォルダに「SheepShaver」フォルダを新たに作り、その中に以下の画像のように全部入れ込みます。

起動してみる

初期起動では、「?」と書かれたアイコンのみが表示されると思いますがこれで成功です。 ここまででうまくいかなかった場合は上記画像に従って適切にフォルダやファイルが配置されているか確認してください。

初期設定

初期設定を行います。SheepShaverを起動した後に左上の「SheepShaver」をクリックするとメニューが出てきます。 ここで「Settings...」をクリックしてください。

すると、Virutal Machine Settingsという画面が出てきますので、ここで各種設定を行います。

  • Volumes: インストール先のVolumeとISOメディアを指定します。ISOは「Add...」からFinderで選択、Volumeは「Create...」から選んでください
  • ROM File: 同じフォルダ下のROMファイルを「Browse...」からFinderで選択します
  • Unix Root: これはmacOSホストOSとエミュレータ上で共有化されるフォルダを指定します。エミュレータOS上ではデスクトップがこのフォルダに当たります。
  • Boot From: 初期は「Disable CD-ROM」のチェックを外し、RAMを512MB程度、「Boot form」を「Any」にしてください・
    • インストール後は「Disable CD-ROM」にチェックを入れ再起動します。

「Miscellaneous」と書かれた別タブに移動します ここで重要なのはEthernet Interfaceの項目です。ここには「slirp」と記入しましょう。

これで初期設定は完了です。Ctrl+Escを押してSheepShaverを終了し、再起動します。 以下のような画面が出れば成功です!

「Name: 」はボリューム名なので「mac」とかにしておくと良いでしょう。 このあとは「Initialize」を押し、出てきたインストーラーでMacOSをインストールし、Virtual Machine SettingsにてDisable ROMを有効化しボリュームディスクから起動すればOKです。

ここまででインターネット接続も完了します。(macOSがインターネットに繋がっていれば)

MacOS 9.0.4にNetscape Navigator 3をインストールする

やっと目的のNetscape Navigator 3をインストールできます。 以下URLからファイルをダウンロードします。未展開のまま、先ほどUnix Rootで設定したフォルダにおくことでデスクトップにファイルが追加されているはずです。あとはこれを解凍し、インストールするだけです。

https://www.macintoshrepository.org/2712-netscape-navigator-3-x-standard-gold-edition-

Netscape Navigator 3が立ち上がったよ!

ブラウザが立ち上がったので、http://example.comにアクセスして画面が出てくることを確認して終了です。

@kumikumitmさんに聞いたところによると、どうやらNetscape Navigatorはデフォルトグレー背景らしいです。知らんかった

最後とこれから

古のJavaScriptに触れる環境ができました。SheepShaverを使えばWindows 2000なんかも動くということで今後はActive Xなども触れていってみようと思います。 ムキムキマッチョマンに近づけたかな...?

参考記事

saturday-in-the-park.netlify.app