bug 和 pr
bug
Support decorators in .vue file.
pr
allows overwrite esbuild config
问题发现与解决记录
问题发现
使用vue-facing-decorator这个库开发vue时,发现无法在vite + vue项目中正常使用
### 一个面向class编程的爱好者
我最开始是学java的,在编写vue时,也喜欢使用java的那套oop写法,所以我使用了支持vue3 + oop 写法的vue-facing-decorator库
tc39的离谱规则,target小于ESNext时,自动转换装饰器,ESNext则不转换
然后在我使用中就遇到了一些问题,关于最新的装饰器提案,tc39有一个比较离谱的规则,即当typesciprt:target小于ESNext时,自动转换装饰器,ESNext则不转换,而esbuild的默认target就是esnext,vite又使用esbuild编译ts,这问题不就来了
在vite+typescript中使用属性装饰器decorator一定要单独修改配置,否则就会遇到vite的这个issus,与这个esbuild规则有关
解决问题记录
- 最开始我遇到了,无法在vite+vue中使用tc39最新提案的装饰器语法
- 使用vite编译最简化代码测试,问题依旧存在
- 手动使用tsc和esbuild编译最简化代码测试,发现tsc编译正常,esbuild异常,此时我还什么都不懂,以为是esbuild有问题,就去给esbuild提了bug,The execution results of decorator code compiled by esbuild and compiled by tsc are inconsistent ,之后被esbuild作者告知,原因:tsc默认target:es5, esbuild默认target:esnext
- 指定target使用esbuild编译正常,
- 指定target使用vite编译正常
- 指定target使用vite+vue编译,发现.vue文件中的装饰器代码无法正常编译,
- 在git上搜索相关问题,发现相关issues dev模式下,调用esbuild构建时的配置是否可以从vite.config.js同步读取或者支持参数传入? 开发服务器不会转译 .vue 文件中的脚本(但可以转译 .ts 文件中的脚本,验证问题,发现build环境下,代码正常,只有开发环境下存在问题
- 将vite.config.ts中的 build:{minify:false}, 查看编译后的代码,
- 调试源码发现开发和build环境下,同样是.vue文件却走了不同分支,开发环境下是.vue文件单独编译,build环境下是vue中的script使用esbuild编译ts的通用逻辑
- 编写测试插件,使用在插件中使用@vue/compiler-sfc获取.vue文件中的script代码块,使用esbuild编译发现编译正常
- debug,vue-plugin-vue,获取编译.vue文件时的参数,在测试插件中使用相同插件,发现编译错误
- 得到结果,编译问题是由于编译参数错误导致的
- 对比正确和异常参数,发现是esbuild{target}异常导致的,target是esnext而不是指定的es2020
- 然后调试为什么vue-plugin-vue,esbuild{target:esnext},发现代码中写死了target:esnext,而没有使用vite.config.ts中的配置
- 然后就是查找如何在插件中获取vite.config.ts中的esbuild配置,由于vue-plugin-vue是开源插件,尽量不改动原有逻辑,调试发现vue-plugin-vue插件中存在一个
options.devServer?.config.esbuild可以在开发环境正确获得vite.config.ts中的esbuild配置,又因为7. 只在开发环境下才会单独编译.vue文件,所以使用options.devServer?.config.esbuild 是可以接受的,所以在调用.esbuild编译单独.vue文件的script脚本时,把options.devServer?.config.esbuild传入就可以了