adodo0829 / blog

搭建知识体系
29 stars 4 forks source link

工程化(一)之模块化规范 #26

Open adodo0829 opened 4 years ago

adodo0829 commented 4 years ago

传统模式下的模块

## CommonJS 规范
node 环境下每个文件都有自己的模块作用域, 变量都属于模块

- 导出模块
```js
// 1.整体内容导出
// module.exports 初始值为一个空对象 {}, 由 Module 系统创建
module.exports = {
  id: 1,
  say: () => {}
}

// 2.exports导出
// exports 也是一个模块下的变量, 指向module.exports的引用, 指向同一块内存
exports.id = 1
exports.say = () => {}

// 模块导出的始终是 module.exports 对象
exports = module.exports = { id: 2, say: () => {} }

2.模块是同步加载的,即只有加载完成,才能执行后面的操作

3.模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存

4.模块加载的是值的拷贝, 同时 require('./moudle.js') 多次都只是一个对象的拷贝; CommonJS 模块遇到循环加载时,返回的是当前已经执行的部分的值,而不是代码全部执行后的值


## AMD 规范(require.js)
异步加载
浏览器环境下使用
定义模块: define(fn())
导入: require(['模块名',...], cb())
存在缓存

## ESModule 规范
js 语言环境下使用, 语言层面的规范;
需要 babel工具 进行语法编译
#### export: 规定模块对外接口

默认导出:export default Person(当导入时可指定模块任意名称,无需知晓内部真实名称) 单独导出:export const name = "huhua" 按需导出:export { age, name, sex }(推荐) 改名导出:export { name as newName }

#### import:导入模块内部功能
输入的模块变量是不可重新赋值的,它只是个可读引用,可以改写属性

默认导入:import Person from "person" 整体导入:import * as Person from "person" // Module对象 按需导入:import { age, name, sex } from "person" 改名导入:import { name as newName } from "person" 自执导入:import "./person" 复合导入:import Person, { name } from "person"

#### 复合模式
当`export命令和import命令`结合在一起写成一行,变量实质没有被导入当前模块,相当于对外转发接口,导致当前模块无法直接使用其导入变量

默认导入导出:export { default } from "person" 整体导入导出:export * from "person" 按需导入导出:export { age, name, sex } from "person" 改名导入导出:export { name as newName } from "person" 具名改默认导入导出:export { name as default } from "person" 默认改具名导入导出:export { default as name } from "person"


## CommonJS与ESModule规范的区别

- CommonJS模块是运行时加载,ES6 Modules是编译时输出接口  
CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成

- CommonJS输出是值的拷贝; ES6 Modules输出的是值的引用,被输出模块的内部的改变会影响引用的改变

- CommonJs导入的模块路径可以是一个表达式,因为它使用的是require()方法;而ES6 Modules只能是字符串

- CommonJS this指向当前模块,ES6 Modules this指向undefined  
ES6 Modules中没有这些顶层变量:arguments、require、module、exports、__filename、__dirname

## webpack打包工具
为了让同一套代码在各个运行环境规范下都能适用

- 模块解析

将各个模块维护到一个list中 / module code / 样板代码解析 replace

- 模块加载

同步加载: 直接加载文件 异步加载: jsonp + promise

adodo0829 commented 4 years ago

update: module