文章目录
- 什么是模块化开发
=> 多个 js 文件之间的相互配合来实现效果
=> 一个 js 文件里面只封装一类内容
问题: 由多个 js 文件出现的
- js 文件引入顺序
- js 文件之间的相互依赖不清晰
- js 文件内部的变量会污染全局
没有模块化的时候
- 按照顺序引入文件
- 把整合的文件放在最后面
<h1>没有模块化</h1>
<script src="./a.js"></script>
<script src="./b.js"></script>
<script src="./c.js"></script>
问题:
- 没有办法维护
- 我们一般把整合的 js 文件起名叫做 main.js
- 你并不知道依赖了哪一个文件
- 全局变量污染
- 我每定义一个变量都得注意不能重复定义
- 依赖关系不清
- 我现在只能知道 c.js 里面用到了 a.js 和 b.js 文件
- b.js 里面有没有依赖到 a.js 里面的内容我也不清楚
IIFE 标准
- Immediately Invoked Function Expression 立即调用函数表达式
- 所有的内容放在一个自执行函数
(function(){})()
里面- 但是外界不能使用
- 我可以把我想向外暴露的内容直接暴露出来
解决问题:
- 依赖不清
- 直接在自执行函数的参数位置, 能看到依赖了哪些模块
- 变量全局污染
- 你后面的代码该用什么变量用什么变量
<h1>IIFE 模块化标准</h1>
<script src="./a.js"></script>
<script src="./b.js"></script>
<script src="./c.js"></script>
CommonJS 模块化标准
- 2009 年, nodejs 出现了
- 使用了 JS 去做服务端语言
- 伴生的是 CommonJS 模块化标准
- 缺点: 只能在后端 JS 里面用
AMD 模块化标准 - Async Module Definition - !依赖前置!
- 异步模块
- 2011 年出现的, 社区里面发起的
- 因为非官方, 所以没有关键字, 大家书写了一套叫做 require.js 的第三方文件
- 来实现 模块化标准
- 把每一个 js 文件独立出来了
-> 使用了导入导出的语法来实现模块化
-> 在 JS 文件里面引入另一个 JS 文件 - 定义模块
=> 通过调用 define 的方法- 独立模块定义
-> 每一个模块文件开始执行 define()
-> 我不依赖其他文件, 就是一个单纯的模块
-> 向外暴露的内容, 就直接 return 出去 - 依赖其他模块的模块
-> 我也是一个模块文件, 但我依赖了其他模块的内容
-> 使用 define() 定义
-> 语法: define([依赖文件1, 依赖文件2, …], function(模块A, 模块B, …){}) - 导入 其他模块
-> 我是一个模块整合文件
-> 我就直接使用 a.js 文件里面的方法
-> 使用 require() 方法导入
-> 语法: require([依赖文件1, 依赖文件2, …], function(模块1, 模块2){})
- 独立模块定义
解决问题:
- 依赖很清晰
- 因为只有一个文件, 那么所有的东西都在一个文件里面出现
- 变量全局污染
- 都在私有作用域, 没有全局污染
独立模块定义
-> 每一个模块文件开始执行 define()
-> 我不依赖其他文件, 就是一个单纯的模块
-> 向外暴露的内容, 就直接 return 出去
依赖其他模块的模块
-> 我也是一个模块文件, 但我依赖了其他模块的内容
-> 使用 define() 定义
-> 语法: define([依赖文件1, 依赖文件2, …], function(模块A, 模块B, …)\
导入 其他模块
-> 我是一个模块整合文件
-> 我就直接使用 a.js 文件里面的方法
-> 使用 require() 方法导入
-> 语法: require([依赖文件1, 依赖文件2, …], function(模块1, 模块2){})
<script src="../modules/require.js"></script>
<body>
<h1>AMD 模块化标准 - 依赖前置</h1>
<h2>页面必须引入一个叫做 require.js 的第三方文件</h2>
<!-- 页面只需要引入最后的整合文件即可-->
<script src="./c.js"></script>
</body>
过程如果出现了has been blocked by CORS policy问题
has been blocked by CORS policy问题解决方法
问题:
- 依赖前置
- 不管多少行以后使用的东西, 都会在打开页面的时候就加载进来, 第一个不加载完成, 后面的用不了
- 缺点: 首屏加载时间长
- 优点: 后期操作流畅
CMD - Common Module Definition - 通用模块定义 - !即时依赖!
- 2011 左右, 在社区里面出现的一个标准
- 淘宝 “玉伯”, 开发了 CMD 的模块化标准
- 依赖于一个叫做 sea.js 的文件来实现的模块化标准
- 使用: 文件需要引入一个 sea.js 第三方文件
-
独立模块定义
-> define(function(require, exports, module){})
-> require() 用来导入其他文件
-> module 是为了本文件导出内容的
-> exports 是 module.exports 的别名
-> var exports = module.exports -
依赖其他模块的模块
-> 你需要依赖其他文件模块
-> 在 define(function(require, exports, module){
在你需要的位置使用 require() 方法来导入
var modA = require(‘地址’)
}) -
资源整合
-> 使用 seajs.use()
-> 语法: seajs.use([‘你要依赖的模块’], function(模块A){})
-
解决问题
- 依赖前置
- 按需加载
- 也留下了依赖前置的接口
独立模块定义
-> define(function(require, exports, module){})
-> require() 用来导入其他文件
-> module 是为了本文件导出内容的
-> exports 是 module.exports 的别名
-> var exports = module.exports
依赖其他模块的模块
-> 你需要依赖其他文件模块
-> 在 define(function(require, exports, module){
在你需要的位置使用 require() 方法来导入
var modA = require(‘地址’)
})
资源整合
-> 使用 seajs.use()
-> 语法: seajs.use([‘你要依赖的模块’], function(模块A){})
<script src="../modules/sea.js"></script>
<h1>CMD 模块化标准 - 即时依赖</h1>
<h2>需要在页面引入一个叫做 sea.js 的文件</h2>
<script src="./c.js"></script>
问题
- 即时依赖
- 首屏加载快
- 操作不够流畅
ES6 Module
- 2015 年发布, ES6 语法里面自带了一个模块化标准
- 各大浏览器厂商不买账
- 2016 年开始, Vue 出现了, 出现了一个脚手架(他搭好了开发的框架)
=> 搭建这个架子的时候, 内置了 ES6 模块化标准 - 2018 年, 各大浏览器厂商开始原生支持 ES6 模块化标准
- 2018 年中, Chrome 率先原生支持 ES6 模块化
- 语法: 变成了 JS 的语法, 和关键字, 不需要任何第三方文件的引入
- 特点: 页面必须在服务器上打开
=> live server 插件
=> 如果你想使用模块化语法, script 标签要加一个属性 type = ‘module’ - 使用:
- 每一个文件都可以作为独立模块, 也都可以作为整合文件
- 导出语法
2-1. export default{ 导出的内容 }
2-2. export var num = 200 - 导入语法
3-1. 接收 export default 导出- import 变量 from ‘哪一个 JS 文件’
3-2. 接收 export 导出的内容 - import {接受变量} from ‘哪一个 JS 文件’
- import 变量 from ‘哪一个 JS 文件’
解决问题
- 变成关键字, 不需要依赖第三方文件
- 每一个文件都可以变成模块文件, 也可以是整合文件
export default{ 导出的内容 }
export var num = 200
接收 export default 导出
+ import 变量 from ‘哪一个 JS 文件’
接收 export 导出的内容
+ import {接受变量} from ‘哪一个 JS 文件’
<h1>ES6 模块化标准</h1>
<h2>必须要在服务器上打开</h2>
<h2>script 标签要有 type ="module"</h2>
<script src="./c.js" type="module"></script>
问题:
- 浏览器支持不好
- 必须要在服务器上打开
- 一旦项目上线, 肯定是在服务器打开
- 依赖前置
ES2020 发布新的标准
=> ES2020 发布新的标准
=> 多了一个 按需加载 的模块化
=> 语法: import(你要加载的文件).then(function(res){})
=> 可以和 ES6 标准混合使用
<script src="./d.js" type="module"></script>