グローバル変数の衝突でエラーが発生したけど type="module" で解決できた
どういうことがあったか
すでに運用されているサイトの一部のページを制作することになり、
自分が作成したJSとは別に、サイト共通で使用されているJSも読み込む必要があった。
<script src="/common.js"></script><!-- 共通ファイル -->
<script src="/new/script.js"></script><!-- 自分が作成した新ファイル -->
これらのJSファイル間で変数名が衝突してしまい、結果としてエラーが発生してしまっていた。
// /common.js
const a = 123;
// /new/script.js
const a = "abc";
※上記あくまでイメージ。
共通ファイルを変えてもらうわけにもいかず、
新ファイルのほうの原因である変数はnpmパッケージで使われているもので、簡単に変更することもできない。
解決:type="module"
結論としては、以下のように新ファイルの読み込みに type="module"
を追加して解決しました。
(共通ファイルの読み込みについては、予期せぬところで影響があっては困るのでそのままとしました。)
<script src="/common.js"></script>
<script src="/new/script.js" type="module"></script>
type="module"
(JavaScript モジュール)とは
script
タグに type="module"
を指定することで、読み込むファイルはJavaScript モジュールとして扱われます。
module: コードを JavaScript モジュールとして扱います。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/script#attr-type
JavaScript モジュールは、 import
と export
文を用いてインポート・エクスポートができる形式です。
モジュールスクリプトの通常のスクリプト(クラシックスクリプト)の違いのうち、今回重要なのはこの部分です。
最後ですが重要なこととして明らかにしておきますが、モジュールの機能は単独のスクリプトのスコープにインポートされます。つまり、インポートされた機能はグローバルスコープから利用することはできません。それゆえ、インポートされた機能はインポートしたスクリプトの内部からしかアクセスできず、例えば JavaScript コンソールからはアクセスできません。文法エラーは開発ツール上に表示されますが、使えることを期待するデバッグ技術の中には使えないものがあるでしょう。
宣言された変数や関数のスコープが閉じられており、グローバルスコープの変数や関数と衝突することがないのです。
かなり重要なことなのに今回始めて知りました。
今後はグローバル汚染を避けるために、自分が設置するscriptタグには基本的に type="module"
をつけておこうと思いました。
Author And Source
この問題について(グローバル変数の衝突でエラーが発生したけど type="module" で解決できた), 我々は、より多くの情報をここで見つけました https://zenn.dev/kagan/articles/731ca08f45b8c1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol