模块化发展史

209 阅读3分钟

模块化演进的过程

  • 1.文件划分的方式 污染全局作用域 命名冲突 无法管理模块依赖关系
  • 2.命名空间方式 在第一个阶段的基础上 将每个模块只暴露一个全局对象 所有的变量都挂载到这个全局对象上
  • 3.IIFE 立即执行函数 为模块提供私有空间 以上是早起在没有工具和规范的情况下对模块化的落地方式

AMD

基于浏览器实现的,依赖前置,异步加载 require.js

运行机制

通过require加载时,它会先加载对应的依赖,等依赖资源加载完之后,会执行回调函数,将依赖作为入参,执行对应的业务逻辑

特点

AMD机制是基于浏览器实现的,它是在客户端使用的,由于资源都是在服务器上,所以它是异步加载。同时,它最大的特点是强调依赖前置。

CMD

也是基于浏览器实现的 按需加载依赖 异步加载 sea.js

运行机制

与AMD类似,最大的区别就是CMD强调延迟加载,对应的依赖等到回调函数里执行具体依赖语句,才会去加载,但是AMD在后续版本里也支持了延迟加载的写法

commonjs规范

一个文件就是一个模块,每个文件通过module来表示,用require来引用其他依赖,用module.exports来导出自身

运行机制

通过require去引用文件时,会将文件执行一遍后,将其执行结果通过浅克隆的方式,写入全局内存。后续再require该路径,就直接从内存里取出,不需要重新执行对应的文件

特点

  • 以同步的方式加载模块 资源加载完再执行 node的执行机制是在启动时去加载模块 在执行阶段不需要加载模块
  • 在浏览器阶段使用会导致效率低下,因为浏览器需要在运行时频繁的加载文件
  • 服务端:Node.js 模块加载是以运行时同步加载
  • 浏览器:webpack browserfy 提前编译打包处理

UMD

CommonJS、AMD、CMD并行的状态下,就需要一种方案能够兼容他们,这样我们在开发时,就不需要再去考虑依赖模块所遵循的规范了,而UMD的出现就是为了解决这个问题。

ESModule

在语言层面实现了模块化 通过给script的标签 将type设置成module 就可以使用这个规范了,服务端和浏览器端通用,依赖需要提前声明好 通过在顶层使用import。

特点

  • 自动采用严格模式,忽略use strict
  • 每个ESM模块都是单独的私有作用域
  • ESM是通过CORS去请求外部JS模块的
  • ESM中的script标签会延迟执行脚本

运行机制

ES6的模块机制在依赖模块时并不会先去预加载整个脚本,而是生成一个只读引用,并且静态解析依赖,等到执行代码时,再去依赖里取出实际需要的模块

ESModule VS CommonJS

  • 输出值: es6输出的是一个值的引用,es6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块

commonjs输出的是一个值的拷贝,模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就会被缓存,以后再加载就直接读取缓存结果,要想让模块再次运行,必须清除缓存

  • 加载方式 es6编译时输出接口,ES6模块不是对象,它的对外接口只是一种静态定义,在代码解析阶段就会动态生成

commomjs运行时加载,因为commonjs加载的是一个对象,该对象只有在脚本运行时才会生成

参考连接

github.com/Advanced-Fr…