overview

讲解esm的运行逻辑。
esm是一种模块化解决方案。其他方案还有:commonjs(本文简写为cjs)/amd/umd。模块化是工程化的组成部分。
后端早就把工程化做的很好了。前端的代码还是一地鸡毛。使用拙劣的<script>。es6为前端带来了模块化。

出生背景

  1. 已经存在一些简单的/补漏的模块化解决方案。如:iife.
  2. commonjs已经在node.js中正常运行。
    虽然有这些补救措施,但是不足以完美解决前端模块化。还有一些问题没解决,如下:
  3. 严格确定<script>引入顺序。
  4. 为了让其他脚本间协同工作。不得不使用全局变量。而全局变量又会被全局访问/使用/修改。无法限制。

能解决什么问题

  1. 把一大块功能分为若干小模块去开发,然后再组合为了一个模块,整合后对外输出。
  2. 每个模块只能操作本模块和本模块引入模块输出的变量/方法等。不需要全局变量。
  3. 控制本模块向外输出哪些东西。
  4. 没有引入顺序限制。不引入则无使用依赖,想使用依赖,就得引入依赖。

如何运行

分以下4个部分运行。

1. 发现/加载。

在浏览器中使用<script src="main.js" type="module">指定使用的脚本。浏览器会根据url下载脚本。type="module"会让浏览器把该文件当做module处理。该文件中可以使用import
浏览器会一层一层地根据依赖关系依次加载依赖。此过程需要较长时间。然后模块地图

2. 创建(也叫解析)

根据模块地图生成模块记录。然后模块记录代替模块地图。
模块记录包括:代码/状态。
代码是该模块的运行逻辑,
状态是该模块变量的实际值。
模块的url与模块一一对应。
后会生成一个入口对应若干模块记录。

3. 实例化

js引擎创建模块环境记录。里面保存了该模块的所有变量。在评估前不能被访问。
使用一块内存专门保存该模块的实例。该模块对外输出就是使用此内存。即使已经输出对象,再在该模块内修改值,也会作用于已经输出的对象。因为对象对应的内存没变。

4. 评估

执行实例化结果。

commonjs & es module

cjs的运行逻辑与esm的运行逻辑的不同。
若cjs中使用esm。则需要把文件扩展名设置为.mjs
cjs在实例化时会返回该模块的输出的对象。若已经输出对象,再在该模块内修改值,则不会影响已经输出的对象。
cjs已经做了一些兼容esm的功能。

future

esm/cjs正在统一。


飞机
124 声望3 粉丝

« 上一篇
入门rollup
下一篇 »
api设计原则

引用和评论

0 条评论