谈谈前端JS的三种模块化规范(AMD,CMD,CommonJS)

模块化规范是什么?

将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起,完成指定工作

为什么要有这个东西?

存在即合理是最好的解释,这能帮助我们更好的管理各个js文件,处理不同模块间的依赖关系


  • 举个例子,用jquery要先引包,如果你在使用后才引入,那没得玩,然而新手可能并不清楚一大堆js文件之间存在先后顺序和依赖关系,很容易一个错误找半天。
  • 而且,这也和浏览器解析js顺序有关,从上到下解析,a.js,b.js,c.js,依次引入,实际上c.js不需要任何依赖,就是打印一个helloworld,这种情况浏览器依旧需要先把上边两个js加载完。无效加载,浪费时间,没有主次。
  • 换一种想法,用到哪个加载哪个岂不美哉?模块化规范就是这个时候诞生的。

AMD规范(以require.js为例)

AMD规范 Asynchronouse Module Defined,异步模块定义,AngularJS+RequireJS是符合AMD规范的
AMD规范使用依赖注入的模式,所有当前模块依赖的模块,都要通过异步来调用,执行语句放在回调函数里面。不依赖其他模块的语句,就不要放在回调函数里面,不干扰其他模块的运行。

官网

hello world

  • 目录结构
    在这里插入图片描述
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>require.js之hello world</title>
</head>
<body>
		<h1></h1>
<!-- 	这里main.js是入口文件,可以省略拓展名 -->
<script data-main="main" src="https://cdn.bootcss.com/require.js/1.0.8/require.min.js"></script>
</body>
</html>
  • main.js
document.querySelector("h1").innerHTML="hello world";
  • 效果图
    在这里插入图片描述

单一模块加载

  • 目录结构
    在这里插入图片描述
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>require.js之模块加载</title>
</head>
<body>
		<h1></h1>
<!-- 	这里main.js是入口文件,可以省略拓展名 -->
	<script data-main="js/main" src="https://cdn.bootcss.com/require.js/1.0.8/require.min.js"></script>
</body>
</html>
  • main.js
//SPA我们习惯性的只留入口文件在最外边,其他的单独放文件夹里
//配置相对于index.html的js文件夹路径
requirejs.config({
    baseUrl: 'js'  
});

//注入依赖模块,此时必须省略.js
requirejs(["math"],function (math) {
    document.querySelector("h1").innerHTML=math.add(1,2);
});
  • math.js

//每一个功能模块都用的define包起来,里边的[]用来注入其他依赖模块
//模块暴露的API用return来返回
//这一点很像angular中的factory
//下面定义了一个简单的求和函数并向外暴露
define([],function(){
	return {
		add : function(num1,num2){
			return num1+num2;
		}
	}
});

  • 可以看到上述代码执行是有顺序的,先等依赖加载完,自己才能够运行
    在这里插入图片描述

  • 这种不需要依赖的可以裸着写,直接就执行了

多模块加载和路径配置

  • 目录结构
    在这里插入图片描述

  • 这里就只粘贴主要代码了

  • main.js

//SPA我们习惯性的只留入口文件在最外边,其他的单独放文件夹里
//配置相对于index.html的js文件夹路径
//由于依赖的sub模块和main.js不在同一个文件夹,所以需要用paths配置一下相对路径
requirejs.config({
    baseUrl: 'js' ,
    paths : {
    	"sub" : "other/sub"//注意,不要加.js
    } 
});

requirejs.config({
    baseUrl: 'js',
    
});
//注入依赖模块,此时必须省略.js
requirejs(["math","sub"],function (math,sub) {
    document.querySelector("h1").innerHTML=math.add(1,2);
    document.querySelector("h2").innerHTML=sub.do_sub(2,1);
});


  • sub.js

//每一个功能模块都用的define包起来,里边的[]用来注入其他依赖模块
//模块暴露的API用return来返回
//这一点很像angular中的factory
//下面定义了一个简单的求差函数并向外暴露
define([],function(){
	return {
		do_sub : function(num1,num2){
			return num1-num2;
		}
	}
});

  • 最终结果一个3一个1

CMD规范(以Sea.js为例)

CMD规范 Common Modeule Defined,普通模块定义。对于依赖的模块,AMD讲究的是提前注入,管他这会用不用,先注入再说,CMD是延迟执行,什么时候用什么时候注入。

  • 目录结构
    在这里插入图片描述

  • 大体和上边的amd差不多

  • index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>sea.js</title>
</head>
<body>
	<script src="https://cdn.bootcss.com/seajs/1.3.1/sea.min.js"></script>
	<script >
		//与js文件夹的相对路径
	 	seajs.config({
			base: "js"
		});
		// 加载入口模块
		seajs.use("main");
	</script>

</body>
</html>
  • math.js
//下面定义了一个简单的求和函数并向外暴露

define(function(require,exports,module){
	//暴露
	exports.add = function(num1,num2){
		return num1+num2;
	}
});
  • main.js

//这里使用define()来包裹模块,里面有一个函数,内置require、exports、module对象:
define(function(require,exports,module){
	//声明依赖,这里省略.js与否都行,用哪个require哪个
	var math = require("./math");
	console.log(math.add(1,2));
	var sub = require("./other/sub.js");
	console.log(sub.do_sub(2,1));

});
  • sub.js

//下面定义了一个简单的求差函数并向外暴露
define(function(require,exports,module){
	//暴露
	exports.do_sub = function(num1,num2){
		return num1-num2;
	}
});
  • 效果图
    在这里插入图片描述

CommonJS

Node使用CommonJS模块规范,内置的require命令用于加载模块文件。这个没什么好说的,想搞懂这个,学学node好了

  • 目录结构
    在这里插入图片描述

  • a.js
//直接向外暴露属性,方法
exports.name = "冷月心";
exports.say = function () {
  console.log("你好");
}
  • b.js
//加载
var a= require('./a.js');
//使用
console.log(a.name);
a.say();
  • 效果图
    在这里插入图片描述

node 中自定义模块注意require加载的路径问题,相对路径./不能省略,可以省略.js,直接加载模块名字的是核心模块,node内置,比如path,fs,os

构建工具webpack

webpack是CMD规范的构建工具,可以让我们裸写CMD规范的程序,帮我们自动打包成为一个js文件。这个js文件浏览器可以识别,用的时候引入就好,和引jquery方式一样。这里简单介绍webpack编译CMD规范代码的能力。

  • 目录结构

在这里插入图片描述

  • main.js
var math = require("./math");
console.log(math.add(1,2));
  • math.js
exports.add = function(m,n){
	return m+n;
}
  • 全局安装webpack后,进入js文件夹
    webpack main.js all.js

  • 效果如下
    在这里插入图片描述

  • index.html引入all.js

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>webpack</title>
</head>
<body>`在这里插入代码片`
	<script type="text/javascript" src="js/all.js"></script>
</body>
</html>
  • 效果图
    在这里插入图片描述

  • 为了方便,引入了配置文件webpack.config.js
var webpack = require('webpack')

module.exports = {
  entry: './js/main.js',//入口
  output: {//出口
    path: __dirname,// 项目根目录
    filename: './dist/all.js'//文件名
  },
  watch : true//热监听,实时监听代码状态,修改代码后,保存,会自动更新all.js
}
  • 使用:直接webpack
  • 热监听效果图
    在这里插入图片描述

学习资源推荐https://blog.csdn.net/qq_42813491/article/details/90213353

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值