
JavaScript模块化
本文最后更新于 2025-01-07,文章内容可能已经过时。
模块化概念
模块化
是一种规范
,将一个文件模块拆分
成多个文件模块
,即可称为模块化
!
模块化
,通过模块拆分
可减少单独文件的代码量
,分成多个模块
后,代码维护性更好
,且每个模块代码之间都是相互隔离
的,避免了变量名全局污染的可能性
,另外也可以将重复的模块代码单独抽离成一个子模块
,并供其它模块去使用
,提高代码的复用性
!
没有模块化的一些问题
变量全局污染
变量
全局污染
,就是变量命名冲突
的问题!当在一个
html文件
中,同时引入两个js文件
时,分别是a.js
和b.js
,这时两个js文件
内部有相同的变量名
时,则后面的变量会覆盖前面的变量
!
a.js
b.js
index.html
这里看到,
b.js文件
在a.js文件之后
引入,且内部变量
会覆盖a.js文件中的变量
!最终会打印:
我是b.js文件
!
文件依赖引入混乱
当在一个
真实的开发环境
时,且一个html文件
会引入大量的外部script链接
,且每个链接之间
都产生互相依赖
,且其中一个链接位置
一旦发生变化
,便会导致整个程序崩溃,无法正常运行
!
数据安全问题
一个
html
中引入的js外部链接
,其每个js文件
中的数据变量都是共享
的,例如在a.js文件中定义数据变量
,在b.js文件中可以直接获取
,这样的数据是不安全
的!
a.js
b.js
b.js 在 a.js 后边引入,并可以直接操作 a.js 中定义的变量数据!
模块化规范
模块化规范
,主要就是对文件模块代码
进行分别导出
,并在其它文件内部
进行模块导入
!
模块化规范
主要有四种
,分别为(CommonJs ESModule AMD CMD)!
CommonJs 是 Nodejs中提出的模块化规范,在Nodejs中用的比较多!
ESModule 是 ECMAScript提出的模块化规范,在浏览器中用的比较多!
CommonJs
CommonJs
是Nodejs
中提出的模块化规范
,通过module.exports
可以对模块内容进行导出
,通过require方法
对模块进行导入
!
CommonJs 模块化是非官方标准
,Nodejs
是2009年
提出的,主要用来开发服务器
,当时js还没有模块化概念
,所以社区
就提出了CommonJs模块化
,最后被NodeJs
采纳使用!
初体验
student.js
school.js
index.js
使用
require方法
导入模块
这里使用了
exports
对模块内部变量
做了一个导出
,exports
是一个对象
,相当于给对象内部添加属性
!
导出数据
导出数据
有两种方式
:exports
和module.exports
- exports.attr = value
- module.exports = value
注意事项:
每个
模块
中都有一个空对象{}
,在模块
中可以通过this exports 和 module.exports
来访问这个空对象
,并且三个都是指向一个对象的引用地址
!无论
修改某个对象中的值
,最后向外导出的模块
最终都是module.exports
为准!使用
exports
时不能直接对其进行赋值
!exports = "value"
无论怎么修改,导出的对象
都是module.exports
导入数据
导入数据
,通过require
来引入模块
,引入的模块代码内部会被包裹成一个自执行函数
,并获取module.exports
的值,返回出去
!
注意:
require("./student.js")
中的路径./
表示为当前目录
,是一个相对路径
,且不能被省略
!
相对路径
在内部中,会转换为绝对路径
,根据路径获取模块文件内容
,最后包裹成自执行函数
,获取module.exports
值作为返回值
!
扩展
在
每个模块
中是如何能获取,exports
和module.exports
对象的?- 其实
每个模块都是一个函数体
,内部会将模块代码
通过函数
进行包裹并执行
,并获取module.exports
中的值!
arguments.callee.toString()
callee
可以获取函数本身函数体!
- 其实
在
浏览器
中使用CommonJs规范
,本质上是不可以的,需要通过browserify工具
来对文件进行编译
后才能让浏览器识别
!全局安装
browserify
:编译文件
将
index.js
编译输出
结果为build.js
!页面中使用
ESModule
ESModule模块化
是官方定义的模块化标准
,通过指定的模块语法来实现模块化!
初体验
使用
export
对变量
进行导出!
school.js
student.js
index.js
使用
import xx from "./xxx.js"
语法来导入模块代码
!
这里的
*
表示所有,as student
表示,将导入的模块对象
放入到一个别名为student
!
Node中运行ES模块
- 将
所有模块文件
的.js
后缀改为.mjs
! - 可以在
package.json
中增加type属性
,且值为module
即可!
导出数据
使用
export关键字
可以对模块中的数据进行导出
!
分别导出
分别导出
,就是在每个声明变量
和函数前
使用export关键字进行导出
!
统一导出
统一导出
,在代码尾部使用export关键字
并跟一个类似于对象结构
的花括号
,对声明变量名进行导出
!
注意: export 后面 {} 花括号里面的内容不是以"键值对"形式去书写的,它类似于对象,但并不是属于对象范畴!
默认导出
默认导出
,在export关键字
后面增加default关键字
,后面可以跟字面量表达式
!
默认导出
,只能在模块中存在一个,且不能有多个默认导出
!
这里会导出一个
default
对象!
也可以
默认导出一个字面量
混入导出
混入导出
,同时可以使用分别导出
,统一导出
,默认导出一起使用
!
index.js
导入数据
通过
import关键字
可以对模块进行导入
,需要注意
的是,导入的数据都是常量
,且无法被修改
!
导入全部
导入全部
,是指分别导入
以及默认导入
都会被加载进来
!
命名导入
只能用于分别导出
,默认导出不能用
!
默认导入
export default
混入导入
school.js
动态导入
动态导入,也是按需导入,当触发某一个时机时,可以加载某一个模块!
import可以当做一个函数去执行,返回一个promise!
import不接收数据
当一个
模块没有导出语句
时,也可以通过import语法将模块进行导入
并执行模块中的代码
!
这里会
导入该模块
,并执行模块中的代码
!