如今的前端工作中,模块化开发成为主流,无论是前端还是后端,由于模块化开发为我们带来巨大的收益,因此开发者都在使用它。模块化开发部分的面试题主要考察应试者对几种模块化开发规范的了解,应试者要明白它们之间的异同点,以及所适用的场合。
相关认识如下:
(1)异步模块定义(AMD)规范是 require. js推广的、对模块定义的规范。
(2)通用模块定义(CMD)规范是 SeaJS推广的、对模块定义的规范。
(3)AMD提前执行,CMD延迟执行
(4)AMD推荐的风格是通过 module transport规范暴露接口,即通过返回一个对象暴露模块接口;CommonJs的风格是通过对 module.exports或exports的属性赋值来达到暴露模块接口的目的。
CommonJS是服务器端模抉的规范, Node. js采用了这个规范。CommonJS规范同步加载模块,也就是说,只有加载完成,才能执行后面的操作。AMD规范则非同步加载模块,允许指定回调函数。
AMD推荐的风格是通过 module transport规范暴露接口,即通过返回一个对象来暴露模块接口, CommonJS的风格是通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。
在Web开发中,通常将项目的实现划分成许多模块。模块化开发其实就是将功能相关的代码封装在一起,方便维护和重用。另外,模块之间通过API进行通信
解决了以下问题:
(1)实现了 JavaScript文件的异步加载。
(2)有助于管理模块之间的依赖性。
(3)便于代码的编写和维护。
解决了以下问题:
(1)各个模块的命名空间独立,A模块的变量x不会覆盖B模块的变量x。
(2)模块的依赖关系,通过模块管理工具(如 webpack、 require.js等)进行管理。
require. js、 SeaJS都是适用于web浏览器端的模块加载器,使用它们可以更好地组织 Javascript代码。
优势如下:
(1)将功能分离出来
(2)具有更好的代码组织方式
(3)可以按需加载。
(4)避免了命名冲突。
(5)解决了依赖管理问题
定义模块,即一个单独的文件就是一个模块,文件中的作用域独立,文件中定义的变量是无法被其他文件引用的。如果需要使用这些变量,需要将其定义为全局变量(不建议)。
输出模块指模块只有一个接口对象,即使用 module. exports对象可以将需要输出的内容放入到该对象中。
加载模块指通过 require加载,例如 var module= require('/ moduleFile. js),该 module的值对应文件内部的 module exports对象,然后就可以通过 module名称引用模块中暴露的接口变量或接口函数了。
就近依赖,需要时再进行加载,所以执行顺序和书写顺序一致;这一点与AMD不同,AMD是在使用模块之前将依赖模块全部加载完成,但由于网络等其他因素可能导致依赖模块下载的先后顺序不一致,这就造成执行顺序可能与书写顺序不一致。
相关了解如下:
(1)类似于 Commonjs,语法更简洁
(2)类似于AMD,直接支持异步加载和配置模块加载
(3)对于结构可以做静态分析、静态检测。
(4)比 CommonJS更妤地支持循环依赖。
原因如下:
(1)高内聚低耦合,有利于团队开发。当项目很复杂时,将项目划分为子模块并分给不同的人开发,最后再组合在一起,这样可以降低模块与模块之间的依赖关系,实现
低耦合,模块中又有特定功能体现高内聚特点。
(2)可重用,方便维护。模块的特点就是有特定功能,当两个项目都需要某种功能时,定义一个特定的模块来实现该功能,这样只需要在两个项目中都引入这个模块就能够实现该功能,不需要书写重复性的代码。
另外,当需要变更该功能时,直接修改该模块,这样就能够修改所有项目的功能,维护起来很方便。
区别如下:
(1)对于依赖的模块,AMD提前执行,CMD延迟执行,不过 require.JS从2.0版本开始,也改成可以延迟执行(根据写法不同,处理方式不同)。
(2)CMD推崇依赖就近,AMD推崇依赖前置。
JavaScript以前只用于实现网页的特效、表单的验证等简单的功能,只需要少量的代码就可以完成这些功能。但随着技术的发展,需要使用 JavaScript处理越来越多的事情,以前许多本来由后台处理的内容都转移到前端来处理,这使代码量急剧膨胀。
如果还是像以前一样书写代码,那么对于后期的维护将非常困难。同时在开发中,我们难免会需要一些“轮子”,如果没有模块( Model)这个概念,我们将很难简便地使用别人制造的“轮子”。
所以,我们需要前端模块化。
前端开发相对其他语言来说比较特殊,因为我们实现一个页面功能总是需要JavaScript、CSS和HTML三者相互交织。
如果一个功能只有 JavaScript实现了模块化, CSS和 Template还处于原始状态,那么调用这个功能的时候并不能完全通过模块化的方式,这样的模块化方案并不是完整的。
所以我们真正需要的是一种可以将 JavaScript 、CSS和HTML同时都考虑进去的模块化方案,而非只使用 JavaScript模块化方案。综上所述,前端模块化并不等同于 JavaScript模块化。
主流的 JavaScript模块化方案都使用“异步模块定义”的方式,这种方式给开发带来了极大的不便,所有的同步代码都需要修改为异步方式。
当在前端开发中使用“ CommonJs”模块化开发规范时,开发者可以使用自然、容易理解的模块定义和调用方式,不需要关注模块是否异步,不需要改变开发者的开发行为。因此 JavaScript模块化并不等同于异步模块化。
遵循以下原则:
(1)在编译时纳入所有依赖。
(2)去中心化,实现分布式
(3)内置命名和封装。
服务器端规范主要是 CommonJS, Node.js用的就是 CommonJS规范客户端规范主要有推崇依赖前置的AMD和推崇依赖就近的CMD。AMD规范的实现主要有 require.js。
CMD规范的主要实现有 SeaJS。但是 SeaJS已经停止维护了,因为在 EMAScript 6 中提供了 EMAScript Module模块化规范,随着 EMAScript 6的普及,第三方的模块化规范的实现将会慢慢地被淘汰。