模块化开发
将项目中内容/ 功能 相同的部分 开发成一个独立的文件(模块), 哪个页面需要这个内容 / 功能 就导入 这个独立的文件, 加载使用其中定义的程序
模块化开发 和 script标签导入外部文件区别
外部文件导入
外部文件导入的顺序 不清晰
外部文件的导入数据 谁先谁后 能不能改变顺序 不清楚
外部文件导入的依懒性 不清晰
使用了那个文件中的那个函数 不清楚
没有防止全局变量污染
前端模块化开发的基本介绍
-
没有模块化的时代外部文件导入
-
模块化的洪荒时代IIFE使用 立即执行函数 解决 全局变量污染问题
-
模块化的标准化时代AMD CMD通过导入外部文件 执行设定好的模块化开发模式
-
模块化的当前使用方式ES6模块化开方式配合框架语法
IIFE(Immediately Invoked Function Expression) 立即调用函数
使用立即执行函数 防止全局变量污染 , 将全局变量定义在函数中 变成局部变量
向 window 新增属性属性值 存储数据 就可以通过window调用设定的数据
文件1a.js
// 这是一个 独立模块
// 自己定义程序自己执行 不需要其他模块中的数据
(function(){
// 将全局变量定义在 立即执行函数中
let name = '张三' ;
let age = 18 ;
let sex = '男';
const arr = [100,200,300,400];
const obj = { addr:'北京' , phone:123456 , email:'123@qq.com' };
// 将 之前的全局变量数据 使用一个对象 都定义在 window中
window.modeA = { name , age , sex , arr , obj };
})()
文件2b.js
// 模块B是一个依赖模块
// 在模块B中需要模块A的数据
// 通过立即执行函数的传参语法 向立即执行函数传参模块A的数据
(function( val ){
// console.log( val );
let name = '李四';
let age = val.age + 2 ;
let sex = '女' ;
const arr = val.arr.map( item => {
return item * 2 ;
})
const obj = val.obj ;
window.modeB = { name , age , sex , arr , obj };
})( window.modeA );
demo.html
/*
IIFE
Immediately Invoked Function Expression
立即调用函数表达式
使用立即执行函数 防止全局变量污染
将全局变量 定义在函数中 变成局部变量
向 window 新增属性属性值 存储数据
就可以通过window调用设定的数据
*/
// window是JavaScript定义的一个对象
console.log( window );
// 给window对象新增属性
window.name = '张三' ;
window.age = 18 ;
// 调用模块A 定义在 window中 对象的数据
console.log( window.modeA.name );
AMD(Asynchronous Module Definition)
概念
AMD是js社区 开发一种 前端模块化解决方案,需要导入一个require.js的文件
特点
前置依赖
一次性导入所有模块化文件,上一个导入的模块没有执行完毕 下一个导入的模块不会触发执行
页面首次打开时 会比较卡顿,之后页面的浏览执行 就不会卡顿了,一般用于大型页面的设定
基本语法
独立模块
define( function(){
定义数据和程序
return { 当前模块导出的数据和函数 };
})
依赖模块
define( ['导入模块1' , '导入模块2' ...] , function( 参数1 , 参数2 ... ){
参数1 存储 导入模块1 的数据
参数2 存储 导入模块2 的数据
....
return { 当前模块导出的数据和函数 };
})
整合模块
require( ['导入模块1' , '导入模块2' ...] , function( 参数1 , 参数2 ... ){
参数1 存储 导入模块1 的数据
参数2 存储 导入模块2 的数据
....
调用 导入的模块数据和函数
})
html文件
只需要导入 最终的 整合模块文件就可以
html文件
<!-- 导入 AMD 外部文件 -->
<script src="./require.js"></script>
<!-- 只需要导入整合模块 -->
<script src="./c.js"></script>
独立模块
// 独立模块
// 通过 define(函数(){}) 设定 模块A
// 在 函数中 使用 return的语法形式 导出模块A的数据
define(function(){
// 定义的数据
let name = '张三' ;
let age = 18 ;
let sex = '男' ;
const arr = [100,200,300,400];
const obj = { addr:'北京' , phone : 123456 , email:'123@qq.com' };
function fa1(){};
function fa2(){};
function fa3(){};
// 导出数据
// return的数据 通过 define函数
// 将 return 的数据 作为 模块A 导出的数据
return { name , age , sex , arr , obj , fa1 , fa2 , fa3 };
});
依赖模块
// 依赖模块
// 需要依赖模块A中的数据
// 依赖模块 define( 参数1 , 参数2 )
// 参数1 是 以数组的形式 设定要导入的模块
// 参数2 是 模块B的设定 函数的参数是 对应的导入的模块的数据
define( ['./a.js'] , function( valA ){
// console.log( valA );
let name = '李四' ;
let age = valA.age - 5 ;
let sex = '女' ;
const arr = valA.arr.map( item => {
return item / 4 ;
})
const obj = valA.obj ;
function fb1 (){}
function fb2 (){}
function fb3 (){}
function fb4 (){}
return { name , age , sex , arr , obj , fb1 , fb2 , fb3 , fb4 };
})
整合模块
// 整合模块
// 将 所有需要执行的模块 都导入这一个文件中
// html文件只要导入这个整合模块就行了
// 独立模块 依赖模块 都不能直接独立的代入html文件
// 一定是通过 整合模块 整合 独立模块 依赖模块
// 导入的是 整合模块
require( ['./a.js' ,'./b.js' ] , function( valA , valB ){
// 模块A 模块B 的数据
console.log( valA );
console.log( valB );
})
CMD(Common Module Definition)
是 淘宝公司 玉伯团队开发的前端模块化解决方案
参考了后端 commonJS 模块化开发方式,需要导入 sea.js 外部文件
特点
即时依赖
需要哪个模块执行 导入哪个模块
首次打开页面 会比较流畅 之后页面的浏览执行 会出现卡顿问题
一般用于时效性强的页面
抢购 秒杀
基本语法
独立模块
define(function( 参数1, 参数2 , 参数3 ){
设定 数据 和 函数方法
参数3.exports = { 导出的数据 };
})
依赖模块
define(function( 参数1, 参数2 , 参数3 ){
const 变量1 = 参数1('导入模块文件的路径');
const 变量2 = 参数1('导入模块文件的路径');
const 变量3 = 参数1('导入模块文件的路径');
....
设定 数据 和 函数方法
参数3.exports = { 导出的数据 };
})
整合模块
seajs.use( ['导入模块文件路径' , '导入模块文件路径' , '导入模块文件路径' ..] , function( 参数1 , 参数2 ... ){
参数1, 参数2 存储 对应的外部文件导出的数据
})
html文件
<!-- 导入外部 sea.js 文件 -->
<script src="./sea.js"></script>
<!-- 导入整合模块文件 -->
<script src="./c.js"></script>
独立模块
// 独立模块
define(function( require , exports , module ){
// 定义数据和函数方法等
let name = '张三' ;
let age = 18 ;
let sex = '男' ;
const arr = [100,200,300,400];
const obj = { addr:'北京' , phone : 123456 , email:'123@qq.com' };
function fa1(){};
function fa2(){};
function fa3(){};
// 当前模块导出数据
module.exports = { name , age , sex , arr , obj , fa1 , fa2 , fa3 };
})
依赖模块
// 依赖模块
// 依赖模块A的数据
define(function( require , exports , module ){
// 导入 模块A 的数据
const valA = require('./a.js');
let name = '李四' ;
let age = valA.age - 5 ;
let sex = '女' ;
const arr = valA.arr.map( item => {
return item / 100 ;
})
const obj = valA.obj ;
function fb1 (){}
function fb2 (){}
function fb3 (){}
function fb4 (){}
// 导入当前模块的数据
module.exports = { name , age , sex , arr , obj , fb1 , fb2 , fb3 , fb4 };
});
整合模块
// 整合模块
// 整合模块A 和 模块B 的数据和函数方法
seajs.use( ['./a.js' , './b.js'] , function( valA , valB ){
// 参数 valA 存储 第一个文件 模块A 导出的数据
// 参数 valB 存储 第二个文件 模块B 导出的数据
console.log( valA );
console.log( valB );
})