技術記事 by 岡部 健

明日のES Modulesを今日使おう!(esm ライブラリ開発者 @jdalton による解説記事の翻訳)



この記事はesmライブラリの開発者@jdalton自身による解説記事
https://medium.com/web-on-the-edge/tomorrows-es-modules-today-c53d29ac448c
を本人の許可と協力を得て翻訳したものです。

ES Modules(ESM)の解説も含め、前回のブログ記事:
2018年9月時点のJavaScriptモジュール(ES Module/ESM)界隈の最新情報、これまでの経緯とこれからの見通しを解説
もあわせて読むとより全体像がつかみやすくなると思います。


オリジナル記事著者:

Go to the profile of John-David Dalton

John-David Dalton

JavaScript思想家, バグフィクサー & ベンチマークランナー • lodash開発者 • 前職 Chakra Perf PM • 現在 Web Apps & Frameworks PM @Microsoft  主張は個人の見解です。

オリジナル記事投稿日 3月29日

Tomorrow’s ES Modules Today!(明日のES Modulesを今日使おう!)

⚵ より深く知るには Node Module Summit videoをチェック

7ヶ月前、 私はNodeでESモジュールを有効にできる実験的なモジュールローダをリリースしました。100万を超えるダウンロード、数千のコミット、そしてJavaScriptコミュニティのアーリーアダプター達のとてつもない援助を経て、安定版リリースの準備が整いました!🎕🎕🎕

esmを紹介しましょう ー 高速でプロダクション(本番)利用可、パッケージ依存なしのESモジュールローダで、Node 6+で利用可能、素晴らしい開発者体験をもたらします!

これまでの環境のままで、開発者は好みのツールのオプションに “require” オプションをつけることで、 容易にESモジュールを有効に出来ます。

node -r esm  
mocha -r esm  
nyc -i esm  
webpack -r esm

AVA テストランナーはESMサポートのためにesmでdefer可能です。

加えて今回からは、パッケージ作者は以下のいずれかのコマンドを使用することによりesmが使えるパッケージを新規作成できます。

npm init esm (npm@6)
yarn create esm

-y フラグを活用することで、すべてのプロンプトに “yes”と答えられます

npx create-esm の使用例:esm有効化パッケージを新規作成している

Setting the Stage 舞台の前口上

esmを掘り下げる前に、あるバックストーリーを前口上させてください。

私は20年間JavaScriptを書いてきて、そのうち、オープンソースに参画して仕様を読んできたのが13年間です。 Web 2.0の時代に生きてきて、モダンなJavaScriptライブラリとフレームワークの誕生に貢献するために自身の役割を果たしてきました。JavaScriptのエコシステムでどのようなアプローチと姿勢がうまく機能して、どういうものが失敗して立ち消えになってしまのうかを眼の当たりにしてきました。

私はMicrosoftでtechnical program manager (PM) として6年間務めてきました。Chakra、MicrosoftのJavaScriptエンジンのperformance PMとして3年間務めた後、現在はWebプラットフォームチームのDeveloper Experiences PMです。Program management(プログラム管理)ではユーザーと共感し、ユーザの事情、機能要件、外部依存関係、潜在的なブロッカーを特定する必要があります。最初のアイデアから出荷されるコードまで機能を見守るために、チーム間、さらには企業間で作業する必要があります。

私はLodash JavaScriptユーティリティライブラリを作りました。LodashはUnderscoreライブラリのフォークとして始まりました。UnderscoreはNodeと同年にリリースされるとあっという間にそのデファクトユーティリティパッケージになります。3年後、私はLodashをリリースしますが、まったく何も継承することもなく、数百万のユーザに利用される最も依存される数が多いnpmパッケージに成長しました。 これを達成するには、開発者のプラクティスやアプローチはこちら側が修正していく問題として見なすべきではないというマインドセットが必要でした。エコシステムを押す代わりに、私は、彼らの様々なモジュールフォーマット、プログラミングスタイル、多様な環境設定をそのまま受け入れるようにしました。開発者達をブロックしてしまわないことで彼らの移行プロセスを苦痛のないものにしました。パフォーマンスクリティカルなシナリオについて改善し、開発をシンプルにさせました。信頼を養い、開発者がリーチしやすい何かを作ったのです。

