きっかけ
-
tsconfig.json
で定義する"ESNext"
はなんだろう?他の選択肢はあるのか?と疑問に思い調べ始めたことがスタート
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext", // これはなんのため?🤔
"strict": true
}
}
結論
-
"module": "ESNext"
は「最新のES20XX
を自動で追ってくれるモジュールの設定方法」である- フロントエンド/バックエンドで
JavaScript
を使いたい場合には、"module": "ESNext"
を設定しておけば良い(React
を使って開発する時など)と理解✨
- フロントエンド/バックエンドで
「なるほど!そういうことか!」と理解できたJavaScriptの歴史(一部)の流れ
深掘りしていくうちにJavaScript周辺の歴史が少し理解できた。
-
JavaScript
は元々ブラウザが理解できるフロントエンド専用の言語- 🙏サーバーサイドは
PHP
、Java
、Python
などを使ってね! - 😇モジュール化のように部品として使おうという概念がなく全部グローバルで管理
- DOMを直接操作するような再現性の低い表現(読みづらくバグも発生しやすい)
- 🙏サーバーサイドは
-
JavaScript
をサーバが理解できる通訳者として出てきたのがNode.js
(2009年)- 😆
JavaScript
をサーバでも使えるようにしたよ!(フロントエンド/バックエンドが同一の言語で書けるようになる) - 😆
CommonJS
というモジュール化できる仕組みでNode.js
を表現できたよ!- 😇だけど
Node.js
(CommonJS
)vs ブラウザ(グローバル変数)で分断している状態
- 😇だけど
- 😆
- フロントエンド/バックエンドを統一の書き方でモジュールできる
ES Modules
が爆誕🎉- 2015年策定、2017年頃:ブラウザが対応開始、2018年頃:本格的な普及開始
-
ES Modules
にはTreeShaking
(未使用のコードの削除)が可能になる等のメリットもあり
-
ES Modules
ではESXX
と年で変化があるたびにモジュールを更新していくのがしんどい- 例えば
"module": "ES2020"
と定義したら追従するのは"ES2020"
- 常に最新の
ESXX
を追っていってくれるモジュールを作りましょう!→"ESNext"
爆誕 - どちらも
import
やexport
など書き方は同じ。tsconfig.json
でどう定義するかどうかだけ-
tsconfig.json
も最終的にJavaScriptに変換するのでTypeScript
で進める場合には、module設定はtsconfig.json
で定義すればおけ
-
- 例えば
- 現在では
JavaScript
をサーバーサイドで動かすための通訳者として、Bun
やDeno
も出てきた-
React
でのモジュール指定は"module": "ESNext"
と定義すれば良さそうと理解!✨-
ES Modules
がReact
エコシステムの爆発的成長を支えている -
Vite
やTypeScript
では"ESNext"
で最新のESXX
を前提としている機能もあり、"ES2022"
などではなく自動で追従してくれる"ESNext"
の方がよき
-
-
参考1:module
設定自体はいろんな選択肢がある
ES Modules系(汎用的・モダン)
{
"module": "ES6" // ES2015と同じ
"module": "ES2015" // 最初のES Modules
"module": "ES2017"
"module": "ES2018"
"module": "ES2020"
"module": "ES2022"
"module": "ESNext" // 最新 // React、Vue、Angularなど
}
CommonJS系(Node.js専用)
{
"module": "CommonJS" // Node.js標準 // 古いNode.jsアプリ
"module": "Node16" // Node.js 16対応
"module": "NodeNext" // Node.js最新 // 新しいNode.jsアプリ
}
その他(特殊用途)
{
"module": "AMD" // ブラウザ用(古い)
"module": "UMD" // Universal(両対応)
"module": "System" // SystemJS用
"module": "None" // モジュールなし
}
参考2:Modules系とCommonJS系の書き方の違い
ES Modules(フロントエンドでもバックエンドでも統一された書き方)
// utils.js
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }
// app.js(フロントエンドでもバックエンドでも同じ!)
import { add } from './utils.js';
console.log(add(1, 2));
// 🎉 Tree Shaking: subtractは自動削除される
// 🎉 同じ書き方でブラウザでもNode.jsでも動く
CommonJS(Node.js専用)
// utils.js
function add(a, b) { return a + b; }
function subtract(a, b) { return a - b; }
module.exports = { add, subtract };
// app.js(Node.jsでしか動かない)
const { add } = require('./utils');
console.log(add(1, 2));
// ❌ Tree Shaking困難: 全部のコードが残る
// ❌ ブラウザでは動かない