一、前言
项目迭代过程中,模块越来越多,代码变得愈加臃肿,每次通过webpack启动项目都非常缓慢,而本地开发过程中只需要对少部分模块进行修改。
秉着对新技术、新思想的追求,同时也为了提升页面性能,提高用户使用体验,vite改造也被提上日程。
二、可行性分析
通过vite官方提供的插件和部分第三方库的支持,基本上可以帮我们解决大部分问题。还有一些问题会在👇详细描述
三、改造过程
- 添加
vite.config.ts到文件根目录,兼容处理vue.config.js里的配置
改造前的 vue.config.js
const { merge } = require('webpack-merge')
const tsImportPluginFactory = require('ts-import-plugin')
const path = require('path')
const MomentLocalesPlugin = require('moment-locales-webpack-plugin')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
parallel: false,
chainWebpack: config => {
config.module
.rule('ts')
.use('ts-loader')
.tap(options => {
options = merge(options, {
transpileOnly: true,
getCustomTransformers: () => ({
before: [
tsImportPluginFactory({
libraryName: 'vant',
libraryDirectory: 'es',
style: true
})
]
}),
compilerOptions: {
module: 'es2015'
}
})
return options
})
// set svg-sprite-loader
config.module.rule('svg').exclude.add(resolve('src/icons')).end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({ symbolId: 'svg-[name]' })
.end()
config.plugin('html').tap(args => {
args[0].title = '官网'
return args
})
config
.plugin('moment-locales')
.use(MomentLocalesPlugin, [{ localesToKeep: ['en', 'zh-cn'] }])
},
pluginOptions: {
gitDescribe: {
variableName: 'GIT_DESCRIBE'
}
}
}
改造后的 vite.config.js
import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import path from 'path'
import { minifyHtml, injectHtml } from 'vite-plugin-html'
import viteSvgIcons from 'vite-plugin-svg-icons'
// 动态加载
import ViteRequireContext from '@originjs/vite-plugin-require-context'
import compiler from 'vue-template-babel-compiler'
// commonJs的require用法转为原生import
import requireTransform from 'vite-plugin-require-transform/dist'
// webpack环境变量兼容
import env from 'vite-plugin-env-compatible'
import { gitDescribeSync } from 'git-describe'
export default defineConfig({
server: {
port: 8080
},
optimizeDeps: {
exclude: ['painter-kernel']
},
plugins: [
createVuePlugin({
jsx: true,
jsxOptions: { vModel: true },
vueTemplateOptions: { compiler }
}),
minifyHtml(),
injectHtml({
data: {
GIT_DESCRIBE: JSON.stringify(gitDescribeSync())
}
}),
viteSvgIcons({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')],
// Specify symbolId format
symbolId: 'svg-[name]'
}),
ViteRequireContext(),
requireTransform(/^((?!/node_modules/).)+.(jsx?|tsx?|vue)$/),
env()
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'~@': path.resolve(__dirname, 'src')
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
build: {
commonjsOptions: {
transformMixedEsModules: true
},
chunkSizeWarningLimit: 600,
cssCodeSplit: true
},
define: {
'process.platform': null,
'process.version': null
}
})
- 将
public里的文件移出到文件根目录,在body标签最下面加入
<script type="module" src="/src/main.ts"></script>
- 修改
pagekage.json中的启动方式
{
"serve": "vite",
"build": "vite build"
}
- 重新加载依赖,启动项目
yarn
yarn serve
- 打包后测试(重点!!!!)
yarn build
cd dist
serve
三、问题
-
vite里引入vue文件必须把后缀名
.vue带上,可以在extensions里配置['.vue'](官方不推荐,旧项目改造也只能这样了) -
一些样式中使用了
~@,需要在alias中配置 -
原先写在
.env文件中的环境变量,通过插件兼容,或者在define中定义,或者改为官方写法: 环境变量和模式 -
一些使用commonJs规范的依赖(主要是用了require),在
transform过程中未生效(比如引入了worker,解决方法Vite-Worker),实在不好解决只好将依赖放入项目内进行修改
- 如果你使用了代理工具,那么热更新可能不再起作用,比如在LightProxy中配置了:
https://www.xiangmu.com http://localhost:8080
因为vite热更新走的是wss://服务,所以要更改一下代理:
www.xiangmu.com http://localhost:8080
四、总结
总体来说,改造并不算困难,遇到的坑也都能找到对应的解决方案(重点关注打包是否有报错以及依赖中require的使用,改造过后要对所有的页面及功能进行全量回归!!!),目前已在两个项目中成功升级改造为vite,大幅提高了开发体验,还在观望中的小伙伴可以尝试一下😆