# 第 2 章 框架设计的核心要素
# 1. 提升用户的开发体验
友好的警告、错误提示信息,让我们能够清晰快速地定位问题。
源码中 initCustomFormatter
函数用于在开发环境设置浏览器自定义输出的格式
开启浏览器自定义输出格式:
- Settings -> Preferences
- Console -> Enable custom formatters
# 2. 控制框架代码的体积
vue.js 使用 rollup.js 进行构建,会输出两种版本:
- 开发版
- 生产版
打印语句:
// __DEV__ 构建工具预定义常量
if (__DEV__ && !res) {
warn(
`Failed to mount app: mount target selector "${container}" returned null`
);
}
开发环境时:
/*
这段永远不会执行的代码为 dead code,编译时会被移除,这就减少了代码的体积
*/
if (false && !res) {
warn(
`Failed to mount app: mount target selector "${container}" returned null`
);
}
总结:
- 构建工具设置预定义常量
__DEV__
,在生产环境不包含打印语句,从而使得框架自身的代码量不随着警告信息的增加而增加。
# 3. 框架要做到良好的 tree-shaking
说明:
- tree-shaking 因 rollup.js 而普及
- 作用:消除那些永远不会执行的代码,即排除 dead code
条件:
- 针对 ESModule(依赖 ESM 的静态结构)
- 移除没有副作用的 dead code
标记为没有副作用的代码:
// utils.js
export function add(num1, num2) {
return num1 + num2;
}
// main.js
import { add } from './utils';
add(1, 2);
/*#__PURE__*/ console.log( add(1, 2) );
tree-shaking 后,上面三行代码都会被移除:
npx rollup main.js -f esm -o bundle.js
# 4. 框架应该输出怎样的构建产物
带 -browser
的都是给浏览器用的,如 vue.esm-browser.js
带 -bundle
的是给构建工具用的:
if (__DEV__) {
// ...
}
// => __DEV__ 会被替换
if (process.env.NODE_ENV !== 'production') {
// ...
}
webpack、rollup.js 寻找资源时,会优先使用 package.json 中的 module
属性:
{
"main": "index.js",
"module": "dist/vue.runtime.esm-bundle.js"
}
# 5. 特性开关
通过预定义常量来控制是否包含某特新的代码
源码:
// support for 2.x options
if (__FEATURE_OPTIONS_API__) {
// ...
}
带 -bundle
的代码:
if (__VUE_OPTIONS_API__) {
// ...
}
在 webpack 中设置值:
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: JSON.stringify(true)
})
# 6. 错误处理
统一的错误处理接口:
utils.js
let errorHandler = (e) => console.log(e); export default { fn1(callback) { callWithErrorHandling(callback); }, fn2(callback) { callWithErrorHandling(callback); }, registerErrorHandler(fn) { errorHandler = fn; } } function callWithErrorHandling(fn) { try { fn && fn(); } catch(e) { console.log(e); } }
使用:
import utils from './utils'; utils.registerErrorHandler((e) => { console.log(e.message); }) utils.fn1(() => {/* ... */}); utils.fn2(() => {/* ... */});
在 vue 中注册统一的错误处理函数:
app.config.errorHandler = () => {
// ...
}
# 7. 良好的 TS 类型支持
用 TS 编写框架,与对 TS 类型支持友好 是两码事
# 8. 总结
提供友好的警告信息很重要,有助于开发者快速定位问题
但警告信息越详细,框架体积越大
利用 tree-shaking 和 预定义常量 __DEV__
排除掉提升开发体验的代码以减小包的体积
tree-shaking 是一种排除机制,基于 ESM,可利用 /*#__PURE__*/
注释来辅助构建工具
上一篇: 下一篇:
本章目录