Web开发越来越复杂,需要一个团队分工协作、进度管理、单元测试、持续集成、持续部署…… 社区也开发了很多工具来协助构建这些规模庞大的应用。诸多工具中最核心的非模块系统莫属,在这样一个系统中,你可以通过多个文件和目录来组织你的项目,最重要的是,所有代码都可以按需彼此访问并高效加载。所以JavaScript就这么顺理成章地有了几个知名的模块系统。当然,随之而来的还有几个包管理器,可以用它们安装所有软件以及处理高层次的依赖。如此一来,模块化开发就显得非常重要了,所以本节主要聊一聊JavaScript的模块化开发之CommonJS规范。
理想状态下,Developer只需要实现核心的业务逻辑,其他的可以加载别人已经写好的模块即可,因此JavaScript语言的模块化编程就显得异常重要了。然而,ES6之前JavaScript没有为组织管理代码提供任何方案,甚至没有类(Class)的概念,更不用说模块(Module)了.
模块化管理需要具备:
- 定义封装的模块。
- 定义新模块对其他模块的依赖。
- 可对其他模块的引入支持。
CommonJS模块规范
CommonJS规范历史:
- 2009年1月,Mozilla 的工程师 Kevin Dangoor 创建了这个项目,当时的名字是 ServerJS。其是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。
- 2009年8月,这个项目改名为 CommonJS,以显示其 API 的更广泛实用性。
- 2013年5月,Node.js 的包管理器 NPM 的作者 Isaac Z. Schlueter 说 CommonJS 已经过时,Node.js 的内核开发者已经废弃了该规范。
随着JavaScript作为后端语言的发展,CommonJS规范应运而生。参考 CommonJS规范, 需要注意的是CommonJS通常是服务器端模块的规范,Node.js采用了这个规范。Node.JS首先采用了js模块化的概念。
CommonJS规范要点
- 每个文件就是一个模块, 有自己的作用域。
- 在一个文件里定义的变量、函数、类都是私有的,对其他文件不可见。
- 导出:每个模块内部,变量module代表当前模块,这个变量是一个对象。它的exports属性(即module.exports)是一个对外的接口。
- 导入:require方法用于加载模块。
CommonJS的特点
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清楚缓存
- 模块加载的顺序,按其在代码中出现的顺序。