目录
1. ES6 规范
1.1. 导出和导入
1.1.1. Default Exports(默认导出)
1.1.2. Named Exports(命名导出)
1.1.3. Import All The Things(导入所有)
1.1.4. Export All The Things(导出所有)
1.1.5. Dynamic Import(动态导入)
1.1.6. import.meta
1.2. Mutable Bindings
1.3. Imported Variables Are Read-only
2. classic scripts 和 modules 的差别
3. 新提案:import-maps
2.1. "bare" import specifiers
2.2. Import maps
1. ES6 规范
1.1. 导出和导入
1.1.1. Default Exports(默认导出)
代码语言:javascript复制// hello-world.js
export default function() {}
// main.js
import helloWorld from './hello-world';
import anotherFunction from './hello-world';
helloWorld();
console.log(helloWorld === anotherFunction);
JavaScript 的值也可以被默认导出
代码语言:javascript复制export default 3.14;
export default {foo: 'bar'};
export default 'hello world';
1.1.2. Named Exports(命名导出)
代码语言:javascript复制const PI = 3.14;
const value = 42;
export function helloWorld() {}
export {PI, value};
导出的时候还可以重命名
代码语言:javascript复制const value = 42;
export {value as THE_ANSWER};
导入变量的时候也可以重命名
代码语言:javascript复制import {value as THE_ANSWER} from './module';
1.1.3. Import All The Things(导入所有)
代码语言:javascript复制// module.js
export default 3.14;
export const table = {foo: 'bar'};
export function hello() {};
// main.js
import * as module from './module';
console.log(module.default);
console.log(module.table);
console.log(module.hello());
1.1.4. Export All The Things(导出所有)
代码语言:javascript复制// module.js
const PI = 3.14;
const value = 42;
export const table = {foo: 'bar'};
export function hello() {};
// main.js
export * from './module';
export {hello} from './module';
export {hello as foo} from './module';
1.1.5. Dynamic Import(动态导入)
代码语言:javascript复制import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
1.1.6. import.meta
import.meta 是一个给 JavaScript 模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。
代码语言:javascript复制import.meta
1.2. Mutable Bindings
Imported bindings refer to variables inside a module’s body. This causes an interesting sideeffect when you import “by value” variable such as Number, Boolean, or String. It’s possible that the value of that variable will be changed by an operation outside of the importing module.
1.3. Imported Variables Are Read-only
代码语言:javascript复制No matter what kind of declaration is being exported from a module, imported variables are always readonly. You can, however, change an imported object’s properties.
// module.js
export let count = 0;
export const table = {foo: 'bar'};
// main.js
import {count, table} from './module;
table.foo = 'Bar'; // OK
count ; // read-only error
2. classic scripts 和 modules 的差别
除了上面这些差异,还有:
- module 被引入多次,只会执行一次;但 script 会执行多次;
<script src="classic.js"></script>
<script src="classic.js"></script>
<!-- classic.js executes multiple times. -->
<script type="module" src="module.mjs"></script>
<script type="module" src="module.mjs"></script>
<script type="module">import './module.mjs';</script>
<!-- module.mjs executes only once. -->
- modules 默认是 deferred。classic scripts 则会阻塞 HTML 的解析。
3. 新提案:import-maps
3.1. "bare" import specifiers
首先
在 ES6 的 import 语句中
我们称呼下图红框中的部分为
“module specifier”
When importing modules, the string that specifies the location of the module is called the “module specifier” or the “import specifier”.
在 “module specifier” 中
有些并不是以 "/"、“./”、"../" 开头
我们称呼这些为
“bare import module specifier”
但是HTML官方规范中表示
但凡不是以 "/"、“./”、"../" 开头的
不会被当做相对路径处理
会报错
可是我们的确一直都在写
import {useState} from "react"
import {ref, reactive} from "vue"
没见报错啊?为什么?
代码语言:javascript复制import Vue from 'vue'
import _ from 'lodash'
import axios from "axios"
那是因为像 Webpack、Vite 这样的打包工具
已经给你把路径转换工作干了
这有什么问题么?
Today, many web developers are even using JavaScript's native module syntax, but combining it with bare import specifiers, thus making their code unable to run on the web without per-application, ahead-of-time modification. We'd like to solve that, and bring these benefits to the web.
问题就是
原生开发时(不依赖打包工具)你会遇到很多麻烦
1. npm 上多数都是 CJS 的包,需要单独找 ES6 版的包
2. 路径问题太复杂,需要根据运行环境写不同的代码
3.2. Import maps
Importmaps 提案
就是让浏览器原生支持
“bare import specifier”
看一个例子
浏览器兼容性怎么样?
参考:
resolve a module specifier: https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system import-maps: https://github.com/WICG/import-maps Using ES modules in browsers with import-maps: https://blog.logrocket.com/es-modules-in-browsers-with-import-maps/ An Introduction To JavaScript ES6 Modules https://strongloop.com/strongblog/an-introduction-to-javascript-es6-modules/ exploringjs:modules https://exploringjs.com/es6/ch_modules.html#sec_overview-modules JavaScript modules: https://v8.dev/features/modules