详解Js中的模块化
-
- [1. 模块化的背景](#1. 模块化的背景)
- [2. 来看一个例子](#2. 来看一个例子)
- [3. 优雅的做法 ------ 创建模块对象](#3. 优雅的做法 —— 创建模块对象)
- [4. 模块与类(class)](#4. 模块与类(class))
- [5. 合并模块](#5. 合并模块)
- [6. 动态加载模块](#6. 动态加载模块)
1. 模块化的背景
- JavaScript 在诞生之初是体积很小的,早期,它们大多被用来执行独立的脚本任务,在我们的Web网页中提供一些交互效果,所以一般不需要多大的脚本。 随着时代的发展,慢慢有了运行大量 JavaScript 脚本的复杂程序,它也不止被运用在客户端了,甚至服务端都能用,比如 Node.js。
- 所以,近年来的新做法是将 JavaScript 程序拆分为可按需导入的单独模块的机制,Node.js早就支持了,另外js的很多库和框架都开始了模块化的使用,比如:Common.js,Require.js,以及最新的Webpack.js 和 Babel.js。
- 目前大部分主流浏览器都是支持的,浏览器能够最优化加载模块,使它比使用库更有效率:使用库通常需要做额外的客户端处理。
2. 来看一个例子
- html 文件
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模块化</title>
</head>
<body>
<script type="module">
import util from './util.js'
let value = util(10, 20);
console.log(value );
</script>
</body>
</html>
- js文件
javascript
// 用来取两者范围内整数随机数的方法
export default function getRandom(a, b) {
let max = Math.max(a, b)
let min = Math.min(a, b)
return parseInt(Math.random() * (max - min)) + min;
}
- 这里就是模块化的写法,定义了一个工具方法,然后导出它:export default ,当然如果有多个方法,就只需要 export 了,引入的时候加 { },解构的方式取值,如下:
javascript
export { fnA, fnB, fnC, fnD};
javascript
import { fnA, fnB, fnC, fnD } from '/util.js'
- 需要注意的是,这里的 js 已经不是脚本了,它是一个模块,所以必须在标签上加 type="module
- 另外,你需要在本地启动一个服务才能正常运行(vscode 下个Live Server即可),不然会报错。
- 否则,你直接打开html文件会报错: CORS 错误,这是因为 JavaScript 模块安全性需要如此。
- 加载一个模块脚本时不需要使用 defer 属性模块会自动延迟加载。
3. 优雅的做法 ------ 创建模块对象
- 当有多个方法以及导出时,以上做法其实并不优雅:需要N个 export ,与N个 import,于是我们可以优化一下。
javascript
import * as Module from "/modules/module.js";
- 这将获取 module.js 中所有可用的导出,并使它们可以作为对象模块的成员使用,从而有效地为其提供自己的命名空间。例如:
javascript
Module.function1();
Module.function2();
- 很明显,可以像以前一样编写代码,并且导入更加整洁。
4. 模块与类(class)
- 正如我们之前提到的那样,你还可以导出和导入类;这是避免代码冲突的另一种选择,如果你已经以面向对象的方式编写了模块代码,那么它尤其有用。
javascript
class Snake {
constructor({ width = 20, height = 20, direction = 'right' } = {}) {
}
render(map) {
}
move(food, map) {
}
remove() {
}
}
export default Snake;
- 使用的时候引入整个即可:
javascript
import Snake from "./snake.js";
this.snake = new Snake();
snake.render();
snake.move();
snake.remove();
5. 合并模块
- 有时你会想要将模块聚合在一起。你可能有多个级别的依赖项,你希望简化事物,将多个子模块组合到一个父模块中.
- 这可以使用父模块中以下表单的导出语法:
javascript
export * from "x.js";
export { name } from "x.js";
6. 动态加载模块
- 浏览器中可用的 JavaScript 模块功能的最新部分是动态模块加载。
- 这允许你仅在需要时动态加载模块,而不必预先加载所有模块,这有一些明显的性能优势。
- 这个新功能允许你将 import() 作为函数调用,将模块的路径作为参数传递。它返回一个 promise,它用一个模块对象来实现,让你可以访问该对象的导出,例如:
javascript
import("/modules/mymodule.js").then((module) => {
// Do something with the module.
});
1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(文底有V)