为什么改用vite
可能是我闲着。
能不动就不动吧,折腾啊,你看看vite的issue数量那么多。
旧项目慢的话,不如换个新macbook pro吧,质的改变。不仅“webpack项目”启动变快,而且“vite项目”启动还会更快!
我的依赖
- @vitejs/plugin-legacy。浏览器兼容性处理
- @vitejs/plugin-react。集合插件,相当于react插件的preset
- vite-plugin-inspect。调试用,可忽略
- postcss-flexbugs-fixes
- postcss-preset-env
- autoprefixer
后面3个主要是处理css,
const loder_presetEnv = postcssPresetEnv({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
});
// vite配置
{
css: {
modules: {
scopeBehaviour: 'local',
},
postcss: {
plugins: [autoprefixer, postcssFlexbugsFixes, loder_presetEnv],
},
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
scss: {},
},
},
}
问题汇总
当时是直接抄的别人配置,后来发觉@vitejs/plugin-react
可以解决很多事情,比如第七个问题
1.xxx does not provide an export named 'xxx'
比较常见错误。ts导出报错,要把import {xxx} from '...'
改成
import type {xxx} from '...'
,多一个关键字“type”。
因为还有其他分支开发业务,每次合并可能处理type会有冲突,同时,文件太多了。决定撸个解决这个问题的插件,叫
vite-plugin-transform-ts-import
。
快就快在用这个插件,解决这个问题。该插件可以自动帮你做加“type”这个处理,省心省力。
2.process 未定义
配置文件追加,这个也是常见的环境变量获取方式改造。
define: {
'process.env': process.env,
},
同时 package.json
里面原本的环境变量,提到vite
关键字之前
"script": {
"vite": "MY_ENV=dev vite",
}
也可以考虑
import.meta.env
,终端参数是mode,详情翻阅官方文档
3. 'ReferenceError: require is not defined'
可以去找github.com/vitejs/awes… ,
- 关键字是“require”的插件。有对应的插件,
- 也可以试试“vite-plugin-commonjs”。
第一点我都没有生效,还会报奇怪的错。就直接改成import。
但是下面这个写法,还不知道好的办法代替,就把所有环境配置放进来,不多。
const config: Config = require(`./${env}`).default
4. Uncaught TypeError: require.context is not a function
同上。 这个主要是用了webpack的require.context特性,获取当前文件。 我是直接用vite提供import特性解决
const modules = import.meta.globEager('./*.ts')
5.react 多次定义
<!--配置追加-->
esbuild: {
jsxFactory: '_jsx',
jsxFragment: '_jsxFragment',
jsxInject: `import { createElement as _jsx, Fragment as _jsxFragment } from 'react'`,
},
可能会碰到吧,改了其他commonjs插件或官方的react插件,之后不复现,当时并没有在意和记录
6.dev 模块导入问题
error: [plugin: vite:dep-pre-bundle] Failed to resolve entry for package "child_process".
error when starting dev server:
Error: Build failed with 1 error:
xxxPaths/dep-36bf480c.js:43807:10: error: [plugin: vite:dep-pre-bundle] Failed to resolve entry for package "child_process". The package may have incorrect main/module/exports specified in its package.json: Failed to resolve entry for package "child_process". The package may have incorrect main/module/exports specified in its package.json.
原本可运行,用yarn装的依赖,装了几个依赖和复制几个代码进来后报错。
搜出github有类似报错,不过是Pnpm。怀疑是依赖问题。
无法定位是哪个依赖造成的问题。回滚一次可以运行,逐个安装排查。
石锤socket.io-client
的问题,但是node_modules里面确实没有child_process
- 方法一
翻了一下node_modules,
socket.io-client
的出口文件是build/index.js
里面用的是“require”,需要支持用插件支持,增加一下配置代码
import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
export default defineConfig({
plugins: [
...
viteCommonjs({
include: ['socket.io-client']
}),
]
})
- 方法二 但是重启vite后又不行了,最后解决办法,在issue里面翻到了,加配置
resolve: {
alias: [
{find: 'socket.io-client', replacement: 'socket.io-client/dist/socket.io.js',},
]
}
可以考虑用CDN链接注入script获取
7.构建时候相对路径报错
Could not resolve './typings' from xxx.tsx
好像这个rollup算是问题,使用了@rollup/plugin-node-resolve
尝试解决。
最后发现是“d.ts”后缀的文件,可以看浏览器的network,vite并不能请求到这种后缀的文件。批量改就行了。
build不通的文件,应该尝试跳到那个页面去看看。这里问题是有漏网的“d.ts”文件,改成“.ts”就行了
8. 无法解析class预发
最后这两个是插件碰到的问题。
[vite] Internal server error: This experimental syntax requires enabling the parser plugin: 'classProperties'
这事解析出错,自定义插件的babel也要装babel插件。
自定义的插件里面也要补充
module.exports = {
plugins: ['@babel/plugin-syntax-class-properties'],
}
9 node_moduels里面的模块无法导入
'getAugmentedNamespace' is not exported by commonjsHelpers.js, imported by /xxx/node_modules/rc-field-form/es/index.js?commonjs-proxy
应该是和其他插件有了冲突? 这些奇奇怪怪问题,给插件做了关键字过滤,传入对应文件名不作处理。
插件编写
vite-plugin-transform-ts-import:写的很粗糙,但也能用在这个文件众多的项目跑,毕竟改几百个 import 代码更加累,而且还要合并其他业务分支。
vite插件也如同rollup插件,不过多一些特定钩子。需要注意的是各个插件和各个钩子之间的顺序。可以看看别人的插件,可以比较简陋地解决一些问题。
原理
在bable的ast中,
import {RenderBtnProps} from 'src/typings'
这一句的ts声明导入,它的节点 importKind
是“value”,而esbuild 辨识的是 “type”。
所以插件原理是,通过babel分析src
里当前使用的文件,存储所有ts的声明,如果import的变量名是存储空间中的ts,加个type进去。
所以,依赖包里面的ts声明要手动输入给插件记录,或者自己改成import type
包括自动处理这些情况
export {ShowProductIdListProps} from './productIdListTyping'
export default from './couponTypeing'
export {default as RenderProductIdsBySelect} from './renderProductIdsBySelectTyping'
官方调试插件
叫这个:vite-plugin-inspect,启动然后打开 https://xxxx/__inspect,
可以看到每个插件处理的结果,就相当于webpack的各个Loader,点进去方便查阅自己的插件编译结果,每个文件都可以看到转换的前后对比。
同时还会记录每个插件的耗时,显示我的插件顶多也是几百ms,不大影响vite的速度优势。
帮转小广告
珠海金山办公,诚招各岗位开发和产品,包餐、海景办公等福利,自己翻招聘软件咯。
内推极有机会绕过学历(重点大学本科or研究生之类)要求,联系方式:610038187@qq.com。