前端模块化的作用

相信很多人都用过 seajs、 requirejs 等这些模块加载器,他们都是十分便捷的工程管理工具,简化了代码的结构,更重要的是消除了各种文件依赖和命名冲突问题,并利用 AMD / CMD 规范统一了格式。然而你了解模块化的作用吗?下面主要讲述模块化能解决哪些问题。

命名冲突

做项目时,常常会将一些通用的功能抽象出来,独立成一个个函数,比如

//util.js

function formate(arr) {
  // 实现代码
}

function isEmpty(str) {
  // 实现代码
} 

把这些函数统一放在 util.js 里。需要用到时,引入该文件就行。这一切工作得很好,同事也很感激提供了这么便利的工具包。

直到团队越来越大,开始有人抱怨:我想定义一个 formate 方法格式化时间,但 util.js 里已经定义了一个。还有的同学不知道util里定义了formate方法,自定义了一个formate函数,然后这个页面其他地方用到formate的地方都报错了。。。

大团队下使用这种方式封装公用工具就会变成全局变量的灾难,一不小心就会有变量命名冲突的问题。
后面有人提出了采用的用自执行函数来包装代码或jQuery风格的匿名自执行函数来试图解决这个问题,代码如下

//util.js

//用自执行函数来包装代码
var Util = function(){
     return {
          formate : function(c){
              //......
          },
          isEmpty: function(){
               //......
          }
     }
}()

//jQuery风格的匿名自执行函数
(function(window){
    //代码
    window.jQuery = window.$ = jQuery;//通过给window添加属性而暴漏到全局
})(window);

这样function内部的变量就对全局隐藏了,达到是封装的目的。但是这样还是有缺陷的:所需依赖还是得外部提前提供、还是增加了全局变量。
作为前端业界的标杆,YUI 团队下定决心解决这一问题。在 YUI3 项目中,引入了一种新的命名空间机制。于是 util.js 里的代码变成了

//util.js

YUI().use('util', function (Y) {
  // Node 模块已加载好
  // 下面可以通过 Y 来调用
  var foo = Y.one('#formate');
});

//YUI 通过沙箱机制,很好的解决了命名空间过长的问题。然而,也带来了新问题。
YUI().use('util1', 'util2', function (Y) {
  Y.formate();  // 如果util1 和util2里都有formate方法,
                // 那么formate 方法究竟是模块 util1 还是 util12 提供的?
});

看似简单的命名冲突,实际解决起来并不简单,再来看另一个常见问题。

繁杂的文件依赖

基于 util.js,同事写了一个很实用的组件 component.js,使用方式很简单,先引入 util.js,再引入 component.js,因为 component.js 依赖于 util.js。


                    
                    

你可能感兴趣的:(模块化)