模块化
CommonJS
- Node 应用由模块组成,采用 CommonJS 模块规范。每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
- 在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
- 每个模块内部有两个变量可以使用,require 和 module。module 代表当前模块,是一个对象,保存了当前模块的信息。exports 是 module 上的一个属性,保存了当前模块要导出的变量。使用 require 加载的某个模块获取到的值就是那个模块使用 exports 导出的值。
- 为了方便,Node.js 在实现 CommonJS 规范时,为每个模块提供一个 exports 的私有变量,指向 module.exports。let exports = module.exports,有一点要尤其注意,exports 是模块内的私有局部变量,它只是指向了 module.exports,所以直接对 exports 赋值是无效的,这样只是让 exports 不再指向 module.exports了而已!
- 如果一个模块的对外接口,就是一个单一的值,可以使用 module.exports 直接导出
- CommonJS模块的加载机制是值拷贝
javascript
//a.js
let name = 'cai'
let age = 18
//module.exports = age //导出一个单一的值
module.exports.name = name
module.exports.getAge = function(){ //这种方式避开值拷贝
return age
}
//b.js
let a = require('./a.js')
console.log(a.name) //'cai'
console.log(a.getAge()) //18
渐进式模块化
AMD
CMD
Webpack
ES Module
特点
- 浏览器原生
- ES6 Module 加载机制是值引用
- 模块不会向全局作用域 window 添加任何内容
- 模块始终处于严格模式
- ES6 模块是编译时加载(有点像把代码复制过来)
使用
<script type="module" src="---"></script>
任何使用 import 或 export 的代码都必须使用type="module"这个属性
导出
- 命名导出:export [标识符]
- 标识符可以是原始值、函数表达式、函数定义、异步函数、类、实例化的类
- 如果标识符有多个,使用对象形式更方便
- 默认导出:export default [标识符或字面量]
导入
- import { var1 as ---, var2 as --- } from './---.js'
- import * as obj from './---.js' 将导出的所有内容作为obj的属性和方法
- import var from './---.js' 如果是默认导出,可以命名导出的值
案例
javascript
//functions.js
export const length = 10
export const width = 5
export default function (x, y) {
return 2 * (x + y)
}
//script.js
import calculatePerimeter, {length, width} from './functions.js' //混合使用
calculatePerimeter(length, width) //30