第二章 Vue框架的设计细节
框架设计的核心
提升体验
- 开发者在进行开发时,框架应该提供足够清晰,友好的提示
- 输出信息可定制,在Vue3中提供了initCustomFormatter函数来自定义输出形式
优化体积
- 框架的体积应该越小越好,但是如果提供清晰,友好的提示,就会导致体积增大
- 框架分为了开发和生产环境,对于生产环境构建时,提示代码会被移除。
- 通过设置全局环境变量,只有开发环境才会调用输出函数,否则直接跳过
Tree-Shaking
- 框架本身提供了许多内置的组件,如teleport,transition等,用户没有使用到,则不应该将其构建
- 框架提供了Tree-Shaking功能,通过ESM静态结构分析,将永远不会执行的deadcode剔除
- 静态分析存在局限性,对于会产生副作用的函数,即便是永远不执行,也无法被剔除
- 框架在开发时,通过/*#PURE*/ 来指明该函数可被剔除。
- 一般只会在顶级函数上注明,只有顶级函数才可能产生副作用(影响外部变量之类的)
框架产物
- 框架本身提供了诸多功能,经过上述优化后,会根据不同使用场景产生不同的构建结果
- 我们就可以在不同场景中使用不同版本的框架来适配
- 比如 vue.global.js用于开发环境,vue.global.prod.js用于生产环境
- 比如 旧版本的浏览器对于ESM支持不好,需要通过IIFE来引入,新版本的可以使用module引入脚本,Node环境则通过require来引入
- 比如 vue.runtime.esm-bundler.js 用于webpack等打包工具,esm-browser则用于浏览器
特性开关
- 原理同Tree-shaking的环境变量,框架提供预定义变量,通过这些变量来控制某些特性是否保留
- 比如Vue3提供的__VUE_OPTIONS_API_,通过该变量我们可以控制Vue2的选项式API是否保留
错误处理
- 开发者在编写代码时,发生错误后,框架应该自动处理错误,并将错误信息暴露出去
- 如果不在框架层面处理,那就意味着开发者需要自行trycatch来捕获错误,无疑会增加开发者的负担
- 框架内置callWithErrorHanding函数,用户编写的代码,均会被包装成函数,作为回调传入,这样当用户的代码发生错误时,callWithErrorHanding内部会捕获错误,并对其处理
- 框架内置registerErrorHandler函数,用户可将错误处理的函数注册其中,这样callWithErrorHanding捕获错误后会将错误传入错误处理函数,由用户控制处理方式
总结
- 框架对自身提供的功能进行控制,将控制权交给用户,根据不同场景来对自身的体积,特性进行筛选
- 为用户提供了提示信息的定制能力,错误处理的能力
- 为适配不同的场景,将自身最终构建的产物以不同形式提供,常见的IIFE,module,require等