一、提升用户的开发体验
关于打印ref数据
const count = ref(0)
// 1、直接打印
console.log(count);
// 控制台输出: RefImpl{_rawValue: 0, _shallow: false, _v_isRef: true, _value: 0}
// 2、打印.value
console.log(count.value)
// 控制台输出: 0
// 3、直接打印 + 控制台调整配置
// 原因: chrome允许编写自定义的formatter, 自定义输出形式, vue3源码中含有initCustomFormatter用于定义输出
// 配置: chrome->控制台->右侧设置按钮->偏好设置中的控制台勾选启动自定义格式设置工具(Enable custom formatters)
// 控制台输出: Ref<0>
二、控制框架代码的体积
方法: 打包工具webpack和rollup会通过tree-shakingq去掉无用的代码
实现: 通过__DEV_ _等常量的使用, 常量的定义可以在类似wepback.DefinePlugin中提供
三、框架要做到良好的tree-shaking
如下面函数被调用, 但是实际上没有进行任何操作, 这时候可以通过/#_PURE_/让打包工具知道, 这个函数调用不会产生副作用
什么是副作用→当调用函数的时候会对外部产生影响, 例如修改全局变量
- 没有添加/#_PURE_/之前虽然foo没有执行任何操作, 但是考虑到obj可能是个proxy代码对象, 在执行get操作的时候可以对全局变量进行修改, 所以打包的时候会保留
function foo(obj) {
obj && obj.foo
}
foo();
- 添加了/#_PURE_/之后, 打包工具可以删除foo相关的内容/#_PURE_/
function foo(obj) {
obj && obj.foo
}
/*#_PURE_*/ foo()
四、框架应该输出怎么样的构建产物
1、通过设置rollup中的format值
const config = {
input: "input.js"
output: {
file: "output.js"
format: "iife"
}
2、通过设置webpack中的libraryTarget
entry: [path.resolve(__dirname, "../src/material/index.js")],
output: {
path: path.resolve(__dirname, "../material/dist"),
library: "material",
libraryTarget: "umd"
},
知识点 :
vue输出esm的资源有两种,
vue.esm-browser.js(直接给浏览器使用, __DEV__等变量直接设置为false)
vue.esm_bundler.js (给打包工具使用,__DEV__等变量则被process.env.NODE_ENV !== 'production'代替)
五、特性开关
例子 :
__FEATURE_OPTIONS_API__: IsBundlerESMBuild ? `_VUE_OPTIONS_OPTIONS_API__` : true
对应到源码上 vue3使用的composition方式, 为了兼容vue2, 添加了__FEATURE_OPTIONS_API__判断是否开启data, methods等方式, 可以在wepback中通过DefinePlugin进行配置
new webpack.DefinePlugin ({
_VUE_OPTIONS_OPTIONS_API__: JSON.stringify(true)
})
如果明确代码中不会存在vue2的写法, 就可以设置 _VUE_OPTIONS_OPTIONS_API__为false, 关闭该特性, 减少打包体积
六、错误处理
// 全局注册方法和处理错误
let handleError = null;
export default {
foo(fn) {
callWithErrorhandling(fn)
}
registerErrorHandler(fn) {
handleError = fn
}
}
function callWithErrorhandling(fn) {
try {
fn && fn()
} catch (e) {
handleError(e)
}
}
对应在vue中可以看到
import App from "App.vue"
const app = createApp(App);
app.config.errorHandler = () => {
// 错误处理程序
}