模块化开发

目前比较主流的模块化规范有一下四种:
CommonJS(服务端)、AMD(外国人出品)、CMD(阿里出品)、ES6模块化(官方出品)。

模块化开发解决的问题:

  1. 污染全局变量
  2. js文件加载顺序
模块化进化历史:
阶段一:一个页面或者一个功能对应一个js文件

在一开始的时候,我们前端一般都会把一个页面的js写在同一个文件,把一个功能写在同一个js文件。在小项目上可能适用,但是在一个大项目中,就得考虑js文件的加载顺序了,因为js文件是从上往下加载的,而且这种方法,都是在全局上申明变量的,有可能造成全局变量污染,将一些数据给覆盖掉。

阶段二:插件化(闭包+自调用函数)

小例子:
index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
  </head>
  <body></body>
  <script src="./a.js"></script>
  <script src="./b.js"></script>
  <script src="./index.js"></script>
</html>

a.js:

const moduleA = (()=>{
	const a = [1,2,3]
	return {
		a
	}
})()

b.js:

const moduleB = ((moduleA) => {
	return {
		b: moduleA.a.reverse()
	}
})(moduleA)

index.js

;((moduleA, moduleB) => {
	console.log(moduleA.a)
	console.log(moduleB.b)
})(moduleA, moduleB)

问:moduleA和moduleB都是全局变量,为什么还要把它作为参数传进去?
答:因为这样可以把moduleA和moduleB做一个缓存。
总结:利用函数的作用域和闭包的,去避免全局变量污染,但是还是得去考虑js的加载顺序。

阶段三:服务端的CommonJS的出现

commonJS是一个模块化开发的规范,是在node.js中的模块化开发规范。
使用案例:
a.js:

const a = 1
module.exports = {
	a
}

index.js:

const {a} = require('./a.js')
console.log(a) // 1

总结:node中会对加载的模块进行一个缓存,当第二次加载的时候就会大大的加快。

AMD的出现

AMD:(Asynchronous Module Definition)异步的模块定义。是国外的民间大佬写的一个模块化规范。AMD依靠requireJS来实现,所以如果想要用AMD的去开发,必须先引入require.js文件。
AMD的基本使用:
index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
  </head>
  <body></body>
  <script src="./require.js"></script>
  <script src="./index.js"></script>
</html>

a.js:

define('moduleA', function() {
	const a = [1,2,3]
	return {
		a
	}
})

b.js:

define('moduleB', ['moduleA'], function (moduleA) {
	return {
		b: moduleA.a.concat([5,6,7])
	}
})

index.js:

require.config({
	paths: {
		moduleA: './js/a',
		moduleB: './js/b'
	}
})
require(['moduleA', 'moduleB'], function (moduleA, moduleB) {
	console.log(moduleA.a) // 输出[1,2,3]
	console.log(moduleB.b) // 输出[1,2,3,5,6,7]
})

AMD的define和require、require.config基础使用解释:
define:该方法用于定义模块,第一个参数是:你定义的模块名(string)。第二个参数(可选):你这个模块所要依赖的模块,是一个字符串类型的数组。第三个参数是:当加载完依赖后进行回调的function。
require: 该方法用于加载模块,第一个参数是:你需要加载的模块,是一个字符串类型的数组。第二个参数:和define方法的第三个参数一样,当加载完依赖进行回调的function。
require.config: 用于配置模块的路径。

require.config({
	paths: {
		moduleA: './js/a',  // 路径,不用写.js,它会自动补充的。加了.js会报错
		moduleB: './js/b'
	}
})

CMD的出现

CMD:通用模块定义(common module define)。是我们阿里写的一个模块化规范。CMD依靠SeaJS去实现。如果你想使用CMD去模块化,就必须引入sea.js。
CMD的简单使用:
index.js

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
  </head>
  <body></body>
  <script src="./js/sea.js"></script>
  <script src="./index.js"></script>
</html>

a.js:

define('moduleA', function(require, exports, module) {
	const a = [1,2,3]
	module.exports = {
		a
	}
})

b.js:

define('moduleB', function(require, exports, module) {
	const moduleA = require('./a.js')
	return {
		b: moduleA.a.concat([4,5,6])
	}
})

index.js

seajs.use(['moduleA', 'moduleB'], function(moduleA, moduleB) {
	console.log(moduleA.a) // [1,2,3]
	console.log(moduleB.b) // [1,2,3,4,5,6]
})

CMD中seajs.use和define这两个方法的基本使用说明:
seajs.use:使用模块的方法,第一个参数是一个字符串数组,表示需要用到的依赖。第二个参数是一个回调函数。
define: 用于定义模块的方法。第一个参数是模块id,第二个参数是一个回调函数,参数是:require、exports、module。这三个参数和CommonJS的用法一样,require用于加载模块,exports用于导出、module下的exports也可以导出,return也可以进行导出。

最终阶段ES6模块化:

ES6模块化:使用ECMAScript官方出,大家日常开发应该用的也比较多,下面就详细的介绍一下:
导入:

import module from '路径'

导出:

export default {}
export {}

各个规范之间的区别:

CommonJS和ES6模块化的区别:

  1. 由于浏览器对于es6的语法不能全面支持,所以ES6的模块是在编译的时候就进行了加载。而node环境是支持CommonJS的,所以CommonJS的模块是在运行的时候加载的。
  2. CommonJS导出的是一个拷贝的值,而且是一个浅拷贝。ES6导出的是引用。

AMD和CMD的区别:

  1. AMD是加载完所有的模块,才进性回调的。这种就依赖前置。
  2. CMD是需要的时候才去加载模块。这种叫做依赖就近、按需加载。
  3. AMD由于先加载所有模块才回调,所以用户体验良好。CMD由于是按需加载,所以性能良好。

CommonJS:有一种缓存机制,第一次的加载模块的时候,会把它缓存下来,下次就直接读取缓存就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值