web前端--js模块化

本文详细阐述了JavaScript模块化的演变历程,从早期的IIFE解决全局污染,到CommonJS、AMD、CMD和ES6模块化。讨论了各种模块化方案的优缺点,如CommonJS适用于服务端,AMD解决浏览器异步加载,CMD强调按需加载,而ES6模块化成为新时代标准。同时,提到了前端工程化和打包工具如何进一步优化模块化处理。
摘要由CSDN通过智能技术生成

1、js模块化历史

​ js本身简单的页面设计:页面动画+表单提交

​ 无模块化和命名空间的概念

​ 幼年期:无模块化

​ 1、开始需要在页面中增加一些不同js:动画、表单、格式化等

​ 2、多种js文件被分在不同的文件中

​ 3、不同文件被一个模板引用

​ 出现了jqury.js main.js depl.js

​ 文件分离是基础的模块化第一步,但出现了这些问题

​ * 污染全局作用域 =>不利于大型项目开发、多人团队的共建

​ 成长期:模块化雏形 -IIFE(语法优化)

​ 具体而言就是作用域的把控

//对全局变量的影响
let count = 0;
const increase = ()=>++count;
const reset = ()=>{
    count = 0;
}
//利用块作用域来解决多个函数改变变量产生的冲突
(()=>{
    let count = 0;
})
increase();
reset();
//立即执行
(()=>{
    let count = 0;
})();
//定义最简单的模块(IIFE代码)
const lifeModule = (()=>{
    let count = 0;
    return {
        increase:()=> ++count;
        reset:()=>{
            count = 0;
        }
    }
})();
lifeModule.increase();
lifeModule.reset();
//面试题:有额外依赖时,如何优化IIFE相关代码
//优化1:依赖其他模块的IIFE
const lifeModule = ((dependencyModule1,dependencyModule2)=>{
    let count = 0;
    return {
        increase:()=> ++count;
        reset:()=>{
            count = 0;
        }
    }
})(dependencyModule1,dependencyModule2);
lifeModule.increase();
lifeModule.reset();
//老公司面试1:了解jquery的依赖处理以及模块加载方案吗?(了解窗体IIFE是如何解决多方依赖的问题吗)
//IIFE加传参调配来解决多方依赖
//jquery等框架应用了revealing的写法 revealling是揭示模式
const lifeModule = ((dependencyModule1,dependencyModule2)=>{
    let count = 0;
    return {
        increase:()=> ++count;
        reset:()=>{
            count = 0;
        }
    return {
        ioncrease,reset
    }
   }
})(dependencyModule1,dependencyModule2);
lifeModule.increase();
lifeModule.reset();

//成熟期:
//cjs(node.js制订的方案) - commonjs
//特征:
//*通过module+expoets去对外暴露接口
//通过reuqire来调用其他模块(具体业务场景:下载拉取一个文件进行改变后索引到另外一个id,源文件没有变化,叫伪	  更新)
//模块组织方式
//引入部分
const dependcyModule1 = require(./dependcyModule1);
const dependcyModule2 = require(./dependcyModule2);
//处理部分
let count = 0;
const increase = ()=>count++;
const reset = ()=>{
    count = 0;
}
//暴露的接口
exports.increase = increase;
exports.reset = reset;
module.exports = {
    increase,reset;
}
//模块使用方式
const {increase,reset} = require('./main.js');
increase();
reset();
//可能的面试,运用在sdk上,减少第三方依赖
//实际执行处理 -- commonjs与IIFE结合
(function(thisValue,exports,require,module){
    const dependcyModule1 = require(./dependcyModule1);
	const dependcyModule2 = require(./dependcyModule2);
    //业务逻辑
}).call(thisValue,exports,require,module);
//总结:commonjs的优点
//1、CommonJs率先在服务端实现了,从框架层面解决依赖、全局变量污染的问题
//缺点:
//主要针对服务端的解决方案。服务端数据在硬盘上,同步加载速度也快
//对异步拉取依赖处理整合不是很友好
//commonjs相比于IIFE代码更加易于维护,模块化的特点更加鲜明
//出现了前端的异步依赖问题
//AMD规范
//通过允许制订回调函数解决了异步加载的问题(经典实现框架:require.js)
//新增定义方式
//定义模块
define(id,[depends],callback);
//引入依赖
require([module],callback);

