模块化小讲

Published on with 0 views and 0 comments

服务器端和浏览器端的天然区别

  • 服务器端所有的模块都存放在本地硬盘中,可以同步加载完成,等待时间就是硬盘的读取时间。
  • 浏览器,所有的模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于”假死”状态。

说说JS的模块化

原始模拟模块的一些写法

  • 一个函数就是一个模块
  • 一个对象就是一个模块
  • 立即执行函数为一个模块

CommonJS规范

暴露模块

  • module.exports = {}
  • exports.xxx = 'xxx'

引用模块

使用全局方法require()

模块标识符

  • 核心模块(Node.js自带的模块):直接跳过路径分析和文件定位
  • 路径模块(相对或绝对定位开始的模块):直接得出相对路径就好了
  • 自定义模块(node_modules里的模块):先在当前目录的node_modules里找这个模块,如果没有,它会往上一级目录查找,查找上一级的node_modules,依次往上,直到根目录下都没有, 就抛出错误。

CommonJS规范的特点

  • 所有代码都运行在模块作用域,不会污染全局作用域;
  • 模块是同步加载的,即只有加载完成,才能执行后面的操作;
  • 模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存;
  • CommonJS输出是值的拷贝(即,require返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值)。

AMD规范

  • Asynchronous Module Definition
  • 它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
  • define(id?, dependencies?, factory)
    • id: 一个字符串,表示模块的名称,但是是可选的
    • dependencies: 一个数组,是我们当前定义的模块要依赖于哪些模块,数组中的每一项表示的是要依赖模块的相对路径,且这个参数也是可选的
    • factory: 工厂方法,一个函数,这里面就是具体的模块内容了
  • 主要有两个Javascript库实现了AMD规范:require.js和curl.js。

CMD规范

  • Common Module Definition
  • 是seajs推崇的规范,CMD则是依赖就近,用的时候再require。
  • define(id?, dependencies?, factory)
    • id: 一个字符串,表示模块的名称,但是是可选的
    • dependencies: 一个数组,是我们当前定义的模块要依赖于哪些模块,数组中的每一项表示的是要依赖模块的相对路径,且这个参数也是可选的
    • factory: 工厂方法,一个函数,这里面就是具体的模块内容了
      • require:引入某个模块
      • exports:当前模块的exports,也就是module.exports的简写
      • module:当前这个模块

AMD和CMD的区别

AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同,二者皆为异步加载模块。

  • AMD中会把当前模块的依赖模块放到dependencies中加载,并在factory回调中拿到加载成功的依赖
  • CMD一般不在dependencies中加载,而是写在factory中,使用require加载某个依赖模块
  • AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
  • CMD推崇就近依赖,只有在用到某个模块的时候再去require(需要使用把模块变为字符串解析一遍才知道依赖了那些模块,factory.toString() -> 正则)

ES6 Modules规范

  • export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
  • import命令输入的变量都是只读的,因为它的本质是输入接口,但如果变量是一个对象,改写变量的属性是允许的。不过,这种写法很难查错,建议凡是输入的变量,都当作完全只读,不要轻易改变它的属性。
  • import命令具有提升效果,会提升到整个模块的头部,首先执行。类似变量提升
  • 由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。
  • import语句会执行所加载的模块,多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。

CommonJS与ES6 Modules规范的区别

  • esModule模块输出的是值的引用,输出接口动态绑定; CommonJS模块输出的是值的拷贝
  • esModule是编译时输出接口,CommonJS模块是运行时加载,因此支持动态导入。也就是 require(${path}/xx.js)
  • CommonJS是同步导入(用于服务端,文件在本地,同步导入即使卡住主线程影响也不大),ES module 是异步导入的(运用于浏览器,需要下载文件)

标题:模块化小讲
作者:lj0812
地址:https://blog.hereis.me/articles/2020/05/23/1590241051803.html