これらの経験が、esmが互換性と相互運用性についてアプローチする方法を形成したのです。

Zero Configuration ゼロ・コンフィギュレーション

esm最初にリリースされたのは遡ること2017年8月ですが、そのときはNodeのESモジュールのフラグが外れるまで9ヶ月を残すのみでした。今、その8ヶ月後、NodeはESモジュールのフラグを外すことを暫定的にさらに9〜27ヶ月先延ばしにした上で、新しいNodeモジュールワーキンググループが形成 (私はメンバー) されました。そして、かつてのNodeロードマップは今後必ずしもその通りになるとは限りません。

現時点で「Nodeルール」に追従するのは、特にその仕様が未だ固まっていないような時は、正しい選択ではないように見えます。開発者はESMを選択し、すぐさまコーディングにとりかかれるようにすべきです。理想的には、ESMのサポートは、エコシステムが現在あるところに寄り添ったものでなければなりません。 esmは、ゼロコンフィギュレーションで可能な限りCommonJS (CJS) と 相互運用可能であるべきでしょう。今あなたが愛してやまないもの、アプリケーションパフォーマンスモニタ、バンドラ、 code coverage instrumenters、トランスパイラそしてタイプチェッカーは、引き続きそのままきちんと動作し続けるべきです。

NodeのESMプランでは今でも .mjsファイル拡張をモジュールパースのゴールを通知するためのデフォルト機構としています。しかし、Nodeの .mjs青写真は完全には書かれていないためJavaScriptエコシステムは、Babel 7やWebpack 4で見られるように責務としてかろうじて最小限の機能しかサポートしていません。 esmも追従して、すべてのesmオプションで.mjsを無効化してしまっています。これはつまり現状あなたが開発していくにあたり.jsがベストな選択であるということです。 esmは今日のESMから明日のESMへのブリッジです。 今後NodeのESMへの道筋が明確になっていけば、esmも開発者にその機能を解放するでしょう。

(*訳者注* 
@jdaltonに2018/09時点のNodeのESモジュールサポートの最新の状況を確認したところ、現在までさらに半年ほど、目に見えるような進展はないそうです。また今後、esmをNodeの標準ESモジュールローダとしてマージする心積もりはあるのか?という質問をしたところ、現状技術的にはマニュアルで esm をNodeにコンパイルすることは可能ではあるが、その心積もりはまるでなく、あくまでもこの記事で表明されている思想のとおり、仕様に沿った範囲で、移行パス、パフォーマンス、現実世界の利用シナリオに基づいて、引き続き改善を加え続ける、ということです。)

Mostly JavaScript is Mighty Good ほとんどがJavaScriptで書かれる事は大変素晴らしい

esmは完全にネイティブコードではなく、そのほとんどがJavaScriptで書かれていることから、本質的に劣っていると考えるかもしれません。しかし、ほとんどJavaScriptであることが、実は大きな強みとなっているのです。NodeのESMのサポートを追加するには、いくつかの外部のチームや標準化団体からの仕入れや協力が必要です。彼ら各々が異なるアジェンダ、優先順位、タイムラインを持っています。 NodeのESMサポートの統一されたビジョンに向けてすべての関係者を招集しようとするのは現実的ではありません。ほとんどJavaScriptであるということは、ESMのサポートが固まる間にesmはこれらの依存関係をゼロにする必要があり、他のアプローチよりも速い開発とより良いエコシステムのサポートを可能にします。これにより、esmをアンブロックするだけでなく、 vm.Moduleのようなネイティブヘルパーが利用可能になり次第活用できる自由度を与えます。ビルトイン機能をJavaScriptで記述することは何も新しいことではありません。Node自身のビルトインモジュールや、その現在進行系のESM関連はJavaScriptで書かれていますChakra, SpiderMonkeyV8のようなJavaScriptエンジンのパーツでさえ、セルフホストされたJavaScriptで記述されています。おそらくもっともエキサイティングなのは、esmがスタンドアロンのローダであるため、 ChakraCoreであってもJavaScriptエンジンを問わず動作可能であったり、極めて容易に Nodeに直接コンパイル可能であることでしょう。

