JavaScript 内核第 7 / 7 章
JavaScript 模块化
整理模块边界、依赖组织与常见模块规范。
模块化
🏢 提示
模块化
- 模块化开发目的是把程序划分成一个小小的结构
- 这个结构由自己的逻辑代码、有自己的作用域,不会相互影响
- 这个结构可以按需暴露自己的变量、函数、对象给其他的结构使用
- 这个结构可以通过某种方式,导入其他结构的变量、函数、对象等 总结 模块就是,有独立作用域,可以导出和导入变量的单独结构 注意: 模块外并未禁止直接修改模块变量
Commonjs
commonjs是一个规范,在node.js和浏览器里均有实现,简称cjs。node中默认使用,在浏览器里需要由Browserify实现,webpack具备对commonjs的实现
🏢 提示
规范内容
- 使用exports关键词实现导出,module.exports
- 使用require函数实现导入
- 模块中的exports是一个空对象
- module是一个对象,它里面有一个属性exports内存指向了模块中的exports对象
- require函数导入的就是上面的module.exports对象,也就是说它们是同一个内存引用
- 所以如果修改了module.exports的指向,直接添加到模块中exports对象上的属性不会被导出
- 如果在导入的模块中,也可以直接修改模块中的属性,虽然可以,但是不要这么做

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
