Tern Systems, here is a thoughtful answer for that Stack Overflow question:
Short Answer
In modern JavaScript modules (<script type="module">
), variables are scoped to the module itself and are not automatically attached to the global object (window
). Consequently, code in a non-module script cannot directly access variables imported or declared in a module script. You need to explicitly export them from your module or attach them to the global object if you want to share them with non-module scripts.
Detailed Explanation
Module Scope Isolation
When you use <script type="module">
, any variables, classes, or functions declared within that script are module-scoped. They do not leak into the global scope the way variables in normal <script>
blocks do. This design prevents unexpected collisions and promotes better encapsulation.
Why You Can’t Access Module Variables in Non-Modules
window
object, which by default only contains variables declared in global scope.How to Expose Variables from a Module
If you want non-module scripts (or the global scope) to see your module’s variables:
window
object
// Inside your module:
const myValue = 42;
window.myValue = myValue;
Now a non-module script (or even inline code in the HTML) can do:
console.log(window.myValue); // 42
// moduleA.js
export const myValue = 42;
<!-- moduleB -->
<script type="module">
import { myValue } from './moduleA.js';
console.log(myValue); // 42
</script>
Ensure Consistent Script Types
Practical Recommendations
Convert Dependent Scripts to Modules
Whenever possible, convert all <script>
tags to type="module">
. This way, you can leverage JavaScript’s native module system, using export
and import
as intended.
Use the Global Object Only When Necessary
If you genuinely need global access—like for a quick proof of concept—attaching to window
is a simple approach. However, from a design standpoint, global variables can lead to naming collisions and maintenance issues. Use them judiciously.
Check Browser Support
Most modern browsers fully support <script type="module">
, but you might need to transpile or use polyfills for older environments. Keep that in mind if you’re targeting legacy browsers.
Module scripts are designed to provide a more robust and encapsulated code structure. If you need to share variables with non-module scripts, explicitly assign them to the global scope or refactor your code to use only modules. By following the import/export standards, you’ll maintain cleaner, more maintainable code.