认识前端模块化以及了解CommonJS__Vue.js
发布于 4 年前 作者 banyungong 1818 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

JavaScript的发展历程

如果要了解前端为什么要进行模块化,还是得了解JS语言的发展历程。

  • 起初,JavaScript仅仅是一门脚本语言,就是相当于在页面中添加插入一小段脚本,类似给衣服打一块补丁。所以起初JS要处理的东西相当的少,一个script标签足以解决。
  • 后来,ajax的出现,前端的世界从同步转向了异步。前后端逐渐分离,客户端要处理的事情,与日俱增。也导致我们的JS代码量越来越多,往往会分成很多个js文件。

到了这个时候,就会引起一个灾难性的问题:js文件中的全局函数或者全局变量对于所有js文件都是可见的。那么势必会导致几个严重的问题

  1. 变量同名的问题
  2. 我可以通过别的js文件修改这个js文件中的数据。而你很难找到它在哪里修改的。

等等等等一系列问题,这些问题的主要原因是,各个js文件的界限不够清晰,完全混杂在一起,特别的乱。

前端模块化的雏形(ES6之前的模块化雏形)

正是由于这种问题的出现,我们势必要将每个js文件划清界限。所以每个JS文件不能同在一个全局作用域中否则还是会混在一起。除全局作用域之外**,我们可以给它创造函数作用域,使每个JS文件都位于函数作用域中。从而他们互不干扰。对于他们来讲,他们相互使不可见的。**现在我来模拟一下这种情况。(伪代码)

//a.js
;(function(){
var nameA = A;
funtion sum () {}
})()

//b.js
;(function(){
var nameB = B;
funtion sum () {}
})()


//c.js
;(function(){
var nameC = C;

})()

立即执行函数创建了三个函数作用域,导致每个文件中的内容,都是互相不可见的。这似乎到达了我们的要求。但是这样一来,我们文件的关联性就变得很弱了。比如说,我b.js中想使用a.js的nameA变量,c.js想用a.js的sum函数。在这里根本就访问不到的。
怎么解决各个js文件之间毫无关联的问题呢?
**这就要用到我们的闭包了。**就是我们在里面创建一个对象。然后把别的文件要用到的东西,全给他丢到这个对象里,最后再把这个对象返回出去。让一个全局变量去接收。看我操作。

//a.js
;var moudleA = (function(){//全局变量接收
var obj ={}
var nameA = A;
funtion sum () {}
obj={//把要输出的东西打包在这个对象中
nameA:nameA,
sum:sum
}
return obj//将对象返回赋值给全局变量
})()

这个全局变量对于所有的文件实际上都是可见的。所以都可以访问它。如果还想实现刚刚那种b.js中想使用a.js的nameA变量,直接在b.js文件中moudleA.nameA就能访问到了。

总结

以上就是前端模块化的雏形,正是由于js文件的变多,以及会造成一些灾难性的问题,所以出现了模块化的概念还雏形。

了解CommonJS

前言

前端模块化,发展到今天。已经有很多既成的规范

  1. CommonJS
  2. AMD
  3. CMD
  4. ES6的模块化

请注意,这个词规范,这说明一个什么问题呢?这说明他们都只是一种规则,他们教你怎么写各自的模块化代码。但是你得看解析JS代码的家伙,到底支不支持这种规则,他有没有给她做相应的支撑。这个其实是很关键的。不然可能连关键字都认不得。拿CommonJS举例,node环境支持他,所以在node环境中使用它是没有任何问题的,所以我们后面要学的webpack,他依赖的正好是node。所以可以在webpack中使用CommonJS。 对我们的ES6模块化来说,可能并不是所有 浏览器都看得懂ES6模块化的语法,那么这个时候就体现了我们打包工具webpack的强大之处,他能把我们ES6的模块化都打包成每个浏览器都能看的懂的语法(其实就是用一种普通js的方案去实现ES6的模块化)

了解CommonJS

模块化的核心就是两个。一个是输入,一个输出。

CommonJS输出

首先,有点要说。就是我们的js文件没必要放在函数作用域中了,按模块化的规则,一个js文件就是一个模块,有自己的作用域相互是不可见的。
以a.js为例,我们用CommonJS的方式进行模块化

//a.js

var nameA = A;
funtion sum () {}
module.exports = {//CommonJS的形式输出
nameA:nameA,
sum:sum
}

CommonJS的输出的形式很简单,就是使用module.exports输出一个对象。把要输出的内容都放在对象的属性/方法里。

CommonJS输入

CommonJS的输入更简单,直接通过require导入即可。他就会把输出的那个对象输入到文件中。

let   moduleA = require("js文件a的路径");//moduleA就是刚刚module.exports导出的对象。

同时我们还可以使用解构赋值的形式。

let   {sum,nameA} = require("js文件a的路径");//就可以直接使用变量sum,nameA了
```<p style="line-height: 20px; color: #ccc">
        版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
        作者: 羅藝
        原文链接:<a href='https://juejin.im/post/6867755434980147214'>https://juejin.im/post/6867755434980147214</a>
      </p>
回到顶部