您现在的位置是:首页 >技术交流 >《Vue.js设计与实现》-框架设计概览-框架设计的核心要素网站首页技术交流
《Vue.js设计与实现》-框架设计概览-框架设计的核心要素
提升用户的开发体验
在vue3源码中 initCustomFormatter 函数是用来在开发环境下初始化自定义formatter的,打开 Chrome的DevTools,勾选"Console"下的"Enable custom formatters" 即可直观的在控制台看到输出的ref数值
控制框架代码的体积
if (__DEV__ && !res) {
warn(`Failed to mount app: Mount target selector "${container}" returned null.`);
}
在 vue3 源码中会看到 warn 函数调用会配合__DEV__检查,这里的__DEV__常量是通过 rollup.js 的插件配置来预定义的,类似于 webpack 中的 DefinePlugin,就是在编译的时候通过静态变量替换成 true 或者 false,替换成 false 而永远不会执行的代码就是 dead code,它不会出现在最终产物中。
这样我们就做到了在开发环境中为用户提供优化的警告信息的同时,不会增加生产环境代码的体积。
框架要做好良好的 Tree-Shaking
Tree-Shaking指的就是消除哪些永远不会执行的代码,也就是排除dead code;
在编译的过程中除了那些永远不会被执行的代码可以被删除,还有一些执行了没有任何意义的代码也可以被删除,执行以后没有任何意义的代码就是指不会有副作用的代码;副作用是指在调用函数时对外部产生影响,例如修改全局变量,但是 javascript 静态分析很难分析出哪些函数是否具有副作用,因为一些通过 Proxy 代码的对象可能在 get 中去修改全局变量,所以需要人为去指定哪些函数不具备副作用;
在 rollup.js 中通过/*#__PURE*/
指定哪些函数没有副作用
框架应该输出怎么样的构建产物
IIFE 全称 Immediately Invoked Function Expression,即“立即调用的函数表达式”
vue.global.js 文件就是 IIFE 形式的资源,IIFE 形式的资源可以直接在 script 标签中引用,我们可以在 rollup.config.js 中配置output.format = 'iife'
来输出这种形式的资源,代码结构示例如下:
var Vue = (function (exports) {
//.....
exports.createApp = createApp;
//.....
})({});
vue.esm-browser.js 文件可以在现代浏览器中直接引用,配置output.format = 'esm'
来输出 esm 格式的资源
<script type="module" src="/path/to/vue.esm-browser.js"></script>
vue.esm-bundler.js 文件是在 rollup.js 或 webpack 等打包工具中使用的,而在 vue.esm-bundler.js 中__DEV__全局变量不能直接通过打包环境进行静态替换,而是要使用process.env.NODE_ENV !== 'production'
替换DEV常量;
为了实现服务端渲染,配置output.format = 'cjs'
来输出 cjs 模块资源;
特性开关
用户可以通过控制框架的特性开关来增加框架的灵活性,并且配合利用 Tree-Shaking 机制来优化打包资源的体积,也可以通过特性开关来控制框架升级以后使用使用遗留 API;
__VUE_OPTIONS_API__
用来控制打包资源中是否存在 vue2 中选项式 api,如果明确不使用 vue2 的选项式 api 可以在编译的时候静态替换成 false,这样 Tree-Shaking 机制将减少资源体积;
错误处理
vue.js 通过 callWithErrorHandling 函数统一处理错误,我们也可以注册统一的错误处理函数;
良好的 TypeScript 类型支持
使用TS编写框架和框架对TS类型支持友好是两件完全不同的事,有时候为了让框架提供更加友好的类型支持,甚至要花费比实现框架功能本身更多的时间和精力。