第二章-框架设计的核心要素

57 阅读2分钟

一、提升用户的开发体验

关于打印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 = () => {
  // 错误处理程序
}

七、良好的TypeScript类型支持