Better than “Just works” 「ちゃんと動く」以上のこと

ESモジュールのシンタックスがあるのは素敵ですが、Nodeが仕事するために無くてはならないというものでもありません。適応させる障壁は驚くほど低い必要があり明確な恩恵が示されない限り、開発者はすでにこなれて確立しているCJSに固執してしまうことでしょう。これはつまり、 esm はESMに即座にシームレスに適応させる、それ以上のことをしなければいけないということです。

  • Resilient 堅牢性
    esm は独自のコンテクストで動作するのでプロトタイプやポリフィルの改竄に強いです。

  • Reduce pain points 苦痛なポイントを低減する
    esm はNodeのバージョン間APIの不一致加減を低減します。たとえば、require.resolverequire.resolve.paths はNode 8+での拡張ですが、Node 6では利用不能です。 esm を利用することで、たとえNode 6であってもこれらのAPIにアクセスできるようになります。

  • Improve performance パフォーマンスの向上
    esmエンジンコードキャッシュ を利用することで、あなたのアプリケーションのスタートアップタイムを改善させます。Parcel, Webpack, Yarn, そして数多くのElectronアプリケーションといったプロジェクトで今日から恩恵があります。

Powering-Up Developers 開発者をパワーアップさせる

esmは、モダンなシンタックスへの人工的な障壁を取り除き、開発者を増強するために存在します。

  • Full-stack フルスタック
    esmを使うことで開発者はサーバサイドとクライアントサイドの両方でESMを書けるようになります。例えば、esmSvelteコンポーネントのサーバサイドレンダリング を拡張しますし、 クロスプラットフォームアプリケーション(Electron)をすべてESMで完全に書くことを可能にします。(*訳者注* @jdalton によるESM版のelectron-quick-startが公開されているので、その具体的作法もつかめるはず)

  • Real-time リアルタイム
    Quokka.jsWallaby.js は、スクラッチパッドとテキストエディタと統合されたテスト環境を提供します、 VS codeのように。どちらのプロジェクトも、esmを利用することでさらなる面倒な手続き(ESMのみのローダーフック、MIMEタイプのジャグリング、またはコードベースのフォーク)なしで、リアルタイムのESMシンタックスのサポートができています。統合されたスクラッチパッドであるQuokka.jsでは、 esmはファイル拡張子なし、保存もされていないドキュメントの解析すらもサポートしています!

Pay it forward 事前に支払っておこう

私は、esmを開発している間ずっと、それが潜在的に他にインパクトを与える可能性について注視してきました。

  • Babylonで トップレベルのawaitをパースしてlintできるようにパッチ済み です。

  • Chakra, V8, JavaScriptCore,そして SpiderMonkey のProxy についてのいくつかの問題(issue)が、CJSモジュールの named exportsをサポートするための開発を通じて明らかになりました。

  • Nodeで --check--require オプションで問題なく動作するように パッチ済み です。

  • Nodeビルトインモジュール(*訳者注*fsなどのこと)にESM形式のnamed exportsがサポートされるように、esmの初期の実装に基づいてプルリクエストをしている最中(*訳者注*現在プルリクエストはマージ済み)です。

  • npm ES modules proposalNode モジュールワーキンググループの作成を促した)は、代替実装は可能であるとインスピレーションを与えるものとしてesmを取り上げています。

What’s Next 次は何か

esmは目出度く安定版リリースにはなりましたが、それでもまだ沢山すべきことがあります。

  • loader hooksの基礎はこれまでesmにあるので、Nodeの仕様が固まり次第、 esm は準拠します。

  • 私は、Nodeのバンドラ、 instrumenters、ローダそしてユーティリティの中心的パフォーマンスをJavaScriptエンジンがトラックできるNode tooling benchmarkの作成を任されています。

  • 私は、 npmでnpm init <create-pkg-name> が可能なようにチーム作りをしています!

  • 実験的WASMサポートが間もなく開始されます。wasmオプションを用いることで、CJSとESMの.wasm ファイルのロードが解禁されます!

