esm的最简单理解

overview

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

出生背景

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

能解决什么问题

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

如何运行

分如下4个部分运行。node

1. 发现/加载。

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

2. 建立(也叫解析)

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

3. 实例化

js引擎建立模块环境记录。里面保存了该模块的全部变量。在评估前不能被访问。
使用一块内存专门保存该模块的实例。该模块对外输出就是使用此内存。即便已经输出对象,再在该模块内修改值,也会做用于已经输出的对象。由于对象对应的内存没变。浏览器

4. 评估

执行实例化结果。模块化

commonjs & es module

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

future

esm/cjs正在统一。code

相关文章
相关标签/搜索