关于js的模块化,如下图
commonjs的规范之前有提到过,我们这里就不再提了,我们知道commonjs适用于服务端。不适合浏览器。这是为什么呢?因为它是同步的。我们可以想一想:
浏览器获取每一个文件,都需要发送请求,去服务器取回来,如果网速非常的慢,那么浏览器就会一直等require的那个文件返回,就会出现页面卡在那里。阻塞后续代码的执行。用户体验很不好。
下面再来说说其他模块化的东西:
requirejs
是一个工具库,定义了模块定义和模块加载功能。AMD是在requirejs推广的过程中形成的模块化规范。
下面来看一下requirejs的具体使用
首先需要引入
<script src="require.js"></script>
<script src="a.js"></script>
因为requirejs提供了一个全局的define函数来定义模块,所以在requirejs之后引入的文件,都可以使用define来定义模块。
define(id?,dependencies?,factory)
id:
可选参数,模块的标识。
dependencies:
可选参数,是一个数组,注明当前模块所要依赖的模块,如果没有依赖,则可以不写。
factory:
工厂方法,模块初始化要执行的函数或对象。如果是函数,则只执行一次,函数的返回值,就是模块的导出值。如果是对象,则该对象就是模块的导出值。
//a.js
define(function(){
var name='tom';
retrurn {
name}
})
//b.js
define(['a.js'],function(a){
var name='jerry';
console.log(a.name);
return {
name};
})
requirejs采用异步的方式加载模块,模块的加载不影响后续代码的执行,所有依赖这个模块的代码,都写在回调函数中,等模块加载完成之后再去执行。
requirejs的基本思想就是使用define定义模块,当开始执行这块代码的时候,它先加载这个模块所依赖的模块,等所依赖的模块加载完成之后,再去执行回调函数,回调函数返回的值,就是当前模块的导出值。
seajs
CMD是在seajs推广的过程中,对模块化规范的产物。
Sea.js 官网这么介绍 Sea.js:
Sea.js 追求简单、自然的代码书写和组织方式,具有以下核心特性:简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码。 自然直观的代码组织方式:依赖的自动加载、配置的简洁清晰,可以让我们更多地享受编码的乐趣。
具体使用:和requirejs类似
<script src="sea.js"></script>
<script src="a.js"></script>
引入 sea.js 工具库,就是这个库提供了定义模块、加载模块等功能。它提供了一个全局的 define 函数用来定义模块。所以在引入 sea.js 文件后,再引入的其它文件,都可以使用 define 来定义模块。
//a.js
define(function(require,exports,module){
var name = 'morrain'
exports.name = name
})
//b.js
define(function(require, exports, module){
var name = 'lilei'
var a = require('a.js')
console.log(a.name) // 'morrain'
exports.name = name
})
我们可以看到seajs并没有像requirejs那样,先需要把依赖写在一个数组中。它的工作方式是当b.js被加载后,seajs会扫描b.js这个文件,找到require这个关键字,提取所有的依赖,然后去加载。加载完成后,再去执行回调函数,所以当再次执行到require('a.js')的时候,a.js已经存在了。
参考:https://zhuanlan.zhihu.com/p/113009496