所谓前端开发,就是前台,常见的包括几个端:PC、pad、手机、其他智能设备,可以跑浏览器的地方就是我们前端人大施拳脚的乐土。自从node的问世,现在不光可以在浏览上了,疆土可以扩展到服务端即后台。这样一来JavaScript又牛了一级有着前后台通吃的能力,当然操作太底层的东西还需要Java等传统后台语言。随着电脑手机等智能设备性能配置、网络带宽、技术等提升,我们可以把网页做的更炫酷,更复杂、交互更加人性化也不会卡顿。但是这么搞下去,大量的js脚本代码略显其不好管理维护及团队配合开发,有些杂牌军的感觉。于是模块化开发应运而生。
![]()
模块化ES5及之前是如何实现模块化的
通过RequireJS实现:
一提到模块化,常说到CommonJS和AMD。这俩主要是个什么东西呢,记住是模块化的标准规范即可。而RequireJS就是AMD规范的最好实现。就像ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。我们只需要知道,实现CommonJS规范的API是同步加载模块的,而实现AMD规范的API是则是异步加载模块,异步加载即非阻塞加载,更加适合浏览器端。官方文档对RequireJS的描述:
RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node.使用RequireJS加载模块化脚本将提高代码的加载速度和质量。
RequireJS优点:
异步“加载”。我们知道,通常网站都会把script脚本的放在html的最后,这样就可以避免浏览器执行js带来的页面阻塞。使用RequireJS,会在相关的js加载后执行回调函数,这个过程是异步的,所以它不会阻塞页面。
按需加载。通过RequireJS,你可以在需要加载js逻辑的时候再加载对应 的js模块,这样避免了在初始化网页的时候发生大量的请求和数据传输,或许对于一些人来说,某些模块可能他根本就不需要,那就显得没有必要。
更加方便的模块依赖管理。相信你曾经一定遇到过因为script标签顺序问题而导致依赖关系发生错误,这个函数未定义,那个变量undefine之类的。通过RequireJS的机制,你能确保在所有的依赖模块都加载以后再执行相关的文件,所以可以起到依赖管理的作用。
更加高效的版本管理。想一想,如果你还是用的script脚本引入的方式来引入一个jQuery2.x的文件,然后你有200个页面都是这么引用的,那当你想换成jQuery3.x,那你就不得不去改这200个页面。但是如果你的requireJS有在config中做jQuery的path映射,那你只需要改一处地方即可。
RequireJS 使用
需要在页面中引入的文件
<script data-main="js/main" src="xxx/xxx/require.js"></script>
使用RequireJS,你只需要引入一个require.js即可。你的页面上只需要通过\<script\>标签引入这一个js即可。然后这个页面的所有业务逻辑只需要在main.js里面写.
ps:标签中有一个data-main属性,你现在只需要了解require.js会在加载完成以后通过回调方法去加载这个data-main里面的js文件,所以这个js文件被加载的时候,RequireJS已经加载执行完毕。
整个RequireJS2000来行源码,暴露出来供我们使用的就那么几个,主要有导入模块,定义模块。(requirejs,require,define),其中:requirejs和require的关系如同:jQuery和$的关系。说道这里:前端的人想必都懂了。
ES6是如何实现模块化的
通过自带的实现:
es6原生支持模块化了,通过import导入模块,export导出模块。这两个单词一直作为保留字,如今赋予它应有的身份出现了,丰富了js语言功能。传统的模块模式基于闭包,返回的“公有API”。这个“公有API”带有对内部变量和功能拥有闭包的方法。它经常这样表达:
模块greetingfn的定义:外边套一层父函数 function myName(name) { //父函数myName function greetingfn() { //子函数greetingfn console.log( "myName " + name + "!" ); } // 公有API---返回父函数里包裹的方法的指针。 return { greetingfn: greeting }; } 使用: var me = myName( "macrolam" ); me.greetingfn(); // myName macrolam!
ps:使用时注意:import和export都必须总是出现在它们分别被使用之处的顶层作用域。例如,你不能把import或export放在一个if条件内部;它们必须出现在所有块儿和函数的外部。
export的使用
export关键字要么放在一个变量或函数声明的前面,要么就对象形式导出,代码如下:
方式1:export function fn() { // 导出函数 } export var num = 42; // 导出变量 var arr = [1,2,3]; export { arr };
方式2:
function fn() { } var num = 42; var arr = [1,2,3]; //统一导出 export {fn,num,arr};
import使用
要导入一个模块,你将不出意料地使用import语句。就像export有几种微妙的变化一样,import也有,所以你要花相当多的时间来考虑下面的问题,并试验你的选择。
如果你想要导入一个模块的API中的特定命名成员到你的顶层作用域,使用这种语法:
import { foo, bar, baz } from "foo";
ps: 这里的{ .. }语法可能看起来像一个对象字面量,甚至是像一个对象解构语法。但是,它的形式仅对模块而言是特殊的,所以不要将它与其他地方的{ .. }模式搞混了。
被罗列的标识符foo,bar和baz必须匹配在模块的API上的命名导出(这里将会发生静态分析和错误断言)。它们在你当前的作用域中被绑定为顶层标识符。
import { foo } from "foo";
foo();你可以重命名被导入的绑定标识符,就像:
import { foo as theFooFunc } from "foo";
theFooFunc();小结:
对于一个小项目,没有多少页面(十几个)的PC端站点,没必要进行前端模块化开发;但是从维护性角度来说还是采用模块化好些。对于一个大项目,数据交互功能性动画频发的站点js代码大量涌现还是模块化更优。
作者:麦壳儿UIandFE2
链接:http://www.jianshu.com/p/e422c28e2471
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
什么是前端模块化?前端模块化开发到底有无必要
最新推荐文章于 2021-09-19 09:37:19 发布