js-primer
js-primer copied to clipboard
Node.js ESMの対応
概要
Node.jsのLTSはESMをネイティブサポートしているので、Node.jsでCLIアプリの章をESMベースに書き直したい。 しかし、現状のNode.js ESMは色々中途半端な部分があって完全に切り替えるかが迷いどころ。
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
refs Pure ESM package
#1337 ES2022の対応と合わせてやりたいので、大体2022年6月ぐらいまでに完了させたいイメージ。
Node.jsでのESMの現状
今Node ESMを扱う問題は
- CommonJSとESMどっちで書くか迷う
- 使ってるライブラリがPure ESMのみかどうか(CJSからimport()が必要、ESMの場合も
type:module
かmjsが必要で一手間) - いろいろなイディオムを覚える必要あり(
__dirname
とか、resolve
とか普通に使えて欲しいものも、今はイディオムがいる) - Node ESMを扱えないツールが多い(CJS + TSで書かないとフラストレーションがある)
今Node ESMを扱うべき理由は
- 将来的にCJSじゃなくてESMになるのは明白
- Pure ESMなモジュールを扱うには、ESMで書いた方が楽
- ESMなCDN、Deno、Webとの相性が良い
直接Node.jsでJavaScriptを書くならESMでなんとかなるけど、 他のツールを使おうとすると結構ハマり所があると言うのが所感。
CLIの章をESMにする場合に決めないといけないこと
- CommonJS の扱いをどうするか
- CommonJS(require/exports)自体は無くならないので、どっかで触れる必要がある。
- XHRの時みたいにコラムサイズで収まるかは不明
- 利用してるパッケージのESM対応調査
- [x] Marked: v4.0.0で対応、Dual Modules
- [ ] Commander.js はCJSのまま
- [x] Mocha: v9.0.0で対応、本体はCJSのまま
ESMからCJSとESMは特に問題なくimportできるinteropがNode.jsにはあるはずなので、パッケージ自体が対応してるかはあんまり気にしなくていいけど一応(mochaだけは対応が必須ではあるけど、対応してたので問題ないはず)
その他 関連する変更
- Node.js LTS 16へのアップデート
- npm 7へのアップデート(新規作成のみなのでほぼ影響ない? このリポジトリ自体を更新する感じ)
-
node:
prefix module New in Node.js:node:
protocol imports
大まかな方針としては、次のやり方が考えられそう
- ESMで書き直して、ESMをベースにしてCJSについては補足程度にする
- CJSは補足程度で済むのかが怪しい。現状はデファクトであることには変わらない
- 全体的に書き直し
- CJSで書いて、最後にESMに直してみましょうみたいリファクタリングをする方向で追加する
- 利用してるパッケージは幸いCJS or dual moduleなのでコードの変更のみでいいはず
- 最後に1セクション追加するようなイメージ
- ベースはCJSのままにして、現在のNode.js("node": "^12.20.0 || ^14.13.1 || >=16.0.0")ではESMも扱えるよと補足する
- 一番変更が少ないような方針
@lacolaco どうするのがよさそうですかね?
理想的には1かなーと思いますが現実問題CJSの話がどれくらい必要になるか確かめてみて次第ですかね 年末に調べてみますが、CJSが捨てられるのはまだ先だろうし3を選んでもいい時期でもありそうです
例えばnode-fech v3はESMになりましたがそれに依存するgaxiosは当面移行する気なさそうですね。 https://github.com/googleapis/gaxios/issues/445 https://github.com/googleapis/gaxios/issues/429
Marked ReDoSの脆弱性修正が入ったので、今のバージョンだとnpm install時に警告出ちゃうようになるかなー #1375 #1376
ベースはCJSのままにして、現在のNode.js("node": "^12.20.0 || ^14.13.1 || >=16.0.0")ではESMも扱えるよと補足する
一旦、3で進めるかなー
Node.js 16のLTSが今年の後半だから、npm 8の対応はやっておかないといけないのか。 Node ESMに関しては特に変わらないけど。 https://nodejs.org/en/about/releases/
https://deploy-preview-1457--js-primer.netlify.app/use-case/nodecli/argument-parse/#commonjs-module
このユースケースで今後登場するモジュールはすべてCommonJSモジュールです。 Node.jsではES Moduleもサポートされる予定ですが、現在はまだ安定した機能としてサポートされていません。
これを書き換える必要はある。
1 の方針でやる。