模块化和非模块化的理解

将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起,模块的内部数据/实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信。

1.1 无模块化的原始时代

最开始js只是作为一个脚本语言来使用,做一些简单的表单校验,动画实现等等。

代码都是这样的,直接把代码写进

<script>
 if(true) {
     
     
   ...
 } else {
     
     
   ...
 }
 for(var i=0; i< 100; i++){
     
     
   ...
 }
 document.getElementById('button').onClick = function () {
     
     
   ...
 }
</script>

1.2 代码量剧增带来的灾难性问题

后来随着ajax异步请求的出现,前端能做的事情越来越多,代码量飞速增长。

也暴露出了一些问题。
全局变量的灾难

这个非常好理解,就是大家的代码都在一个作用域,不同的人定义的变量可能会重复从而产生覆盖。

//试想彭彭定义了一个变量 
name = 'pengpeng';

//后来,丁满后面又定义了
name =  'dingman';

//再后来, 彭彭开始使用他定义的变量

if(name === 'pengpeng'){
  ...
}

这就杯具了。

依赖关系管理的灾难

<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>


如果c依赖了b,b依赖了c,则script引入的顺序必须被依赖的放在前面,试想要是有几十个文件,我们都要弄清楚文件依赖关系然后手动,按顺序引入,无疑这是非常痛苦的事情。

1.3 早期的解决方式

(1)闭包

moduleA = function() {
   var a,b;
   return {
      add: function (c){
         return a + b + c;
      };
   }
}()

这样function内部的变量就对全局隐藏了,达到了封装的目的,但是最外层模块名还是暴露在全局,要是模快越来越多,依然会存在模块名冲突的问题。

(2)命名空间

Yahoo的YUI早起的做法

app.tools.moduleA.add = function(c){
   return app.tools.moduleA.a + c;
}

毫无疑问以上两种方法都不够优雅。

那么,模块化到底需要解决什么问题提呢?我们先设想一下可能有以下几点

安全的包装一个模块的代码
避免全局污染唯一标识一个模块
优雅的将模块api暴露出去
方便的使用模块

2 服务端模块化

Nodejs出现开创了一个新的纪元,使得我们可以使用javascript写服务器代码,对于服务端而言必然是需要模块化的。

2.1 Nodejs和CommonJS的关系这里要说一下Nodejs和CommonJS的关系。
Nodejs的模块化能一种成熟的姿态出现离不开CommonJS的规范的影响
在服务器端CommonJS能以一种寻常的姿态写进各个公司的项目代码中,离不开Node的优异表现Node并非完全按照规范实现,针对模块规范进行了一定的取舍,同时也增加了少许自身特性

参考文章:前端模块化一——规范详述 - 一只傻汪的文章 - 知乎
https://zhuanlan.zhihu.com/p/41568986

猜你喜欢

转载自blog.csdn.net/liulang68/article/details/108690562