Vue.js 设计与实现 - 02 框架设计的核心要素

框架设计要比想象得复杂,并不是说只把功能开发完成,能用就算大功告成了,这里还有很多问题:

  • 框架应该给用户提供哪些构建的产物?
  • 产物的模块格式如何?
  • 当用户没有以预期的方式使用框架时,是否应该答应合适的警告信息从而提供更好的开发体验,让用户快速定位问题?
  • 开发版本的构建和生产版本的构建有何区别?
  • 热更新(Hot Module Replacement,HMR)需要框架层面的支持,我们是否考虑?
  • 框架提供了多个功能,而用户只需要其中几个功能时,用户能都选择关闭其他功能从而减少最终资源的打包体积

第一篇 框架设计概览 webpack rollup.js Tree-Shaking 函数副作用 压缩工具 terser

2.1 提升用户体验

在框架设计和开发过程中,提供友好的警告信息至关重要。帮助用户快速定位问题,节省时间。

2.2 控制代码体积

通过静态配置的方式,让用户可以控制最终打包的产物。如 DEV 这个变量,它在开发环境下为 true,在生产环境下为 false。

2.3 框架要做到良好的 Tree-Shaking

想要实现 Tree-Shaking,必须满足的条件是,模块必须是 ESM(ES Module),因为 Tree-Shaking 依赖 ESM 的静态结构。

第二个关键点在于,如果一个函数调用会产生副作用(函数执行时对外部产生了影响,如修改了全局变量),那么就不能将其移除。当函数内部读取了一个外部对象 obj 的属性值时,有可能会产生副作用,如 obj 对象是一个通过 Proxy 创建的代理对象,当我们读取对象属性时,会触发代理对象的 get 方法,在get 方法中有可能会对外部对象进行修改,这就会产生副作用。

因为静态分析 JavaScript 代码很困难,所以像 rollup.js 这类工具都会提供一个机制,让我们明确的告诉工具哪些函数调用不会产生副作用,这样工具才能正确的进行 Tree-Shaking(Vue 3 源码中大量使用)。webpack 以及压缩工具(terser)都能识别。

1
2
import { foo } from './foo.js'
/*#__PURE__*/ foo()

2.4 框架应该输出怎样的构建产物

2.5 特性开关

2.6 错误处理

2.7 良好的 TypeScript 支持