js 模块化开发
模块化
- 将程序划分成小结构,有自己的作用域,变量函数不会相互影响
- 可以暴露想访问的变量、函数、对象,导出【export】
- 通过导入引用【import】
- 早期 js 的致命缺陷,就是没有模块化开发
- let 会导致无法声明相同变量的问题,可以包在函数中定义解决,立即执行函数创建一个独立的作用域,无法访问函数内部数据,可以 return 返回。社区开发人员推出很多自己的模块化规范:commonjs、amd、cmd。模块化方案不统一。所以推出了自己的模块化规范。
CommonJS 规范 与 Node 关系【服务端】
-
实现的代表
- node:服务器端,可以进行 commonJS 的解析
- browserify:浏览器
- webpack 打包工具 支持转换解析
-
核心变量:exports、module.exports、require
-
导出、导入原理:引用赋值
-
⚠️ 浏览器默认不可以用commonJS,vue 中 可以实现使用是因为 webpack 进行了解析
-
⚠️ 不要让导入者修改里面的内容
exports
- export 对象,将需要导出的东西付给该对象属性,即可用 require 方法导出使用
❗️module.exports❗️开发常用
- 也是在操作 exports 对象
-
module.exports = { // 每次声明一个新的对象 }
require
- require 方法,引入模块多次,也只执行一次,内部原理,module 对象 理由 loaded 对象默认为 false,再次执行判断该属性
- require 原理:找到模块返回导出的值,本质是找到 moduel 的属性 exports 的对象的内存地址,本质是引用赋值
❗️js 文件后缀默认可以省略?node_modules 里面文件应用访问本质
-
index.js 可以省略
-
js 后缀可以省略
-
❗️require 的查找规则
-
node 的内置模块(path)
require("path"); require("http"); -
外置模块
- 如果有后缀名对应查找
- 没有后缀名:先找该文件,没有加 js 后缀寻找,没有加 json 后缀寻找,没有加 node 后缀寻找
- 没有文件:当作目录,寻找 index.js -- index.json -- index.node 没有 cannot find
- 不是文件夹,也不是文件:先寻找核心模块,然后去 node_modules 下查找
-
-
循环引入的加载顺序:图结构(dfs 深度优先搜索,bfs 广度优先搜索)node 采用 dfs
- main --- aaa --- ccc --- ddd --- eee --- bbb
巧用代码解构
- 应用引入变量、对象、方法
CommonJS 规范缺陷
- 加载模块是同步的,对应模块加载完其内容才可以运行
- 浏览器中不用此规范,js 代码dom操作需要异步执行
- webpack 使用 commonjs 可以,webpack 会将代码解析成浏览器课执行的代码
- 浏览器中使用模块化使用 AMD \ CMD,现在用 es6 module
AMD \ CMD 浏览器模块规范(了解)
AMD 规范
- 异步模块。require.js
CMD 规范
- 异步模块,与 commonjs 非常像。SeaJS,利用立即执行函数
ES Module【前端】
⚠️ES Module 不能本地打开,必须服务打开,本地打开不解析会报错
- 默认严格模式
- script 引入模块 js ,type 设置为 module
export【导出】
export {
// 标识符,标识符,标识符(不是增强语法,只是一种特殊写法)
// 别名 as xxx
}
// 定义变量、函数时就导出,用export关键字
export const name = “xxx”
export function xxx(){
……
}
Import【导入】
// webpack 工具可以省略js后缀,浏览器不行必须加后缀名
improt { xxx, xxx, xxx } from "xxx.js"
// 可以用 as 起给模块别名
import * as xxx from "xxx.js"
import、export 结合写法(开发结构思路)
-
设置 index.js 给多文件统一导出
export {xxx, xxx} from "xxx.js"
default【默认导出】
⚠️ 一个模块只能有一个默认导出
// 相当于没有导出名字
export default 函数名/变量名
// 导入可以起别名
import 别名 from "xxx.js"
import 函数
⚠️声明 是不能放到逻辑代码中的,需要放到 js 代码顶层
使用情景:条件成立才引入
返回的实际是 promise 对象
import meta 属性(ES11)(了解)
- 返回模块的信息
ES Module 解析流程
- 构建:js 下载,生成模块记录
- 实例化:对模块记录进行实例化,分配内存空间 ,解析导出导入语句,模块指向对应的内存地址
- 运行:执行代码,填充 环境记录,分配内存空间
混合使用 commonJS、ES module
- webpack 配置