Skip to content

框架设计的核心要素

框架的核心要素导图
  1. 控制代码体积:
  • 环境变量(DEV)用于判断打包需求
  • Tree-Shaking/ESM 机制确保只打包使用的代码
  1. 输出构建产物: 输出不同版本的构建文件

  2. 错误提示与处理: 统一使用 callWithErrorHandling 接口处理错误

  3. 提升用户开发体验:

  • 保持心智负担低
  • 提供详细的调试和错误信息
  1. 良好的可维护性:
  • 使用 TS 编写提高框架可维护性
  • 对 TypeScript 提供完善支持,包含类型判断和处理

Vue3 中的 /#PURE/ 注释:优化树摇和副作用处理

vue3 源码通过什么告诉编译器 tree-shaking 拿捏不准的时候可以不编译打包?

vue3 源码中大量使用/#**__PURE__/ ,告诉编译器哪些可能产生副作用的函数可以不用编译

  • 详解:在 Vue.js 3 的源码中使用 /#**__PURE**/ 注释的作用是告诉打包工具(比如 webpack、rollup 或者压缩工具如 terser)在进行代码优化和压缩时,可以安全地删除未被使用的代码。这个注释通常用于标记一些函数或语句,告诉工具这部分代码在特定条件下可以被优化掉。 这种优化技术在现代的 JavaScript 打包工具中是非常常见的,它可以帮助减小最终打包后的代码体积,提高应用的加载性能。通过标记未使用的代码,打包工具可以进行更有效的代码压缩和优化,减少不必要的代码体积。

为什么需要通过/#**__PURE__/ 注释告诉编译器,编译器直接判断没有调用就不打包不就好了吗?

  • 编译器进行的是静态分析,这意味着它在分析代码时并不执行代码,而是根据代码的结构和语义来推断哪些代码是必要的,哪些是可以移除的。这种分析是基于代码本身,而不是基于代码的运行时行为。 对于异步代码,尤其是涉及事件循环和回调函数的情况,静态分析确实会遇到一些困难。编译器可能无法准确预测异步代码的执行时间和状态,因此在下面的情况中会更倾向于保守处理:
    1. 异步回调: 当代码执行依赖于异步回调时(例如,来自网络请求、定时器、或其他异步 API),编译器无法确定这些回调何时以及是否会被调用。
    1. 事件监听器: 如果代码中注册了事件监听器,编译器通常无法确定这些监听器是否会被触发,因为它们可能依赖于用户交互或其他运行时事件。
    1. Promise 和异步函数: 当代码中使用了 Promise 或 async/await 时,编译器可能无法确定 Promise 的解决或拒绝是否会影响程序的其他部分。 由于这些原因,编译器在处理异步代码时往往会采取保守策略,保留那些可能在运行时被需要的代码段,以避免移除对程序正确执行至关重要的部分。这样做的结果是,一些未被直接引用的异步代码可能仍然会被包含在最终的打包文件中。 在现代的 JavaScript 打包工具中,如 Webpack、Rollup 或 Vite,它们通常会有一些优化策略来尽可能地进行 tree-shaking,但仍然会保证不会因为过度优化而破坏程序的正确性。这些工具也会提供配置选项,允许开发者指定哪些代码是“副作用-free”的,以便更好地进行 tree-shaking。 总之,静态分析是一种基于代码文本的分析方法。编译器或打包工具在处理异步代码时,会尽量保证程序的正确性,即使这意味着某些未被直接引用的代码也会被编译进最终的结果中。
javaScript
// 没有 PURE 注释时,编译器不确定这个request函数是否有副作用,所以会保守处理
const result = someRequest();

// 有 PURE 注释时,编译器知道这是纯函数调用,如果 result 未被使用就可以安全删除
const result = /*#__PURE__*/ someRequest();