これまで私は開発者たちのESMコードが きちんと動いた ときの彼らの感動を見てきましたし、esmがリファレンス実装として、そして何が可能なのか?を示す強力な実例として、貢献できることを願っています!


  • Go to the profile of John-David Dalton

    John-David Dalton

    JavaScript tinkerer, bug fixer, & benchmark runner • Creator of lodash • Former Chakra Perf PM • Current Web Apps & Frameworks PM @Microsoft. Opinions are mine.

2019年1月時点のJavaScriptモジュール(ES Module/ESM)界隈の最新情報、これまでの経緯とこれからの見通しを解説



具体的には、ES6(ES2015)より標準化されたimportexportをめぐる解説記事です。重要な割に日本語解説記事が大変少ないことと、いずれにせよこの手の記事は情報がすぐ古くなり賞味期限があるので、使い捨て記事、ナマモノ追加投入の意義があります。

そもそもモジュールとは?モジュール化することの重要性 世界はモジュールで溢れている

モジュール化 (Modularity)

1つの複雑なシステムを、機能完結的な部品と標準化された部品間インターフェースで構成すること。

単機能で独立した部品同士を組み合わせて全体システムを構成するという設計構想をモジュラー型アーキテクチャといい、システムをこうした部品(モジュール)に分割することをモジュール化といいます。

その対象は製品の物理的構造だけに留まらず、システム設計や生産工程、組織など多岐にわたります。

IT産業発展の原動力
パソコンはCPUやメモリ、ハードディスクなど標準化されたインターフェースによって接続されているモジュール化製品の典型といえます。

モジュール化は、(1)製品の複雑さを低減、(2)部品の組合せ自由度を向上、(3)設計変更時の局所的対応が可能といったメリット

USBインターフェイスで規格化されたUSB機器、PCならパーツの規格と、機能完結的かつ標準化された部品(モジュール)によるモジュール化は複雑なシステムを構築する際に当たり前のように採用されている手法です。

プログラミングとはそもそも単純な部品を組み立てていく作業であり、プログラミング言語であるJavaScriptもモジュール化が重要です。特に昨今、JavaScriptは大規模システムの構築に普通に利用されるようになりモジュール化は必須です。

ブラウザ戦争 混迷を極めるJavaScript界隈 node.jsとnpmの台頭 1990-

JavaScriptのモジュール化という超基本的な仕様の標準化がこれまで立ち遅れてきた理由は、JavaScriptがブラウザに付属してくるスクリプト言語である、という他に例を見ない特殊な事情によります。

ブラウザ戦争というIT界隈では悪名高い覇権争いがあり、JavaScriptの標準化は各ベンダーの政治的対立に翻弄され立ち遅れました。モジュール標準化もまとまらなかったということです。

  • 第一次ブラウザ戦争 (1990-2000年)
    Internet ExplorerかNetscape Navigatorの二択。 IEの勝利。

  • 第二次ブラウザ戦争 (2004-2014年)
    figure_1
    Mozilla Firefoxが2004年、Microsoft IEの完全かつ絶対的な市場支配に戦いを挑み、それから5年足らずでユーザー数を0人から数億人に伸ばすことに成功した。Googleも2008年、Chromeブラウザを発表して、それに続いた。Chromeは2012年にはFirefoxに追いついた。2014年には揺るぎない地位に納まったことで、第二次ブラウザ戦争は終結したとされる

2008年、GoogleはChromeのJavaScriptエンジンである、V8もブラウザから分離してオープンソースでリリースしています。これまでブラウザの付属物でしかなかったJavaScriptがブラウザとは独立してシステムのローカル環境で動作するようになったというのは結構大きな出来事で、2009年、V8をベースにイベント化された入出力を扱うJavaScript環境であるnode.jsがリリースされます。


node.jsは、非常に効率の良いWebサーバとしてサーバーサイドで活用されはじめると同時に、独自のモジュール/パッケージ管理システムであるnpmを発展させ(JavaScriptの標準仕様としてモジュールが存在しないので独自に発展させるしかしようがない)、2018年現在まで一大エコシステム・コミュニティを形成してきました。

