幼年期:无模块化
成长期: IIFE是立即执行函数表 IIFE其实也就是匿名函数,归根结底都是函数
一种是申明式,一种是表达式。但是两种其实存在着不同,其中第二种中存在着变量提升
function fn1()
var fn = function ()var b = 1 ;
(function () {var b = 2console.log('b的值',b);})()
console.log(b);
成熟期
CJS- commonj =>node.js 制定
特征:通过module+export去对外暴露接口,一个js文件就是一个模块
引入自定义模块
使用require('模块的路径')函数来引入模块
引入自定义模块时
模块名要以 ./或../开头
扩展名可以省略
- 在CommonJS中,如果省略的js文件的扩展名,node会自动补全扩展名
- 如果没有改js文件,会找名字相同的文件进行引入
-
引入核心模块时
- 直接写核心模块的名字即可
- 也可以在核心模块前添加
node:
可以加快查询效率
//引入自定义模块
const m1 = require("./m1")
//按需引入
const name = require('./m1').name
const {name,age,gender} = require('./m1')
//引入核心模块const path = require("path")const path = require("node:path")
通过require进行其他模块的调用
const depModele1 =require('./dependecncyModules1')
const depModule2 =require('./dependecncyModuse2')
let count =0
const obj ={increase:()=>++count;reset()=>{count=0}
}
exports.increase= increase;
exports.insert=reset
module.export={increase,reset
}
> * 优点:
CJS率先在服务实现了从框架层面解决依赖、模块化的问题* 缺憾
针对的是服务端,对于异步依赖没有很友好地处理解决
AMD 规则
它采用异步方式加载模块 。实现了AMD规范的主要的两个JavaScript的两个库:require.js和curl.js
AMD跟CommonJS一样也是通过require来导入,但是区别在于多了一个回调参数。用于导入后执行函数。
> 通过异步加载 + 允许定制回调函数
经典框架:require.js
新增定义方式:
```jsdefine(id, [depModule], callback);require([module], callback);// 栗子 提前声明要依赖的模块define('amdModule', [depModule1, depModule2], (depModule1, depModule2) => {let count = 0;const obj = {increase: () => ++count;reset: () => {count = 0;// fn(depModule1);// depModule1, depModule2}}// ....})// 使用require(['amdModule'], amdModule => {amdModule.increase();})
```
UMD规则
- factory 可以是一个函数或者字符串或者对象。
- 如果 factory 是一个函数,回调函数中会指定三个参数 require,exports,module,表示的是该模块的构造函数。执行构造函数,可以得到模块向外提供的接口。
** 面试:一个代码去兼容AMD和CJS **
```js(function(){// UMD的出现})(// 目标:一次性去区分CJS和AMD// 1. CJS factory// 2. module & module exportsx// 3. definetypeof module === "Object"&& module.exports&& typeof define !== "function"? // 是CJSfactory => module.export = factory(require, exports, module);: // 是CMDdefine)
```
> * 优点:解决了浏览器中异步加载模块,可以并行加载多个模块
* 缺点:会有引入成本,缺少考虑按需加载
```js(function (root, factory) {if (typeof define === 'function' && define.amd) {// AMDdefine(['jquery', 'underscore'], factory);} else if (typeof exports === 'object') {// Node, CommonJS之类的module.exports = factory(require('jquery'), require('underscore'));} else {// 浏览器全局变量(root 即 window)root.returnExports = factory(root.jQuery, root._);}}(this, function ($, _) {// 属性var PI = Math.PI;// 方法function a() { }; // 私有方法,因为它没被返回function b() { return a() }; // 公共方法,因为被返回了function c(x, y) { return x + y }; // 公共方法,因为被返回了// 暴露公共方法return {ip: PI,b: b,c: c}}));```
CMD规范 - sea.js
> 按需加载
```jsdefine('module', (require, exports, module) => {let $ = require('jquery');let depModule1 = require('./dependencyModule1');// ……})
```
新时期:ESM
import : 引入 ,export :导出
```jsimport depModule1 from './dependecncyModule1';import depModule2 from './dependecncyModule2';let count = 0;const obj = {increase: () => ++count;reset: () => {count = 0;// fn(depModule1);// depModule1, depModule2}}export default {increase,reset}// 异步加载import('xxx').then(a => {// ../})
```目标:
1. 隔离每个模块的逻辑和作用域
2. 扩展共同协作的方便程度=> 可以将无数模块进行随意组装 => 万物皆模块
=> 前端工程化