ES Module で読み込んだ関数は window オブジェクトに入らない

ES Module(type="module" を指定したスクリプト)で読み込んだ関数やトップレベルの変数は、window オブジェクトに追加されない。これは従来のスクリプトとの大きな違い。

従来のスクリプト(非モジュール)では、トップレベルで宣言した変数や関数はグローバルスコープに置かれ、window オブジェクトのプロパティとしてアクセスできた。

// 従来のスクリプト(type="module" なし)
function greet() {
  console.log('Hello')
}
var name = 'Alice'

console.log(window.greet) // function greet() {...}
console.log(window.name)  // 'Alice'

一方、ES Module ではトップレベルの宣言がモジュールスコープに閉じ込められる。

// ES Module(type="module" あり)
function greet() {
  console.log('Hello')
}
const name = 'Alice'

console.log(window.greet) // undefined
console.log(window.name)  // undefined

この仕様により、モジュール間での意図しない名前衝突を防げる。複数のモジュールが同じ名前の関数や変数を定義しても、互いに干渉しない。

グローバルに公開したい場合

どうしても window オブジェクトに関数を登録したい場合は、明示的に代入する。

function greet() {
  console.log('Hello')
}

window.greet = greet

ただし、この方法はモジュールの利点を損なうため、通常は import/export を使ったモジュール間のやり取りが推奨される。