Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

JavaScript Scripts and Modules

Understand ECMAScript Scripts and Modules, import/export forms, live bindings, module namespaces, dependency linking and evaluation, cycles, top-level await, dynamic import, import attributes, and JSON modules without confusing language semantics with browser loading.

Levels: Advanced ~55 min read

Advanced

Scripts and modules are different execution units

ECMAScript defines two source-text goals for program-level code: Script and Module. A Script is evaluated as a script; a Module is parsed and evaluated with module-specific syntax and semantics. This lesson owns the language-level boundary between them. Browser loading rules such as HTML script elements, URLs, MIME checks, and fetching are host-platform concerns and are intentionally outside this lesson.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which concept belongs primarily to this lesson?

Export values deliberately

A module can expose bindings with named exports or one default export. The export declaration describes the module interface; it does not copy a value into another module. Exporting a binding makes that binding available to the module graph.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which statement is true about a module default export?

Import named, default, and namespace bindings

Static imports choose the bindings a module needs from another module. Named imports select specific exports, a default import selects the default export, and a namespace import creates a module namespace object binding that exposes the module’s exported names.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does `import * as ns from "./source.js"` bind?

Imported bindings are live

Static imports are live bindings rather than snapshots. If the exporting module changes an exported mutable binding, an importer observes the current binding. The importer cannot reassign the imported binding itself.

Interactive Runnable example
Edit

Ready to run.

Quick check

After `increment()` changes the exported `count`, what does an importer observe?

Module namespace objects expose the module interface

A module namespace object represents the exports of a module. Namespace properties correspond to exported names and are ordered according to the module namespace semantics rather than being ordinary mutable application state. Treat it as an interface view, not a bag of writable variables.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is the useful mental model for a module namespace object?

Re-export without becoming the original owner

A module can re-export another module’s bindings. This lets a package-style entry module define a public surface without copying implementations into one file. `export { ... } from` and `export * from` create forwarding relationships in the module graph.

Interactive Runnable example
Edit

Ready to run.

Quick check

Why use a re-exporting entry module?

Static imports form a dependency graph

Static imports are known from the module source before evaluation. The host loads requested modules, while ECMAScript defines how the resulting Module Records are linked and evaluated. Think in terms of a graph: modules are nodes and import relationships are edges.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does a static import contribute before evaluation?

Linking resolves bindings before evaluation

Module linking prepares the connected graph so imported and exported bindings can be resolved before module code runs. This separation matters: a module can have a valid dependency structure even though its executable statements have not yet evaluated.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is the main purpose of module linking?

Cycles are part of the module model

Module graphs may contain cycles. ECMAScript has explicit module-record machinery for cyclic dependencies so linking and evaluation can reason about strongly connected groups. A cycle is not automatically an error; what matters is whether the code attempts to use a binding before that binding has been initialized.

Interactive Runnable example
Edit

Ready to run.

Quick check

Does the existence of an import cycle automatically make a module graph invalid?

Top-level await makes module evaluation asynchronous

A module can contain `await` at top level. Such a module is individually asynchronous, and its dependants may have to wait for its evaluation to complete. This is module evaluation behavior; the general semantics of Promise objects and async functions remain owned by their dedicated lessons.

Interactive Runnable example
Edit

Ready to run.

Quick check

What is special about top-level `await` in a module?

Dynamic import loads a module from an expression

The `import()` expression performs a dynamic module import and produces a Promise for the module namespace object. Unlike static import declarations, it can be evaluated conditionally or in response to runtime decisions. Promise semantics remain the responsibility of the Promises lesson.

Interactive Runnable example
Edit

Ready to run.

Quick check

What does `import("./feature.js")` produce?

Import attributes are part of the module request

Current ECMAScript module requests can carry import attributes. The syntax uses a `with` clause, and the module request records retain the attribute key/value pairs. The host decides how resources are loaded, while ECMAScript defines the language-level representation and behavior of the request.

Interactive Runnable example
Edit

Ready to run.

Quick check

Where does `type: "json"` belong in the ECMAScript module model?

JSON modules have a defined module record form

ECMAScript defines JSON module records as a module form associated with a JSON import request. The JSON is parsed into the module’s exported value rather than being treated as JavaScript source code. This lesson covers the language-level module relationship; browser fetch and MIME handling remain host concerns.

Interactive Runnable example
Edit

Ready to run.

Quick check

How should a JSON module be understood?

Modules are strict and have their own top-level binding rules

Module code is always strict mode code. Top-level declarations in a module are scoped to that module rather than becoming properties of the global object. This is one reason modules provide a stronger boundary than concatenating unrelated script code.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which statement describes module top-level bindings?

Static import syntax is intentionally constrained

Static import declarations are part of module syntax rather than ordinary runtime expressions. Their structure is known from source text, which allows the module graph to be analyzed before evaluation. When runtime decisions are needed, use dynamic `import()` instead.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which form is an expression that can be evaluated conditionally?

Keep host behavior separate from ECMAScript module semantics

ECMA-262 defines the module language and Module Records, but hosts supply loading mechanisms. In a browser, HTML and Fetch determine how a module URL is requested and delivered. In another host, a different loader can provide the module source. This boundary prevents the JavaScript curriculum from teaching browser behavior as if it were part of the language.

Interactive Runnable example
Edit

Ready to run.

Quick check

Which behavior belongs to a future browser-scripting lesson rather than this ECMAScript module lesson?

Use modules as explicit dependency boundaries

A practical module boundary has a small public surface, clear ownership, and dependencies that point in intentional directions. Re-exporting can define an API entry point, while internal modules remain implementation details. This connects module semantics to program architecture without duplicating the architecture lesson’s broader design material.

Interactive Runnable example
Edit

Ready to run.

Quick check

What makes a module boundary useful?

Know what this lesson owns

Scripts and Modules owns ECMAScript’s Script/Module distinction, import/export syntax, live bindings, namespace objects, module dependency linking and evaluation, cycles, top-level await, dynamic import, import attributes, and JSON modules. It does not replace the lessons for parsing, Promises, async functions, execution contexts, or browser loading. Those boundaries keep the curriculum coherent instead of repeating the same semantics in multiple places.

Interactive Runnable example
Edit

Ready to run.

Quick check

Why does Foxipa keep these boundaries explicit?

Was this page helpful?

Mark this learning resource complete to track your learning progress.