文章目录
一、前端模块化开发
1.1 什么是模块化?
模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。模块化规范就是对代码进行模块化的拆分与组合时需要遵守的那些规则。
编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块
简单来说,模块化就是把系统分成各个独立的部分,每个部分单独实现功能,将系统分割成多个可独立的功能部分。
1.2 为什么要使用模块化?
当我们在一个html文件中引入了多个js文件,此时需要依赖多个模块,就意味着会发送多个请求,从而导致请求过多。
同时我们不知道他们的具体依赖关系是什么,也就是说很容易因为不了解他们之间的依赖关系导致加载先后顺序出错。
将不同的功能封装成不同的全局函数时会导致全局变量污染, 容易引起命名冲突或数据不安全,而且模块成员之间看不出直接关系,这也间接导致我们所写出的代码难以维护。
1.3 使用模块化开发有什么好处?
-
所有代码都运行在模块作用域,不会污染全局作用域,提高了代码的可维护性。
-
模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
-
模块加载的顺序,按照其在代码中出现的顺序。
-
想要什么功能,就加载什么模块,可以实现按需加载。
1.4 代码实现模块化的方法
前端模块规范有三种:commonjs,AMD和CMD。
-
commonjs用在服务器端,AMD和CMD用在浏览器环境
-
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。提前执行(异步加载:依赖先执行)+延迟执行
-
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。延迟执行(运行到需加载,根据顺序执行
二、代码实现模块化
2.1 认识node.js中的模块化

2.1.1 加载模块
使用强大的require()方法,可以加载需要的内置模块、用户自定义模块、第三方模块进行使用。
// 加载内置的fs模块
const fs = require('fs')
// 加载用户的自定义模块,需要写出完整的路径(.js后缀名可写可不写)
const yiyi = require('demo2.js')
// 加载第三方模块
const moment = require('moment')
需要注意的是:在使用require进行加载时,会同时执行被加载的代码。


2.1.2 模块作用域
和函数作用域类似,在自定义模块中定义的变量、方法等成员只能在当前模块内被访问。这种模块级别的访问限制叫做模块作用域。这样就可以防止全局变量被污染的问题。


2.1.3 module对象
每个JS自定义模块中都有一个module对象,它里面存储了和当前模块有关的信息
查看module对象
console.log(module);

2.1.4 向外共享模块作用域中的成员
在自定义模块中,可以使用module.exports对象将模块内的成员共享出去,供外界使用
在外界使用require导入一个自定义模块的时候,得到的成员就是那个模块中通过module.exports指向的那个对象,默认情况下等于空对象


需要注意的是:
使用require()方法导入模块时,导入的结果永远以module.exports指向的对象为准


2.1.5 exports对象



exports 和 module.exports 的使用误区

2.2 commonjs依赖
commonjs是node.js遵守的CommonJS Modules/1.0模块化规范,commonjs 规范应用于 nodejs 应用中,在 nodejs 应用中每个文件就是一个模块,拥有自己的作用域,文件中的变量、函数都是私有的,与其他文件相隔离。在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
commonjs规范规定
-
每个模块内部, module 变量代表当前模块。
-
module 变量变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。
-
加载某个模块,其实是加载该模块的 module.exports 属性。
由于CommonJS是同步加载模块,这对于服务器端不是一个问题,因为所有的模块都放在本地硬盘。等待模块时间就是硬盘读取文件时间,很小。但是,对于浏览器而言,它需要从服务器加载模块,涉及到网速,代理等原因,一旦等待时间过长,浏览器处于”假死”状态。
对于模块的依赖,CommonJS是动态的(动态是指对于模块的依赖关系建立在代码执行阶段),CommonJS导入的是值的拷贝,所以在浏览器端,不适合于CommonJS规范。所以在浏览器端又出现了一个规范—-AMD。
2.3 AMD
CommonJS解决了模块化的问题,但这种同步加载方式并不适合于浏览器端。
AMD是”Asynchronous Module Definition”的缩写,即”异步模块定义”。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。
这里异步指的是不堵塞浏览器其他任务(dom构建,css渲染等),而加载内部是同步的(加载完模块后立即执行回调)。
AMD也采用require命令加载模块,但是不同于CommonJS,它要求两个参数:
require([module], callback);
第一个参数[module],是一个数组,里面的成员是要加载的模块,callback是加载完成后的回调函数。
//math.js
exports.add = function(a, b) {
return a + b;
}
var math = require('math');
math.add(2, 3); //
如果将上述的代码改成AMD方式:
require(['math'], function(math) {
math.add(2, 3);
})
其中,回调函数中参数对应数组中的成员(模块)。
requireJS加载模块,采用的是AMD规范。也就是说,模块必须按照AMD规定的方式来写。
具体来说,就是模块书写必须使用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接写在define()函数之中。
define(id?, dependencies?, factory);
-
id:模块的名字,如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字;
-
dependencies:模块的依赖,已被模块定义的模块标识的数组字面量。依赖参数是可选的,如果忽略此参数,它应该默认为 [“require”, “exports”, “module”]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。
-
factory:模块的工厂函数,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
假定现在有一个math.js文件,定义了一个math模块。那么,math.js书写方式如下:
// math.js 里面只定义了factory
define(function() {
var add = function(x, y) {
return x + y;
}
return {
add: add
}
})
加载方法如下:
// main.js
require(['math'], function(math) {
alert(math.add(1, 1));
})
如果math模块还依赖其他模块,写法如下:
// math.js 里面定义了 dependencies factory
define(['dependenceModule'], function(dependenceModule) {
})
当require()函数加载math模块的时候,就会先加载dependenceModule模块。当有多个依赖时,就将所有的依赖都写在define()函数第一个参数数组中,所以说AMD是依赖前置的。这不同于CMD规范,它是依赖就近的。
2.4 CMD
CMD推崇依赖就近,延迟执行。可以把你的依赖写进代码的任意一行,如下:
define(factory)
1
factory为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module.
define(function(require, exports, module) {
var a = require('./a');
a.doSomething();
var b = require('./b');
b.doSomething();
})
如果使用AMD写法,如下:
define(['a', 'b'], function(a, b) {
a.doSomething();
b.doSomething();
})
AMD和CMD都是用difine和require,但是CMD标准倾向于在使用过程中提出依赖,就是不管代码写到哪突然发现需要依赖另一个模块,那就在当前代码用require引入就可以了,规范会帮你搞定预加载,你随便写就可以了。但是AMD标准让你必须提前在头部依赖参数部分写好。这就是最明显的区别。
总结
学会了代码模块化,就能使得我们的代码具有更高的质量和执行能力,使代码更加优化、高效。
本文介绍了前端模块化的概念、原因和好处,详细讲解了Node.js中的模块化,包括require()加载模块、模块作用域、module和exports对象。此外,对比分析了CommonJS、AMD和CMD三种模块规范,阐述了它们的特点和应用场景,帮助理解如何在实际开发中实现代码模块化。

357

被折叠的 条评论
为什么被折叠?



