動的インポート(import())で別ファイルを読み込んだ場合、同名の関数があっても衝突しない。各モジュールは独立したスコープを持ち、インポート時に明示的に名前を指定するためである。
// moduleA.js export function process() { return 'A' } // moduleB.js export function process() { return 'B' } // main.js const modA = await import('./moduleA.js') const modB = await import('./moduleB.js') console.log(modA.process()) // 'A' console.log(modB.process()) // 'B'
動的インポートは Promise を返し、解決されるとモジュールの名前空間オブジェクトが得られる。このオブジェクトを通じてエクスポートされた関数にアクセスするため、同名であっても別々の変数に格納すれば問題ない。
同じ変数に代入すると上書きされる
同じ変数に代入すれば後からインポートしたものが残る。
let mod = await import('./moduleA.js') console.log(mod.process()) // 'A' mod = await import('./moduleB.js') console.log(mod.process()) // 'B'
これは衝突ではなく、単なる変数の再代入である。
分割代入での注意点
分割代入を使うと、同じスコープ内で同名の変数を宣言できない。
const { process } = await import('./moduleA.js') const { process } = await import('./moduleB.js') // SyntaxError
この場合はエイリアスを使う。
const { process: processA } = await import('./moduleA.js') const { process: processB } = await import('./moduleB.js') console.log(processA()) // 'A' console.log(processB()) // 'B'
ES Module の設計上、名前空間が分離されているため、インポート側で適切に変数名を管理すれば衝突は起きない。