#代码模块化
模块化其实涉及到作用域的概念,我们现在存在全局作用域, 函数作用域 块作用域,但随着项目的增大,代码的复杂度的增加,会产生一系列的问题,比如命名冲突 为了代码的可维护性 我们必须将代码结构化----模块化,以模块来划分作用域
优化程序的结 构和组织的方式,就是把它们分成小的、耦合相对松散的片段,这些片 段称为模块。
模块是比对象和函数更大的代码单元,使用模块可以将程序进行归 类。创建模块时,我们应该努力形成一致的抽象和封装
##在JavaScript ES6之前的版本中模块化代码
- AMD (require.js)
- CMD (Sea.js)
- Commonjs (Nodejs服务端)
-
通过返回的对象暴露模块的公共接口。模块内部的实现(私有变量和函数)通过公共接口创建的闭包保持活跃
-
通过使用立即执行函数,我们可以隐藏指定的模块执行细节。通过 添加对象和闭包,我们可以定义模块接口,通过接口暴露模块的功能
这种在JavaScript中通过使用立即执行函数、对象和闭包来创建模块 的方式称为模块模式。
扩展模块的过程与重新创建模块的过程类似。调用立即执行函数, 并传入需要扩展的模块作为参数
##模块模式的缺点
- 扩展的模块无法共享原有模块的内部属性。
- 模块模式还有其他问题。当我们开始创建模块化应用 时,模块本身常常依赖其他模块的功能。然而,模块模式无法实现这些 依赖关系。我们作为开发者,则不得不考虑正确的依赖顺序
##AMD的原理
加载主模块 根据script标签中data-main属性确认主模块的路径
执行require配置
通过define传递的参数拼接路径,然后创建动态script标签,引入对应模块并执行代码
如果代码中还存在依赖则继续上面的步骤直到所有代码执行完毕
##CommonJS
AMD的设计明确基于浏览器,而CommonJS 的设计是面向通用 浏览器端的JavaScript不支持module变量及export属性,我们不得不采用浏览器支持的格式打包代码 ###commonjs在nodejs环境流行的原因 CommonJS 使用基于文件的模块,所以每个文件中只能定义一个模块。 CommonJS提供变量module,该变量具有属性exports,通过exports可以 很容易地扩展额外属性。最后,module.exports作为模块的公共接口。 如果希望在应用的其他部分使用模块,那么可以引用模块。文件同 步加载,可以访问模块公共接口。这是CommonJS在服务端更流行的原 因,模块加载相对更快,只需要读取文件系统,而在客户端则必须从远 程服务器下载文件,同步加载通常意味着阻塞。
##ES6模块 ES6模块结合了CommonJS与AMD的优点
- 与CommonJS类似,ES6模块语法相对简单,并且基于文件(每个 文件就是一个模块)
- 与AMD类似,ES6模块支持异步模块加载。
目前部分浏览器尚未支持ES6。如果现在就需要使用ES6模块,我们 需要对代码进行编译,可以使用Traceur,Babel或TypeScript