模块化

早期JS开发的时候,没有模块化规范,很容易出现全局污染和依赖管理混乱的问题。

全局污染

1
2
3
<script src="./index.js"></script>
<script src="./home.js"></script>
<script src="./app.js"></script>

在这些不同的JS文件里面可能定义着相同的名字,比如name在index.js里面是一个变量名,在home.js里面是一个函数名

依赖管理混乱

因为执行JS的顺序是从上到下 index->home->app

index,home,app里面分别有公共方法func1,func2,func3

func1无法调用func2,func3(因为home,app还没有执行),而func3可以调用func1,func2

模块化规范包括,CommonJs,AMD,CMD,UMD和ESM

其中CommonJS主要用于服务端NodeJS项目;AMD和CMD提供相似的异步加载模块方式,但对依赖的处理稍有不同;ESM是依赖于ES静态模块结构的一种更为高效的模块规范;UMD则是对以上几种规范的兼容。

注:客户端和服务端不懂,可以看注解

规范 使用场景 加载顺序 加载方式
CommonJS 服务端 同步 运行时
AMD 客户端 异步 运行时
ESMoudule 客户端 异步 编译时
UMD 客户端 异步 编译时

CommonJS规范

CommonJS是一种用于非浏览器环境的JavaScript模块化规范,最常见的场景是用于NodeJS。

1
2
3
4
5
6
7
 // 引入 
const doSomething = require('./doSomething.js');

// 导出
module.exports = function doSomething(n) {
// do something
};

ESM规范

ESM(ECMAScript Modules) 是JavaScript的官方模块化规范

export 用来导出模块,import 用来导入模块。

ES6 module 特性

1 静态语法

ES6 module 的引入和导出是静态的,import 会自动提升到代码的顶层 ,import , export 不能放在块级作用域或条件语句中。

2 执行特性

ES6 module 和 Common.js 一样,对于相同的 js 文件,会保存静态属性。

但是与 Common.js 不同的是 ,CommonJS 模块同步加载并执行模块文件,ES6 模块提前加载并执行模块文件,ES6 模块在预处理阶段分析模块依赖,在执行阶段执行模块,两个阶段都采用深度优先遍历,执行顺序是子 -> 父。

3 导出绑定

不能修改import导入的属性

对 import 属性作出总结:

  • 使用 import 被导入的模块运行在严格模式下。
  • 使用 import 被导入的变量是只读的,可以理解默认为 const 装饰,无法被赋值
  • 使用 import 被导入的变量是与原变量绑定/引用的,可以理解为 import 导入的变量无论是否为基本类型都是引用传递。

详细可以看一下文章:

JS模块化之CommonJS、AMD、UMD和ESM规范在现代化的前端工程中,模块化已经成为习以为常的规范之一。成熟的框 - 掘金

「万字进阶」深入浅出 Commonjs 和 Es Module一 前言 今天我们来深度分析一下 Commonjs 和 E - 掘金

注:

客户端和服务端

客户端

客户端是用户直接接触的移动设备或应用程序,负责展示数据、收集用户输入,并通过网络与服务端通信。

可以是浏览器,移动应用,桌面软件。

服务端

服务端是运行在远程服务器上的程序或服务,负责处理核心业务逻辑、数据存储、安全验证等任务。

它接收客户端的请求,执行计算或操作后返回结果。