ES6的模块设计
可以参考ES6的模块设计, 不同于Nodejs的动态, ES6的模块技术竟然是静态的
导出什么东西?
我们首先思考一下, 我们在使用export的时候, 会用它导出什么东西。答案是名字(name)和值(value)。毕竟除了关键字, 那些加减乘除, 还有一些括号符号之外, 名字和值就是你代码出现且有用的东西了。
1 | //基础声明的name |
首先关于名字比较容易理解, 做一个表登记一下, 然后读取, 就像编程语言中的环境(env)一样, 那么值(value)如何理解, 值压根没有名字, 所以为了这一点JavaScript为导出的值 设计了一个特殊的名字叫做default。这样值就有了一个默认的名字叫做default。
所以你可以写出下面这种代码:
1 | export default expression; |
导出语句与导入语句的处理逻辑
我们导出一个名字之后, 还需要使用它 比如
1 | 模块1 |
由于其他模块需要使用, 我们就需要为导出的名字绑定一个值, 所以export的处理逻辑为
- 形成一个模块表(name), 登记一个名字
- 为名字绑定一个值, 这是为执行期间的东西
可以使用JavaScript简单模拟一下:
1 | let table = []; |
对应的模块2的import处理逻辑为
- 添加对该模块的一个依赖, 这样我们就可以根据import形成模块依赖树, 找到跟模块, 然后加载了.
- 在当前模块环境(scope)声明一个名字
所以总结export/import就是:
- 根据export形成一个名字表
- 根据import形成一个依赖
所以说ES6的模块系统export/import完全是静态的, 因为根本就没有出现像a+1这样执行代码.但是到了执行阶段就要做下面的事情:
- 找到静态装载阶段的模块树, 并且遍历
- 执行最顶层的代码
- 为名字绑定值, 包括为导出值绑定default这个特殊的名字
- 使用名字