//例子
//amdModule是定义的模块名
//dependencyModule1,dependencyModule2是第三方依赖
define('amdModule',['dependencyModule1,dependencyModule2'],(dependencyModule1,dependencyModule2)=>{
    let count = 0;
	const increase = ()=>count++;
	const reset = ()=>{
    count = 0;
	}
    return {
        increase,reset
    }
});
reuqire(['amdModule'],amdModule=>{
    amdModule.increase();
})
//面试题2:如果在AMDmodule中想兼容已有代码,怎么办?
//1、IIFE实现外部传参 2、define回调函数中require同步和异步加载中的代码切换问题
//面试题3:AMD中使用revealing
//UMD的出现
define('amdModule',[],(require,export,module)=>{
    let count = 0;
	const increase = ()=>count++;
	const reset = ()=>{
    count = 0;
	}
	export.increase = increase();
    export.reset = reset();
})
define(require=>{
    const otherMoudle = require('amdModule');
    otherModule.increase();
    otherModule.reset();
})
//面试题4:兼容AMD和CMD的方法(如何判断是cms还是amd)
(define('amdModule',[],(require,export,module)=>{
    const dependcyModule1 = require(./dependcyModule1);
	const dependcyModule2 = require(./dependcyModule2);
    let count = 0;
	const increase = ()=>count++;
	const reset = ()=>{
    count = 0;
	}
	export.increase = increase();
    export.reset = reset();
}))(
	//目标是一次性区分CMD和AMD
    	typeof module === "object"&&module.exports&&typeof define !== "function"
    				?//是CJS
    				factory=>module.exports = factory(require,exports,module)
    				://AMD
    				define
	)

//amd优点:适合在浏览器中加载异步模块,可以并行加载多个模块
//缺点:不能按需加载,有引入成本
//cmd的规范:出现时为了解决amd的不能按需加载,主要应用在sea.js框架
define('amdModule',[],(require,exports,module)=>{
    let $ = require('jquery');
    //jquery相关逻辑
    let dependencyModule1 = require('./dependcyModule1');
    //dependencyModule1的相关逻辑
})
//优点:按需加载,依赖就近
//缺点:依赖于打包,加载逻辑存在于每个模块中,会扩大模块的体积
//面试题5(开放型问题):amd和cmd的区别
//依赖就近,按需加载
//es6模块化:走向新时代
//新增定义:引入关键字--import
//		  导出关键字--export
  import dependencyModule1 from './dependencyMoudule1.js';
  import dependencyModule2 from './dependencyMoudule2.js';
    const dependcyModule1 = require(./dependcyModule1);
	const dependcyModule2 = require(./dependcyModule2);
    let count = 0;
	export const increase = ()=>count++;
	export const reset = ()=>{
    	count = 0;
	}
    //导出区域
    export default {
        increase,reset
    }
//模板引入的地方
<script type="module" src="esModule.js"></script>
//node中
//mjs就是一个文件后缀,是nodejs中使用es module 规范需要使用的js文件的后缀
import {increase,reset} from './esModule,mjs';
esModule.increase()
esModule.reset()
//面试题6:import如何解决动态模块(考察export promise)
//es11原生解决方案:
import('./esModule.js').then(dynamicEsModule=>{
    dynamicEsModule.increase();
})
//es6模块化的优点:统一的形态整合了js的模块化
//局限性:本质还是只做了运行时的依赖分析对代码进行局部的调整
//解决模块化的新思路:前端工程化
//出现的背景:前端的模块化处理方案依赖于运行时进行分析
//解决方案:打包和预编译线下执行
//grunt gulp webpack

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值