模块化的基础是IIEE
本文对模块化做一下总结。
模块化是工程化的基础:只有能将代码模块化,拆分为合理单元,才能使其具备调度整合得的能力,才有架构和工程一说。
什么是模块化?
对于一个复杂的应用程序,与其将其所有代码全部放在一个文件中,不如按照一定的语法,遵循确定的规则将其拆分到几个相互独立的文件中,这些文件具备原子特定性,其内部完成共同的或者类似的逻辑,通过对外暴露一些数据或者调用方法与外部进行整合。
模块化发展历程
IIFE模式
最早的被认可的模块化方案是IIFE模式:通过构建一个私有作用域,再通过闭包,将需要对外暴露的数据和接口输出。这种模式是现代模块化方案的基础。利用构建工具webpack打包后的模块化就是这种模式。
(function(window, $){ let data = 'data' function foo(){ console.log(3) } function bar(){ data = '333' console.log(222) } window.module = {foo, bar} // 对外暴露 })(window,JQuery)
规范标准阶段
1,Commonjs
Commonjs是Nodejs带来的。其具备以下几个特点:
1)文件即模块,文件内的所有代码都运行在独立的作用域中,因此不会污染全局空间
2)模块可以被多次引用、加载。在第一次被加载时,会被缓存,之后都从缓存中直接读取结果
3)加载某个模块,就是引入该模块的module.exports属性
4)module.exports属性输出的是值的拷贝,一旦这个值被输出,模块内在发生变化也不会影响到输出的值
5)模块按照代码引入的顺序进行加载
6)同步加载模块文件,因此不适合浏览器端
2,AMD
AMD的代表是requirejs。requirejs通过define方法,将代码定义为模块,通过require方法实现模块的加载。其底层也是一个IIFE。
有一个知识点:在我过去使用requirejs时候发现即使引入了模块也没有看到引入的script,其实这是被requirejs删除了,因为模块内容已经被加载了,一旦加载完成就没必要保留script了。
3,CMD
CMD的代表是seajs。和AMD的requirejs相比,requirejs是异步的,而seajs既可以是同步的也可以是异步的。
4,UMD
UMD也就是Universal Module Definition。其实就是上面三种情况做了一个整合。
ES原生
ES模块的设计思想是尽量静态化,保证在编译时就确定模块之间的依赖关系,每个模块的输入和输出变量都是确定的;而Commonjs和AMD无法保证编译时就确定这些内容,这俩只能在运行时确定。另外,Commonjs模块输出的是一个值的拷贝,ES模块输出的是值的引用。
说下ES原生规范的优势
ES设计成静态的,能够很好的分析导入的依赖。如果导入的模块没有被使用,可以通过tree shaking等手段减少代码体积,进而提升运行性能。
当然ES模块化规范预热带来一些限制:
1)只能在文件顶部引入依赖
2)导出的变量类型受到严格限制
3)变量不允许被重新定义,也就是read-only
未来发展展望
ES模块化是未来发展的趋势,它具有开箱即用的tree shaking和对未来浏览器的兼容性支持。目前各大浏览器都开始逐步支持ES模块化。而这一点也是构建工具vite的基础。