为什么要使用模块化?

在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的。

  • 那个时候的代码是怎么写的呢?直接将代码写在<script>标签中即可

随着ajax异步请求的出现,慢慢形成了前后端的分离

  • 客户端需要完成的事情越来越多,代码量也是与日俱增。

  • 为了应对代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护。

但是这种维护方式,依然不能避免一些灾难性的问题。

  • 比如全局变量同名问题:看右边的例子

另外,这种代码的编写方式对js文件的依赖顺序几乎是强制性的

  • 但是当js文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。

  • 而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生

image-20200610075801945

案例

创建一个index.html,和aaa,bbb,mmm三个js文件。

aaa.js

code-snapshot (5)

此时index.html引入小明写的aaa.js和小红写的bbb.js都是能正常起作用的

image-20200610082502228

这时小明再写一个mmm.js

code-snapshot (6)

由于这是自己写的js文件。他知道自己在aaa.js中定义了flag=true所以这样使用。我们在index.html中引入新写的mmm.js

code-snapshot (7)

由于aaa.jsbbb.js都定义了全局变量flag,并且bbb.js设置flag=false所以此时的flag应该被bbb.js覆盖成了false。所以小明写的·mmm.js`中的代码是不被执行的!!

image-20200610083405442

虽然我们可以把mmm.js放在bbb.js之前,aaa.js之后引入

  • 但是当js文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。

  • 而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生

匿名函数解决方案

code-snapshot (8)

code-snapshot (9)

虽然这样解决了全局变量名命名冲突覆盖的问题。但是这时mmm.js中flag就会出现未定义。因为aaa.js使用了匿名函数中定义的都是局部变量,需要在mmm.js中重新定义一个flag

image-20200610084526240

使用了匿名函数定义的都是局部变量,所以我们不能对代码进行复用,例如使用aaa.js中的sum函数,这也就带来了新的问题

使用模块作为出口

我们在匿名函数的基础上定义一个对象,接收匿名函数中的所有变量和函数。将对象return出去,用一个全局变量接收。

code-snapshot (10)

这时我们只有在mmm.js中通过全局变量.xx的方式就能使用了

code-snapshot (12)

image-20200610090213134

使用这种方式我们只要按照规定自定义自己的模块名就行了

image-20200610090425671

常见的模块化规范:CommonJS、AMD、CMD,也有ES6的Modules

CommonJS

image-20200610090825508

CommonJS的使用需要对其提供支持(node中使用的就是CommonJS)

导出方式

code-snapshot (13)

code-snapshot (14)

导入方式

code-snapshot (15)

code-snapshot (16)

ES6模块化

export基本使用

image-20200610092840000

image-20200610093358912

导出方式

code-snapshot (17)

code-snapshot (18)

import使用

image-20200610093450535

code-snapshot (20)

导入

code-snapshot (19)

统一全部导入

如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦

  • 通过*可以导入模块中所有的export变量

  • 但是通常情况下我们需要给*起一个别名,方便后续的使用

code-snapshot (21)

export default

image-20200610094523313

code-snapshot (22)

export default在同一个模块中,不允许同时存在多个,图上只为展示效果

code-snapshot (23)

不需要使用{}导出,名字自定义。默认导入导出文件default导出的东西,因为只能存在一个export default同一模块中。