1 静态语法
ES6 module 的引入和导出是静态的,import
会自动提升到代码的顶层 ,import
, export
不能放在块级作用域或条件语句中。import 的导入名不能为字符串或在判断语句。
错误写法一:
function say(){
import name from './a.js'
export const author = 'fishman'
}
错误写法二:
isexport && export const name = 'es6 module 特性'
错误写法三:
import 'defaultExport' from 'module'
let name = 'Export'
import 'default' + name from 'module'
2 执行特性
ES6 module 和 Common.js 一样,对于相同的 js 文件,会保存静态属性。
但是与 Common.js 不同的是 ,CommonJS
模块同步加载并执行模块文件,ES6 模块提前加载并执行模块文件,ES6 模块在预处理阶段分析模块依赖,在执行阶段执行模块,两个阶段都采用深度优先遍历,执行顺序是子 -> 父。
demo
main.js
console.log('main.js开始执行')
import say from './a'
import say1 from './b'
console.log('main.js执行完毕')
a.js
import b from './b'
console.log('a模块加载')
export default function say (){
console.log('hello , world')
}
b.js
console.log('b模块加载')
export default function sayhello(){
console.log('hello,world')
}
-
main.js
和a.js
都引用了b.js
模块,但是 b 模块也只加载了一次。 -
执行顺序是子 -> 父
输出结果:
3 导出绑定
不能修改import导入的属性
c.js
export let num = 1
export const addNumber = ()=>{
num++
}
main.js
中加入
import { num , addNumber } from './c'
num = 2
如果直接修改,那么打包会报错。如下所示:
属性绑定
所以可以在 main.js
中这么修改。
import { num , addNumber } from './c'
console.log(num) // num = 1
addNumber()
console.log(num) // num = 2
-
如上属性 num 的导入是绑定的。
接下来对 import 属性作出总结:
-
使用 import 被导入的模块运行在严格模式下。
-
使用 import 被导入的变量是只读的,可以理解默认为 const 装饰,无法被赋值
-
使用 import 被导入的变量是与原变量绑定/引用的,可以理解为 import 导入的变量无论是否为基本类型都是引用传递。
tree shaking 实现
Tree Shaking 在 Webpack 中的实现,是用来尽可能的删除没有被使用过的代码,一些被 import 了但其实没有被使用的代码。比如以下场景:
d.js
:
export let num = 1
export const addNumber = ()=>{
num++
}
export const delNumber = ()=>{
num--
}
main1.js
:
import { addNumber } from './d'
addNumber()
-
如上 d
.js
中暴露两个方法,addNumber
和delNumber
,但是整个应用中,只用到了addNumber
,那么构建打包的时候,delNumber
将作为没有引用的方法,不被打包进来。
es module 总结
Es module
的特性如下:
-
ES6 Module 静态的,不能放在块级作用域内,代码发生在编译时。
-
ES6 Module 的值是动态绑定的,可以通过导出方法修改,可以直接访问修改结果。
-
ES6 Module 可以导出多个属性和方法,可以单个导入导出,混合导入导出。
-
ES6 模块提前加载并执行模块文件,
-
ES6 Module 导入模块在严格模式下。
-
ES6 Module 的特性可以很容易实现 Tree Shaking 和 Code Splitting。