2011- Browserifyの登場 “bundler”

JavaScriptのモジュール化の標準化が定まらない中、独自のエコを発展させたnodeベースの膨大なJavaScriptモジュール資産(npmエコ)をWebブラウザでも活用すべくBrowserifyが登場します。これは実際結構な力技で、当初私などはよくこんなハックが出来たなと衝撃を受けたものですが、npmの依存関係に従ってモジュールを単一のJSファイルにつなぎあわせる、というものです。現在は、webpackのほうが人気だとは思いますが、いわゆる"bundler"(バンドラ)と呼ばれるものの先駆的存在です。

2013- Reactの登場

Facebookはコンポーネントで仮想DOMを設計するReactをリリースします。Reactのコンポーネントはモジュールにそのまま呼応するので、Reactのドキュメンテーションではかなり早くからES6のimport/export準拠で書かれていました。ブラウザでモジュールが実装される前からこのようにES6準拠となるのは、同時期に台頭したトランスパイラ(Babel)と上記バンドラ(Browserify/webpack)に依存して技術を先取りできているからです。

従って、Reactなどの先進的なフロントエンド開発をする際には、もうトランスパイラとバンドラをセットで使うのがデフォという感じになっています。そして驚くべきことに、React開発陣が完全にこの大前提にたっているためにReactライブラリ自体をES6Module(ESM)の仕組みでimportさせるのにネイティブにESM対応モジュールをリリースしておらず、トランスパイラとバンドラにNPM用のモジュールを読ませて変換させるというリリースの仕方をしています。

現状、別に規格化されているわけでもなんでもないnpmというモジュール/パッケージ管理システムとそれを単一ファイルに統合するバンドラを前提にフロントエンド開発が当たり前のように行われている、というのは、すべてブラウザ戦争により標準化されたモジュール化が立ち遅れたことが原因で、なかなか不安定な過渡期であると言えます。

2014- ECMAScript標準化の加速

ブラウザ戦争が収束するのと並行して、ブラウザ世界でもJavaScriptの標準化= ECMAScript標準化が活発化していきます。

ES6(ES2015)ではようやくモジュールが標準化され、importexportの仕様が固まりました。今後も、 ES2015-2018と立て続けに続くようで標準化は順調に加速していくようです。

2018 すべてのモダンブラウザがES6-Module(ESM)を実装完了

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import#Browser_compatibility

compati.png

より関数型プログラミング的な、dynamic import(動的読み込み)がFirefoxにはまだ実装されていませんが、とりあえず基本的なモジュール化はモバイルも含めすべてのモダンブラウザ(EdgeじゃないIE除く)で実装完了されており、プロダクションレベルでも積極的に利用可能な情況になっています。

Webブラウザがモジュールをそのまま実行してくれるようになってくると(本来そうであるべき)、わざわざなんか面倒で複雑なバンドラって必要?ということになってきます。ReactのJSXをトランスパイルしなければいけないというのも、実はTypeScriptのTSXで書いていたらTypeScriptがやってくれるのでBabelというトランスパイラは不要とかいろいろすっきりしそうな気がします。

実際今、自分はいろいろ外部ツールを組み合わせてセットアップしないとWebアプリケーションが開発できないという複雑な情況をシンプルにするために、Reactアプリでも基本TypeScript(TSX)だけ、Babelとwebpackなしでそのままブラウザで展開するようにしています。

Screenshot from 2018-08-19 16-48-09.png
Screenshot from 2018-08-19 16-46-44.png

https://github.com/kenokabe/esm-bundlerless
https://github.com/kenokabe/esm-bundlerless-react

ESM/NPM(CJS)2つの互換性のないモジュールシステムの問題発生

2018年になって、ようやくモバイル含めてもうすべてのモダンブラウザがES6-Module(ESM)が普通に使えるようになった、素晴らしい。ではこれから書くライブラリはすべてESMで行こう!それならわざわざwebpackつかって面倒なセットアップと開発フローはなくて済むんでしょ?

現状はこういう流れになりつつあるのは間違いありません。それが本来の標準化されたモジュール化なのだから。

