js 模块化开发(CommonJS、ESModule)

117 阅读4分钟

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 配置