JavaScript 模块化入门教程
模块化介绍
模块化的概念
模块化的本质是将一个复杂的程序依据一定的规则 (规范) 封装成几个块 (文件),并进行组合在一起,块 (文件) 的内部数据和操作实现是私有的,只是对外部暴露一些接口 (方法) 与外部其它模块通信。
模块化的进化史
一、将不同的功能封装成不同的全局函数(全局函数模式)
- 缺点:Global 被污染,很容易引起命名冲突
二、简单对象封装(命名模式)
- 优点:减少 Global 上的变量数目
- 缺点:本质是对象,一点都不安全
三、匿名函数自调用【闭包】(IIFE 模式)
- 优点:函数是 JavaScript 唯一的 Local Scope
- 缺点:如果当前这个模块依赖另一个模块怎么办?
四、引入依赖(IIFE 模式增强),这是现代模块化实现的基石
为什么要模块化
前端开发的现状
前端开发的现状往往是在页面中引入加载大量的 JavaScript 文件(如下图),这会导致页面请求过多、依赖模糊、代码难以维护等问题。值得一提的是,这些问题可以通过现代模块化编码和项目构建来解决。
模块化的需求
- Web sites are turning into Web apps(网站正转变为网络应用程序)
- Code complexity grows as the site gets bigger(代码复杂度随着站点变大而变复杂)
- Assembly gets harder(组装变得更难)
- Developer wants discrete JS files/modules(开发者想分离 JS 文件 / 模块)
- Deployment wants optimized code in just one or a few HTTP calls(网站部署者想通过使用一个或者很少 HTTP 请求来优化代码)
模块化的优点
- 避免命名冲突(减少命名空间污染)
- 更好的分离,按需加载
- 更高的复用性
- 更高的可维护性
模块化规范
JavaScript 的模块化规范分为四大类,分别是 CommonJS、ES 6、AMD、CMD。
CommonJS
概述
每个 JavaScript 文件都可以当一个模块,并具有以下特性:
在服务器端
:模块的加载是在运行时同步加载的在浏览器端
:模块需要提前编译打包处理
实现
服务端的实现
浏览器端的实现
- Browserify,它也称为 CommonJS 的浏览器端的打包工具
Node.js 与 Browserify 的区别
Node.js 是在运行时动态加载模块(同步),而 Browserify 是在转译(编译)时就会加载并打包 (合并) require
的模块。
基础语法
暴露模块
module.exports = value
exports.xxx = value
引入模块
require(xxx)
- 内置模块:
xxx
为模块名 - 第三方模块:
xxx
为模块名 - 自定义模块:
xxx
为模块文件的路径
- 内置模块:
使用案例
- 创建项目结构
1 | 05 |
- Node 安装第三方模块
1 | npm install uniq --save |
- 模块化编码 - module1.js
1 | // module.exports = value 暴露一个对象 |
- 模块化编码 - module2.js
1 | // module.exports = value 暴露一个函数 |
- 模块化编码 - module3.js
1 | // exports.xxx = value 暴露多个目标 |
- 模块化编码 - app.js
1 | // 引入内置模块 |
- 通过 Node 运行 app.js
1 | node app.js |