We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
これをお読みの皆さんの中には、JavaScriptやTypeScript以外のプログラミング言語を経験したことがある人もいるかと思います。他の言語で、複数のモジュールシステムが共存している言語を使ったことはありますでしょうか。
JavaScriptには、系統が異なるモジュールシステムが、少なくとも2つ存在しています。ESモジュールとCommonJSです。こうした状況は、プログラミング言語としては、珍しいことです。JavaScriptのモジュールまわりを理解するのを難しくしている要因でもあります。
では、どうしてJavaScriptは2系統もモジュールシステムを持つようになったのでしょうか? ここでは、JavaScriptの現状に至る流れを歴史からひも解いていきます。
JavaScriptのモジュールシステムは、ブラウザよりも先んじて、サーバーサイドJavaScript、とりわけNode.jsの文脈で発展してきた経緯があります。
JavaScriptで広く普及しているモジュールシステムのひとつがCommonJSです。CommonJSの歴史をさかのぼると、2009年のServerJS発足に至ります。ServerJSはJavaScriptをサーバーサイドで使えるようにすることを目指し、サーバーサイドJavaScriptの共通APIを策定する標準化プロジェクトでした。のちに、CommonJSに改名されます。
サーバーサイドにJavaScriptを持ってくると一言で言っても、ブラウザのJavaScriptをそのまま持ち込んでもうまくいきません。たとえば、ブラウザには<script>タグがあるので、ひとつのページに複数の<script>タグを書くことで、複数のJavaScriptが実行できます。一方、サーバーサイドにはページという概念がありません。
<script>
また、当時のJavaScriptにはESモジュールのようなモジュールシステムもありませんでした。そのため、JavaScriptファイルを複数ロードできる仕組みを考えるところから始めなければなりませんでした。
そこで考え出された仕様がCommonJSのモジュールです。おなじみのrequire()やmodule.exportsです。CommonJSは、モジュールシステムが存在しない当時のJavaScriptの文法や機能の枠を超えずに、関数や変数で工夫することで、モジュール的なものを成立させるものでした。
require()
module.exports
Node.jsはCommonJSと同時期にリリースされましたが、Node.jsに採用されたモジュールシステムがこのCommonJSでした。このおかげで、Node.jsにおいてはサーバーサイドJavaScriptでもファイルの分割と、複数ファイルのロードができるようになっていました。このモジュールシステムは、Node.jsユーザーに受け入れられはじめ、ライブラリを公開できるnpmなど、モジュールまわりのエコシステムも発展していきました。
ちなみに、CommonJSやNode.jsがスタートした2009年の前年には、ECMAScript 4草案破棄というショッキングな出来ごとがありました。ES4には、モジュールシステムをJavaScriptに追加する仕様も盛り込まれていました。もし、ES4が実現していたら、CommonJSは必要無かったかも知れません。現実はESの仕様を決めるブラウザベンダー間での意見と対立があり、JavaScriptを改善する動きは仲たがいで終わってしまいました。
Node.jsの登場時期がそんなバッドタイミングだったこともあり、JavaScript自体がモジュールシステムを改善するのはなかなか期待できない状況でした。そのため、Node.jsは既存のJavaScriptでできる範囲内の解決策として、モジュールシステムにCommonJSを採用したという見方もできます。
CommonJSはサーバーサイドで生まれ、発展してきました。CommonJSの土台に乗ったライブラリも数多く作られました。こうしたライブラリは、クライアントサイドでも需要がありました。そのため、webpackを筆頭にモジュールバンドラーはCommonJSをサポートしてきました。CommonJSの生い立ちはサーバーサイドではあったものの、モジュールバンドラーの対応によって、フロントエンドもCommonJSに頼る状況が醸成されました。
CommonJSの誕生から歴史は流れ、2015年になると、ES6という新しいJavaScriptの標準仕様が確定します。これはJavaScriptの10年数ぶりの大型アップデートです。そこには、ES6 Modulesというモジュールシステムを実現するための仕様も盛り込まれていました。皆さんご存知のimport文とexport文です。これは、JavaScript初のJavaScriptネイティブのモジュールシステムです。CommonJSが草の根活動で規格化されたモジュールシステムだとすると、ESモジュールは本家が発表した公式的・標準的なモジュールシステムだとも言えます。
import
export
JavaScript界は、サーバーサイドもクライアントサイドも関係なく、ES6に対応する中で、ES6 Modulesも導入する方向になり、2016年頃からESモジュール導入に向けて議論が始まりました。議論の中心は、やはり、在来のモジュールシステムであるCommonJSと新システムのESモジュールの共存についてです。
ESモジュールの仕様が確定する頃には、JavaScriptはCommonJS前提とした環境ができあがっていて、CommonJSに準拠したNPMパッケージも沢山あったため、CommonJSを切り捨てる選択肢はありませんでした。もしも、CommonJSを切り捨ててしまうと、過去の資産をほぼすべて失うことになるわけで、CommonJSとESモジュールの共存はNode.jsにとって重要なテーマだったのです。
例えば、サーバーサイドJavaScriptのNode.jsひとつとっても、長い議論のすえ、2017年にNode.js v8.5.0にて、ESモジュールが実験的な機能としてリリースされます。その後、2019年にv13.2.0にて、ESモジュールから「実験的な機能」というラベルが外れ、プロダクションで使われることを想定した機能に昇格しました。そして2020年には、CommonJSの名前付きエクスポートがESモジュールの名前付きインポートでロードできるようになり、次第にNode.jsでESモジュールを動かす環境が整ってきています。
ESモジュール環境が整備されてきたとは言っても、CommonJSは10年以上、JavaScriptを支えてきており、もはや切っても切れない関係になっています。そのため、今日現在においては、2つのモジュールシステムがJavaScriptに生きているわけです。
The text was updated successfully, but these errors were encountered:
docs: 📚 モジュール草稿の途中経過を追加しました。
90c6381
Refs: #129 Closes: #529 #527 #520 #530
Successfully merging a pull request may close this issue.
これをお読みの皆さんの中には、JavaScriptやTypeScript以外のプログラミング言語を経験したことがある人もいるかと思います。他の言語で、複数のモジュールシステムが共存している言語を使ったことはありますでしょうか。
JavaScriptには、系統が異なるモジュールシステムが、少なくとも2つ存在しています。ESモジュールとCommonJSです。こうした状況は、プログラミング言語としては、珍しいことです。JavaScriptのモジュールまわりを理解するのを難しくしている要因でもあります。
では、どうしてJavaScriptは2系統もモジュールシステムを持つようになったのでしょうか? ここでは、JavaScriptの現状に至る流れを歴史からひも解いていきます。
ひとつめのモジュールシステム
JavaScriptのモジュールシステムは、ブラウザよりも先んじて、サーバーサイドJavaScript、とりわけNode.jsの文脈で発展してきた経緯があります。
JavaScriptで広く普及しているモジュールシステムのひとつがCommonJSです。CommonJSの歴史をさかのぼると、2009年のServerJS発足に至ります。ServerJSはJavaScriptをサーバーサイドで使えるようにすることを目指し、サーバーサイドJavaScriptの共通APIを策定する標準化プロジェクトでした。のちに、CommonJSに改名されます。
サーバーサイドにJavaScriptを持ってくると一言で言っても、ブラウザのJavaScriptをそのまま持ち込んでもうまくいきません。たとえば、ブラウザには
<script>
タグがあるので、ひとつのページに複数の<script>
タグを書くことで、複数のJavaScriptが実行できます。一方、サーバーサイドにはページという概念がありません。また、当時のJavaScriptにはESモジュールのようなモジュールシステムもありませんでした。そのため、JavaScriptファイルを複数ロードできる仕組みを考えるところから始めなければなりませんでした。
そこで考え出された仕様がCommonJSのモジュールです。おなじみの
require()
やmodule.exports
です。CommonJSは、モジュールシステムが存在しない当時のJavaScriptの文法や機能の枠を超えずに、関数や変数で工夫することで、モジュール的なものを成立させるものでした。Node.jsはCommonJSと同時期にリリースされましたが、Node.jsに採用されたモジュールシステムがこのCommonJSでした。このおかげで、Node.jsにおいてはサーバーサイドJavaScriptでもファイルの分割と、複数ファイルのロードができるようになっていました。このモジュールシステムは、Node.jsユーザーに受け入れられはじめ、ライブラリを公開できるnpmなど、モジュールまわりのエコシステムも発展していきました。
ちなみに、CommonJSやNode.jsがスタートした2009年の前年には、ECMAScript 4草案破棄というショッキングな出来ごとがありました。ES4には、モジュールシステムをJavaScriptに追加する仕様も盛り込まれていました。もし、ES4が実現していたら、CommonJSは必要無かったかも知れません。現実はESの仕様を決めるブラウザベンダー間での意見と対立があり、JavaScriptを改善する動きは仲たがいで終わってしまいました。
Node.jsの登場時期がそんなバッドタイミングだったこともあり、JavaScript自体がモジュールシステムを改善するのはなかなか期待できない状況でした。そのため、Node.jsは既存のJavaScriptでできる範囲内の解決策として、モジュールシステムにCommonJSを採用したという見方もできます。
CommonJSはサーバーサイドで生まれ、発展してきました。CommonJSの土台に乗ったライブラリも数多く作られました。こうしたライブラリは、クライアントサイドでも需要がありました。そのため、webpackを筆頭にモジュールバンドラーはCommonJSをサポートしてきました。CommonJSの生い立ちはサーバーサイドではあったものの、モジュールバンドラーの対応によって、フロントエンドもCommonJSに頼る状況が醸成されました。
ふたつめのモジュールシステム
CommonJSの誕生から歴史は流れ、2015年になると、ES6という新しいJavaScriptの標準仕様が確定します。これはJavaScriptの10年数ぶりの大型アップデートです。そこには、ES6 Modulesというモジュールシステムを実現するための仕様も盛り込まれていました。皆さんご存知の
import
文とexport
文です。これは、JavaScript初のJavaScriptネイティブのモジュールシステムです。CommonJSが草の根活動で規格化されたモジュールシステムだとすると、ESモジュールは本家が発表した公式的・標準的なモジュールシステムだとも言えます。JavaScript界は、サーバーサイドもクライアントサイドも関係なく、ES6に対応する中で、ES6 Modulesも導入する方向になり、2016年頃からESモジュール導入に向けて議論が始まりました。議論の中心は、やはり、在来のモジュールシステムであるCommonJSと新システムのESモジュールの共存についてです。
ESモジュールの仕様が確定する頃には、JavaScriptはCommonJS前提とした環境ができあがっていて、CommonJSに準拠したNPMパッケージも沢山あったため、CommonJSを切り捨てる選択肢はありませんでした。もしも、CommonJSを切り捨ててしまうと、過去の資産をほぼすべて失うことになるわけで、CommonJSとESモジュールの共存はNode.jsにとって重要なテーマだったのです。
例えば、サーバーサイドJavaScriptのNode.jsひとつとっても、長い議論のすえ、2017年にNode.js v8.5.0にて、ESモジュールが実験的な機能としてリリースされます。その後、2019年にv13.2.0にて、ESモジュールから「実験的な機能」というラベルが外れ、プロダクションで使われることを想定した機能に昇格しました。そして2020年には、CommonJSの名前付きエクスポートがESモジュールの名前付きインポートでロードできるようになり、次第にNode.jsでESモジュールを動かす環境が整ってきています。
ESモジュール環境が整備されてきたとは言っても、CommonJSは10年以上、JavaScriptを支えてきており、もはや切っても切れない関係になっています。そのため、今日現在においては、2つのモジュールシステムがJavaScriptに生きているわけです。
まとめ
The text was updated successfully, but these errors were encountered: