ESM基本特性
- 自动采用严格模式,忽略“use strict"
<script type="module">
console.log(this) //undefine
</script>
- 每个ESM模块都是单独的私有作用域
<script type="module">
var a = 10
</script>
<script type="module">
console.log(a) //error
</script>
- ESM是通过CORS去请求外部的js模块
- 外部服务没有设置跨域的话,请求不到模块
- ESM的script标签会延迟执行脚本
<script type="module">
alert('sx')
</script>
<p>显示内容</p>
* 此时会先有弹窗,弹窗执行完页面才会有内容,这个特点和defer属性类似
ESM导出和导入
- ESM的导出可以直接利用export关键词单个导出,也可以一块导出,导出时可以通过as起别名,但是如果别名是关键字,则再引入的时候需要起别名把关键字修改了
let a = 10
let sx = ()=>{
console.log('sx')
}
class sx1{
sx = '25'
}
export {
a as default,
sx as esm1,
sx1
}
- 引入可以直接通过import引入。
import {
default as sx,
esm1,
sx1} from "./module.js"
* 与commonjs规范不同的是,import 引入的路径必须要加.js,且路径不能省略
* 路径要用./ 不能用/
import {a} from "./home" //err
import {a} from "./home/index" //err
import {a} from "/home/index.js" //err
import {a} from "./home/index.js" //success
export {} 导出的并不是一个对象的字面量,而是固定的语法,包含了各种要导出的成员
export default 后面跟的可以是一个变量也可以是固定值,自然也可以是对象字面量,因此在接收的时候可以用一个变量接收
import的接收也不是对对象的解构,导出和接收的,都是成员的引用
浏览器的兼容
虽然ESM已经被大多数浏览器兼容,但是ie中还是不行,想要在不适配的浏览器中运行esm规范,需要做兼容性处理
<script nomodule="" src="https://unpkg.com/promise-polyfill@8.1.3/dist/polyfill.min.js" ></script>
<script nomodule="" src="https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/babel-browser-build.js" ></script>
<script nomodule="" src="https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js
" ></script>
ESM在node环境中的发展
- ESM在node中可以运行,但是目前还并不成熟,只是实验产物
- 直接运行需要将定义的模块后缀改成.mjs,同时引用的地方同步更改,运行 输入 node --experimental-modules index.mjs即可
- esm规范可以直接引用node中的模块
import { writeFileSync } from "fs"; writeFileSync('./test.js','sx')
- 值得注意的是,esm也可以引用第三方模块,但是import是不能解构的
- esm可以引入commonjs定义的模块,反之则不行,且commonjs只会导出一个默认成员,因此import是不能直接提取成员的,因此esm中也无法读取node自带的全局模块函数,如__dirname,require
- 在package.json中更改为type:“module”,也可以实现esm加载,不用改后缀名
- 早期的node可以使用babel来兼容ems特性