前端模块化以及了解CommonJS

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了
复制代码

如果你现在也想学习前端开发技术,在学习前端的过程当中有遇见任何关于学习方法,学习路线,学习效率等方面的问题,你都可以加入到我的Q群中:前114中6649后671,里面有许多前端学习资料以及2020大厂面试真题 点赞、评论、转发 即可免费获取,希望能够对你们有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值