Visual LabINTERACTIVE LEARNING
JavaScript 内核第 7 / 7 章

JavaScript 模块化

整理模块边界、依赖组织与常见模块规范。

this原型异步
进阶预计 65 分钟查看源文 ↗

模块化

🏢 提示

模块化

  • 模块化开发目的是把程序划分成一个小小的结构
  • 这个结构由自己的逻辑代码、有自己的作用域,不会相互影响
  • 这个结构可以按需暴露自己的变量、函数、对象给其他的结构使用
  • 这个结构可以通过某种方式,导入其他结构的变量、函数、对象等 总结 模块就是,有独立作用域,可以导出和导入变量的单独结构 注意: 模块外并未禁止直接修改模块变量

Commonjs

commonjs是一个规范,在node.js和浏览器里均有实现,简称cjs。node中默认使用,在浏览器里需要由Browserify实现,webpack具备对commonjs的实现

🏢 提示

规范内容

  1. 使用exports关键词实现导出,module.exports
  2. 使用require函数实现导入
  1. 模块中的exports是一个空对象
  2. module是一个对象,它里面有一个属性exports内存指向了模块中的exports对象
  3. require函数导入的就是上面的module.exports对象,也就是说它们是同一个内存引用
  4. 所以如果修改了module.exports的指向,直接添加到模块中exports对象上的属性不会被导出
  5. 如果在导入的模块中,也可以直接修改模块中的属性,虽然可以,但是不要这么做

飞书画板

ESModule

📚 提示

js原生的模块化方案,ES6后引入,使用import 和export 关键词,实现模块隔离 注意: 模块外不能直接修改模块内变量,否则会抛出错误 它可以实现静态分析 这是与commonjs最大的区别

Export

❤️ 提示

导出声明不受暂时性死区规则的限制。你可以在声明名称 X 之前声明当前模块导出 X

// export default value/func/name 值/函数名/变量名
// 1. export default  默认导出
export default 1
export default function(){}
function foo(){}
export default foo

// 2. 分别导出
// export const/let/const // 单独去在定义时导出
const abc = 0
export { abc } // 最后统一导出
export { abc as default } // 分别导出重命名 
/**
  注意
   1. defualt是一个关键词,上面这样写与 export default 相同
   2. export {} 是一个语句,后面的花括号并不是一个对象,不能使用对象增强语法 ,只能使用as重命名,
   是用花括号括起来的用逗号分割的列表
*/ 

// 导出声明
export let name1, name2/*, … */; // also var
export const name1 = 1, name2 = 2/*, … */; // also var, let
export function functionName() { /* … */ }
export class ClassName { /* … */ }
export function* generatorFunctionName() { /* … */ }
export const { name1, name2: bar } = o;
export const [ name1, name2 ] = array;

// 导出列表
export { name1, /* …, */ nameN };
export { variable1 as name1, variable2 as name2, /* …, */ nameN };
export { variable1 as "string name" };
export { name1 as default /*, … */ };

// 默认导出
export default expression;
export default function functionName() { /* … */ }
export default class ClassName { /* … */ }
export default function* generatorFunctionName() { /* … */ }
export default function () { /* … */ }
export default class { /* … */ }
export default function* () { /* … */ }
Import
//1. 导入默认模块
import xxx from './xxx'
//2. 导入分别导出
import { abc,cbd } from './xxx'
//3. 一起结合
import * as aModule from './xxx' //方式一
import { default as aModule,abc ,cbd } from './xxx' // 方式二
import aModule,{ abc ,cbd } from './xxx' //方式三

// 官方例子
import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { default as alias } from "module-name";
import { export1, export2 } from "module-name";
import { export1, export2 as alias2, /* … */ } from "module-name";
import { "string name" as alias } from "module-name";
import defaultExport, { export1, /* … */ } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name"; //副作用导入,只是为了执行一个模块内的代码
结合简化
export * from "x.js";
export { name } from "x.js";
export { defualt as name, nameb } from "x.js";

// 导出模块合集
export * from "module-name";
export * as name1 from "module-name";
export { name1, /* …, */ nameN } from "module-name";
export { import1 as name1, import2 as name2, /* …, */ nameN } from "module-name";
export { default, /* …, */ } from "module-name";
export { default as name1 } from "module-name";
动态导入
import("/modules/mymodule.js").then((module) => {// Do something with the module.});

🍞 提示

Import 按MDN的说法并不是一个函数,而是类函数的方式调用,它是一个关键词 MDN- import