框架设计要比想象得复杂,并不是说只把功能开发完成,能用就算大功告成了,这里还有很多问题:
- 框架应该给用户提供哪些构建的产物?
- 产物的模块格式如何?
- 当用户没有以预期的方式使用框架时,是否应该答应合适的警告信息从而提供更好的开发体验,让用户快速定位问题?
- 开发版本的构建和生产版本的构建有何区别?
- 热更新(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 | import { foo } from './foo.js' |