说说对模块化的理解
# 是什么
- 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
- 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
# 特性
- 对外联系接口
- 内部功能
# 怎么用
# 为什么要模块化
- 代码抽象
- 代码封装
- 代码复用
- 依赖管理
没有模块化, 会怎样?
- 变量和方法不容易维护, 容易全局污染
- 加载js资源从上到下
- 依赖不分
- 大型项目难以维护
# 模糊化发展历程
IIFE AMD CMD CommonJs ESM
- AMD
代表为require.js
/** main.js 入口文件/主模块 **/
// 首先用config()指定各模块路径和引用名
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min", //实际路径为js/lib/jquery.min.js
"underscore": "underscore.min",
}
});
// 执行基本操作
require(["jquery","underscore"],function($,_){
// some code here
});
- CommonJs(nodejs中常用)
// a.js
module.exports={ foo , bar}
// b.js
const { foo,bar } = require('./a.js')
# 既然存在了AMD以及CommonJs机制,为什么还要ES6的Module呢
ES6在语言的层面上,实现了Module, 完全可以取代CommonJs和AMD规范,成为浏览器和服务端通用的模块解决方案。(更牛逼点)
# 区别
- CommonJs和AMD模块都只能在运行时确定执行东西
- ES6设计思想就是尽量的静态化, 使得
编译时就能确定模块的依赖关系,以及输入和输出的变量 - CommonJS 模块输出的是一个
值的拷贝,ES6 模块输出的是值的引用 - CommonJS 模块是
运行时加载,ES6 模块是编译时输出接口 - ES6 模块是
动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
// CommonJS模块
let { stat, exists, readfile } = require('fs');
// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
// ES6模块
// 只加载3个方法,其他方法不加载
import { stat, exists, readFile } from 'fs';
# 使用
- export
// test.js
export const name = 'fangdown'
export const foo = () => {}
export default foo
- import
import {foo, name} from './test.js'
import * as Test from './test.js'
- import会提升到整个模块的头部,首先执行
- 多次重复执行同样的导入,只会执行一次
# 动态加载
允许您仅在需要时动态加载模块,而不必预先加载所有模块,这存在明显的性能优势
这个新功能允许您将import()作为函数调用,将其作为参数传递给模块的路径。它返回一个 promise,它用一个模块对象来实现,让你可以访问该对象的导出
import('/modules/test.mjs')
.then((module) => {
// Do something with the module.
});
# 原理
# FAQ
上次更新: 2021/12/19, 18:05:42