2.5 特性开关
让用户按需裁剪框架特性:关闭的特性靠 Tree-Shaking 整段移除,既保证向后兼容,又不增加资源体积。
一、实现思路
- 本质上是利用 rollup.js 的预定义常量插件来实现(webpack 中对应
DefinePlugin):构建时把开关常量替换为字面量true/false,再让 Tree-Shaking 删掉false分支。 - 举例:框架提供 A、B、C 三个特性给用户,同时提供 a、b、c 三个对应的特性开关,通过把 a、b、c 设置为
true或false来代表开启或关闭对应的特性。
二、特性开关的三个收益
- 用户关闭的特性,可以利用 Tree-Shaking 机制让其不包含在最终的资源中;
- 可以通过特性开关任意为框架添加新的特性,而不用担心资源体积变大;
- 当框架升级时,可以通过特性开关支持遗留 API,这样新用户可以选择不使用遗留 API,从而使最终打包的资源体积最小化。
三、例子:__VUE_OPTIONS_API__
为了兼容 Vue.js 2,Vue.js 3 中仍然可以使用选项式 API 的方式编写代码。明确知道自己不会使用选项式 API 的用户,可以关闭该特性:
// rollup.config.js
import replace from '@rollup/plugin-replace'
export default {
plugins: [
replace({
__VUE_OPTIONS_API__: JSON.stringify(false) // 关闭选项式 API 特性
})
]
}
这样在打包的时候,Vue.js 的这部分代码就不会包含在最终的资源中,从而减小资源体积。
webpack 用户通过
DefinePlugin配置同一批常量,效果一致。
四、易错点
特性开关必须在构建阶段被静态替换为字面量
true/false;如果写成运行时读取的变量,打包工具无法判断分支是否可删,体积优化就失效了。 开关的默认值要保守:不配置时功能应保持可用(如打包工具版本中__VUE_OPTIONS_API__默认为true),否则用户的代码会莫名其妙失效。
相关
- 2.4 框架应该输出怎样的构建产物:这些开关只在打包工具使用的 ESM 产物中暴露。
- 2.6 错误处理:另一个需要框架提前设计好的用户接口。