しかしここで問題はすでに確立されたnode.モジュールのnpmエコがあるということです。nodeのモジュールフォーマットであるCommonJS(CJS)ば後発のブラウザ標準のESMと互換性はありません。2つのメジャーなモジュールエコが互換性なく並立しているというのが現状です。

すでにnpmエコにおいてもコミュニティは積極的にimport/export準拠でライブラリ・パッケージをリリースしているのですが、それはもちろんwebpack/browserifyのバンドラが処理してくれるという前提で皆そうしているようです。nodeはそもそもが自前のCJSモジュールベースで実装されているわけで、本来互換性のないESM対応についてはチーム内でもなかなか意見がまとまらないようで現状も混迷を極めており、早急な進展も望めない情況のようです。

静かにデファクトスタンダードになりつつあるnodeとESMのブリッジesmライブラリ

このような混迷した情況の中、あまりまだ知られていない(少なくとも2018/9月現在、日本語解説記事はまるでヒットしない)のがnpm/yarnに新たに実装された以下のコマンドです。

npm

npm init esm

yarn

yarn create esm

https://docs.npmjs.com/cli/init
によると、

Create a new esm-compatible package using create-esm:

ということで、実態は、
npm init あるいはyarn create する際に、
https://npm.im/create-esm
のコードをフックして「esmに対応した」新しいnpmプロジェクトを作成します。
実際に作成したに新規npmプロジェクトのpackage.jsonを見てみると、

{
  "name": "my-esm-lib",
  "version": "1.0.0",
  "main": "index.js",
  "module": "main.js",
  "license": "MIT",
  "dependencies": {
    "esm": "^3.0.82"
  }
}

となっており、このパッケージの依存パッケージ(dependency)(ライブラリ)としてesmが自動的に追加されているのがわかります。

esmcreate-esmは、MicrosoftのDeveloper Experiences PMでありnpmエコの中でももっとも多く依存されているライブラリlodash(関数型プログラミングのライブラリ)の開発者でもあるJohn-David Dalton @jdaltonによって開発メンテナンスされています。

esmライブラリのダウンロード数は増加し続けており、コミュニティの支持とともに確固たる地位を獲得しているように見受けられます。

nodeとESMのブリッジesmライブラリの役割

じゃあ、実際esmって何ができるのか?

webpackがnode/npmモジュールをブラウザでも活用できるようにしたのと対照的に、esmはブラウザで標準化されたESMをnode/npmでも活用できるようにするブリッジである、と理解すれば良いでしょう。

今後のJavaScriptのフロントエンド、あるいはサーバーサイドの開発者の基本方針としては、ES6以降で標準化されているESMでモジュールを書いていく、しかし同時にnodeのエコでもそのESM資産を無駄なく流用活用できるようにesmでブリッジできるので一石二鳥だ、そういう感じです。

esm(ライブラリ)の2大機能とは、

  1. ESMをラップしてnode/npmエコでシームレスに扱えるnpmパッケージ化
  2. nodeコマンドにフックをかけて直接ターミナルからESMを実行可能

です。おおざっぱにそういう理解でいいでしょう。

この(1)がまさに上で引用した

npm init esm

によってesmパッケージ依存込みで自動生成されるプロジェクトのテンプレです。

実際に作成されたpackage.jsonでは

  //...
  "main": "index.js",
  //...

と、index.jsがパッケージの起点となっており、その内容は以下のとおり自動生成されています。

index.js
require  =  require("esm")(module/*, options*/)
module.exports  =  require("./main.js")

通常のCJSのrequireは一旦("esm")関数でフックをかけられることで、esmの文脈に変換された上で再定義されています。

再定義されたrequireはESMファイルを読み込み解釈できるので、./main.jsにはESMそのものずばりのコードを書けば良い、という仕組みです。

main.js
// ESM syntax is supported.
export {}

実際の利用例

実際の例として、前回のエントリ### JavaScript/TypeScriptに自己参照する「型」(type)を与えるtypeselfnpmパッケージとして公開したばかりですが、上記のESM互換の手順でプロジェクトを作成しています。

https://github.com/kenokabe/typeself

