一、CMD和AMD的区别
模块化规范可以认为是 JavaScript 文件之间相互依赖引用的一种通用的语法约定,就是按照一定的规范来写 JavaScript 文件,让它可以方便的被其他 JavaScript 文件引用。
主要有几种常见的规范:
- AMD(Asynchronous Module Definition,异步模块定义)
- CMD(Common Module Definition,通用模块定义)
这两个都是浏览器端的模块加载方案
1.1 AMD规范
AMD(Asynchronous Module Definition)是异步模块定义,采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。
在 AMD
规范中,我们使用 define
定义模块,使用 require
加载模块。
定义模块:
js
define(id?, dependencies?, factory);
// 1.`id` 是定义的模块名,这个参数是 可选的 ,默认值是引入依赖的文件名;
// 2.`dependencies` 是定义的模块中所依赖的 模块数组 ,也是 可选的 ,依赖模块 优先级 执行,并且执行结果按照数组中的排序依次以参数的形式传入 `factory` ;
// 3. `factory` 是模块初始化要执行的函数或对象,是 必需的 。
加载模块:
js
require([module], callback);
// 1.`module`,数组,里面的成员就是要加载的模块;
// 2.参数 `callback`,则是加载成功之后的回调函数。
优点:
- 适合在浏览器环境中异步加载模块
- 可以并行加载多个模块
缺点:
- 提高了开发成本
- 不符合通用的模块化思维方式
1.2 CMD规范
CMD(Common Module Definition)是公共模块定义,在 CMD
规范中,一个模块就是一个文件。
定义模块:
js
define(factory);
// 1. 当 `factory` 是一个对象或是一个字符串时,表示该模块的接口就是这个对象或者字符串;
// 2. 当 `factory` 是一个函数时,表示是该模块的构造方法;默认传入三个参数:`require`、`exports`、`module`。其中 `require` 用来加载其它模块,`exports` 用来向外提供模块接口。`module` 是一个对象,存储着与当前模块相关联的一些属性和方法。
加载模块:
js
seajs.use([module], callback);
优点:可以很容易在 node
中运行
缺点:依赖 SPM
打包,模块的加载逻辑偏重
二、JS是怎么执行的
两个小概念(宏任务和微任务):
1、微任务 是指在当前任务执行结束后立即执行的任务;
2、宏任务是指需要排队等待 JavaScript 引擎空闲时才能执行的任务;
我们页面中的js执行顺序是这样的:
第一轮事件循环:
- 主线程执行js整段代码(宏任务),将ajax、setTimeout、promise等回调函数注册到事件队列,并区分宏任务和微任务。
- 主线程提取并执行 事件队列 中的ajax、promise等所有微任务,并注册微任务中的异步任务到 事件队列 。
第二轮事件循环:
- 主线程提取Event Queue 中的第一个宏任务(通常是setTimeout)。
- 主线程执行setTimeout宏任务,并注册setTimeout代码中的异步任务到Event Queue(如果有)。
- 执行Event Queue中的所有微任务,并注册微任务中的异步任务到Event Queue(如果有)。
类似的循环:宏任务每执行完一个,就清空一次事件队列中的微任务。
注意:事件队列中分"宏任务队列"和"微任务队列",每执行一次任务都可能注册新的宏任务或微任务到相应的任务队列中,只要遵循"每执行一个宏任务,就会清空一次事件队列中的所有微任务"这一循环规则,就不会弄乱。
具体可参考这个 :图解JS执行机制
三、JS是怎么解析的
JavaScript代码编译原理,编译器把程序分解成词法单元(token),然后把词法单元解析成抽象的语法树(AST),再把语法树变成机器指令等待执行。
四、 angular 是怎么编译的 怎么集成 怎么最后几个文件 angular里面的import 是干嘛用的?
4.1 关于编译
将HTML模板转换为组件树,并生成渲染器,该渲染器用于在运行时将组件树转换为浏览器可以理解的JavaScript代码。在这个过程中,还会将指令、组件和管道编译为渲染器中的可执行代码。
Angular 应用在浏览器中的编译过程通常分为两个阶段:Ahead-of-Time (AOT) 编译 (事先编译) 和 Just-In-Time (JIT) 编译(即时编译)。这两种编译方式决定了应用在浏览器中的运行方式。
Ahead-of-Time (AOT) 编译: AOT 编译是一种在构建过程中将 Angular 应用编译成纯JavaScript的方式,以提高应用的性能。在 AOT 编译下,模板在构建时被编译成JavaScript代码,而不是在运行时在浏览器中进行解释和编译。这意味着应用的代码在浏览器中加载时已经是预编译的,因此应用的启动速度更快。
要启用 AOT 编译,你需要在构建时使用 ng build --aot
命令,或者在使用 Angular CLI 创建应用时选择 AOT 编译。
Just-In-Time (JIT) 编译: JIT 编译是一种在运行时将 Angular 应用的模板编译成JavaScript代码的方式。在 JIT 编译下,应用的模板代码在浏览器加载时动态编译,这使得构建过程更快,但可能会导致应用在启动时有一些性能开销。
要使用 JIT 编译,你可以直接使用 ng build
命令构建应用,或者在创建应用时不选择 AOT 编译。
Aot 性能好些
打包后 文件数量减少 是因为模块合并
angular里面的import 是为了引入组件、服务等模块;