让给各位见笑了,这个只是记录的这段时间对《Vue.js 设计与实现》学习的记录,如果在某些方面不妥,还请您帮忙指出。谢谢😊
一个优秀的开源框架,不是简简单单的把功能顺利的完成即可,而是需要提供大量的辅助功能,比如提供不同的构建产物、未按预期使用友好提示、不同的使用版本(IIFE、ESM、CJS...)、热更新、资源体积...
一、提升用户的开发体验
1. 用户没有以预期的方式使用框架
在使用框架的时候,如果使用不规范,不符合框架预期使用,提供友好的警告,不仅可以节省用户定位问题的时间,还可以收到良好的口碑,提高用户的认可度
2. log format
打开DevTools设置,勾选 “Console” → “Enable custom formatters” 选项
const count = ref(0);
console.log(count)
会输入被格式化的0
主要是因为Vue框架中initCustomFormatter 帮我们做个format
二、控制框架代码的体积,做到良好的Tree-Shaking
1. 框架体积大小也是衡量框架标准之一
在开发阶段,Vue框架提供了各种异常提示,这样会产生大量对于用户来说无用的代码,从而代码体积增大,因此Vue框架通过Tree-Shaking方式,打包生产包的时候,将这些无用的代码给移除,从而减少代码的体积。降低代码体积还有很多,比如代码混合压缩等等
2.Tree-Shaking
- 模块必须是ESM才能Tree-Shaking,因为Tree-Shaking 依赖ESM的静态结构
- 不是所有的dead Code会被删除,比如
// util.js
export function foo(obj){
obj && obj.foo
}
export function bar(obj){
obj && obj.foo
}
// index.js
import { foo } from './util'
foo()
npx rollup index.js -f esm -o bundle.js Tree-Shaking之后:
// bundle.js
function foo(obj){
obj && obj.foo
}
foo这个函数,按照目前的写法是一个无意义的函数,但是为被删除
主要是因为可能会存在副作用,obj被代理了,obj && obj.foo 可能会触发 get代理。因此想要移除这个代码,可以这么做:
// index.js
import { foo } from './util'
/*#__PURE__*/ foo()
/*#__PURE__*/告诉rollup 这里没有任何副作用,可以Tree-Shaking
三、框架应该输出怎样的构建产物
1. 针对不同的环境有不同的构建产物
- 立即调用的函数表达式(IIFE)
<body>
<script src="..../vue.js" />
<script>
const {createApp} = Vue
//...
</script>
</body>
此时Vue这个变量会挂在到window上,成为全局变量
-
ESM(ES Module)
vue提供了两种方式
vue.esm-browser.js、vue.esm-bundler.js二者区别:
- vue.esm-browser.js
直接通过
<script type="module">使用
存在一个疑惑(希望各位大佬能帮忙解答一下): 书中说通过全局变量
__DEV__为ture || false来tree-shaking。tree-shaking是打包工具所拥有的,意思是说<script type="module">然后对html文件做打包?那和vue.esm-bundler.js没有太大的区别了- vue.esm-bundler.js
Vue在package.json的module中
{ "main":"index.js", "module":"dist/vue.runtime.esm-bunder.js" }webpack||rollup构建的时候,在没有特别指定Vue文件的时候,会默认使用vue.runtime.esm-bunder.js会根据process.env.NODE_ENV来做Tree-Shaking- cjs(CommonJS) 服务端渲染版本。 输出的资源是cjs模块资源。Node.js 直接require使用
- vue.esm-browser.js
直接通过
四、特性开关
- 框架具有向下兼容、多功能的支持,但是如果只使用某个功能,或者不使用某个功能,可以通过开关的形式,将其关闭,打包的时候,直接
Tree-Shaking,从而降低包体积。
比如:__VUE_OPTIONS_API__:打开或者关闭options api
开启,至此Vue3写法,options式
关闭,只能写Composition API
五、错误处理
错误直接决定用户应用程序的健壮性,还决定了开发者处理异常的错误的心理负担。
框架统一针对异常做处理,同时还提供用户针对异常自定义,从而提高可扩展性。
六、良好的TypeScript类型支持
- 误区:“使用TS编写框架和框架对TS类型支持优化不是一件事”
- 在一定程度上可以避免低级的bug、增强代码的可维护性。