本体は、
./dist/build/modules/typeself.js
にESMとして書かれており、依存モジュールであるESM
./dist/build/modules/primitive-obj.js
と共に、ブラウザ内のESMのimportとしてやればそのまま動作します。
https://github.com/kenokabe/typeself-dev/tree/master/dist/build

そして同時に、./package.jsonで起点と指定される./index.jsでは、

require = require("esm")(module/*, options*/)
module.exports = require("./dist/build/modules/typeself.js")

と本体のESMへesmフックをかけていて、あくまでCJSのmodule.exportsとされており、通常のnpmパッケージとしてnodeから利用可能です。

さて上記(2)について、

./dist/build/test/test-typeself.jsというテストコードもESMとして記述されていますが、

$ node -r esm ./dist/build/test/test-typeself.js

とesmフックをかけたnodeコマンドでESMがシームレスにターミナル上で実行できてしまいます。

  1. パッケージ内でESMへフックをかけてCJS/npmパッケージ化できてしまう、
  2. ESM単体でもターミナルからnodeコマンドにフックをかけて直接実行可能、

と、もの凄く洗練された設計と実装となっています。

次のエントリではesm開発者の@jdaltonのブログ記事を翻訳して公開

実は、そろそろESMの開発環境を整えようと、上記の「Reactアプリでも基本TypeScript(TSX)だけ、Babelとwebpackなしでそのままブラウザで展開」するための開発ツール
https://github.com/kenokabe/esm-bundlerless
https://github.com/kenokabe/esm-bundlerless-react
Electronをベースに構築しようとしていた時に、「Electronっていうのは、Chromiumブラウザとnodeランタイムのハイブリッド環境なので両方の技術おいしいとこどりでなんでも簡単にできるはず」とタカくくっていたところ、単純にやっぱりnodeではESMは扱えない事実が判明していたのでした。

すでに書いた通り、node組み込みのESMローダーはまったく迷走しているし、どうしたものかと、electron/node界隈を調査していると
Contexts: supporting new Node’s ESM Loader (without hacking)というIssueにたどり着き、同じように文句垂れている人を見かけたので、自分も便乗して「同意見だ」などと長文で遠回しに文句垂れていたところ、@jdaltonが「とりあえずesmみたいなものがある、これならElectronのmain/render両方のプロセスでも一貫性のあるESMの利用ができる」と親切に教えてくれたので、見てみると、英語圏でも知られているようでまだそれほど知られているわけではなさそうなesmですが、これがもの凄いハックで、はじめてBrowserifyというバンドラを見たときと同じくらい衝撃を受けました。それがesmのことを知った経緯です。

そもそもElectronとはGitHub製のAtomEditorのガワ部分が独立して公開されていたもので、先日Microsoftが自社製のVisualStudioCodeの土台にもなっているElectronと一緒にGitHubを買収してしまったので、今現在、ElectronはMicrosoftの資産となっています。その流れか、前からかは知りませんが、MicrosoftのPMの@jdaltonもElectronの開発メンバーになっているのでIssueをWatchしていたのでしょう。

彼はnode/moduleの策定メンバーにもなっているようなので、「今後esmをnodeのデフォルトESMローダーとしてマージする心づもりなのか?」と質問しましたが、そのつもりは全く無いようです。彼のブログを熟読すると彼の志向はどの開発環境、開発スタイルにでも馴染むような汎用的なライブラリ(lodashもたしかにそんな感じだ)の作成で、スタンダードに馴染み、開発者から自然に選択されるデファクトスタンダードを目指しているようです。

ということで、今回の記事では、筆者がES Module/ESM界隈の最新情報、これまでの経緯とこれからの見通しを俯瞰、そして勝手にesmの解説もしましたが、やはり開発者自身の設計思想も含めて理解できる一次ソースに勝る情報はないと思うことと、とても重要な文章だと思うので日本語圏の開発者がよりリーチしやすいように日本語でシェアするために、@jdaltonの許可と協力を得ながら、彼のブログ記事を翻訳公開したいと思います。

↓ 次に読む

明日のES Modulesを今日使おう!(esm ライブラリ開発者 @jdalton による解説記事の翻訳)