Static import
The static import
declaration is used to import read-only live bindings which are exported by another module.
Static import is syntactic.
Named imports
Each import has a name, which must be the same as the corresponding export name in the imported module.
1 | // math.mjs |
1 | // main.mjs |
Default imports
You can import the default export of a module using the following syntax:
1 | // math.mjs |
You can use any name here, not limited to add
. But you can only have one default export per module.
1 | // main.mjs |
Namespace imports
You can also import all exports from a module using the following syntax:
1 | // math.mjs |
1 | // main.mjs |
Side effects imports
You can also import a module for its side effects only, without importing any bindings. This is useful when you just want to run the code in the module, but don’t need to import any of its bindings.
1 | import './math.mjs'; |
This is very common in Angular code, especially with Module Federation, where you import a module for its side effects only.
1 | // bootstrap.ts |
main.ts
use side effect import here which will run all global code in bootstrap.ts
but not import any bindings. (Note, the following code is dynamic import, not static import)
1 | // main.ts |
Static import only execute once
No matter how many times you import a module, it will only be executed once. Suppose you have a math
module with the following code:
1 | // math.mjs |
And another two module add
and subtract
with the following code:
1 | // add.mjs |
1 | // subtract.mjs |
and finlay, you import add
and subtract
in your main module:
1 | // main.mjs |
When you run main.mjs
, you will see only one random number printed in the console, which means the math
module is only executed once.
1 | 0.2534933886729216 |
Dynamic import
Introduction
import()
is dynamic import, it returns a promise. The import() syntax, commonly called dynamic import, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.
Basic example
1 | import("ramda").then(module => { |
With dynamic import, you can import modules conditionally. The following code load the chat-box when user click on the contact button.
1 | const contactBtn = document.querySelector("#button"); |
Async/Await
Since import()
returns a promise, you can use async/await
to import modules.
1 | const contactBtn = document.querySelector("#button"); |
Destruction
You can also use object destruction to import modules.
1 | const contactBtn = document.querySelector("#button"); |
Error handling
And last, don’t forget to handle error when importing modules.
1 | try { |
Use import()
in non-module environment
import()
can be used in non-module environment, such as in a .js
file or script tag without type="module"
.
1 | // test.js, you don't need test.mjs here. |
1 | <!-- You don't need type="module" in script tag--> |
But static import can’t be used in non-module environment, you will got Error: SyntaxError: Cannot use import statement outside a module
, to make static import work, you must use file end with .mjs
or add type="module"
in script tag.
1 | import {load} from "./chat-box.mjs"; |
1 | <!-- You need type="module" in script tag--> |
pass by reference
There is no real
pass by reference in JavaScript like in C/C++ language, but you can use import
to achieve similar effect.
First, create a module module.mjs
, in this file, we export an object person
.
1 | // module.mjs |
Create another module module1.mjs
, in this file, we import person
from module.mjs
and change the age
to 40.
1 | // module1.mjs |
Finally, import module1.mjs
and module.mjs
in main.mjs
, and print the person
object, you will found the age
is 40 now.
1 | // main.mjs |
输出如下:
1 | { name: 'zdd', age: 40 } |
import.meta.url
import.meta.url
The full URL to the module, includes query parameters and/or hash (following the ? or #). In browsers, this is either the URL from which the script was obtained (for external scripts), or the URL of the containing document (for inline scripts). In Node.js, this is the file path (including the file:// protocol).
In Node.js, import.meta.url
is the file path of the current module. It is similar to __filename
in CommonJS modules.
This is server.ts
file generated by angular SSR, you can see import.meta.url
is used to get the current file path.
1 | import express from 'express'; |
References
- Static imports: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#import_a_module_for_its_side_effects_only
- Dynamic imports: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta