I. Introduction
As we all know, Vite , as a next-generation front-end development and construction tool, is one word: fast. And Vite is already the default build tool for Vue3. Experiments show that after the project is migrated, from nearly 2 minutes in Vue-cli to 5 seconds in Vite (different project sizes and time), the speed is increased by dozens or even hundreds of times.
This article provides the most comprehensive solution on the entire network for the migration of old projects from Vue-cli to Vite. The following takes ant-design-vue-pro as an example to migrate, and the version of ant-design-vue is 1.7.8.
At the same time, the migrated warehouse is provided, welcome Star~
GitHub - Seals-Studio/ant-design-vue-pro-vite
For the migration of the Element-UI project, refer to the article: The most hard-core Element-UI in the entire network migrates from Vue-cli to Vite (2)
Comparison before and after migration (reference)
build tools | Server startup time | Page first load speed (no cache) | Second load speed (with cache) | Hot update HMR | Pack |
---|---|---|---|---|---|
Webpack | 83s | 4.78s | 3.35s | 4.78s | 3mins 37s |
Vite | 4.72s (0.72s for the second time) | 1.71s | 1.33s | moment | 51.45s |
2. Delete package.json related dependencies
Remove @vue and babel related
{ "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", "@vue/cli-plugin-babel": "^4.5.17", "@vue/cli-plugin-eslint": "^4.5.17", "@vue/cli-plugin-router": "^4.5.17", "@vue/cli-plugin-unit-jest": "^4.5.17", "@vue/cli-plugin-vuex": "^4.5.17", "@vue/cli-service": "^4.5.17", "@vue/eslint-config-standard": "^4.0.0", "@vue/test-utils": "^1.3.0", "babel-eslint": "^10.1.0", "babel-plugin-import": "^1.13.3", "babel-plugin-transform-remove-console": "^6.9.4", }
Remove loader (webpack plugin) and webpack
{ "file-loader": "^6.2.0", "less-loader": "^5.0.0", "vue-svg-icon-loader": "^2.1.1", "git-revision-webpack-plugin": "^3.0.6", "webpack-theme-color-replacer": "^1.3.26", }
- delete babel.conf.js and jsconfig.json
- Install the pnpm tool
pnpm is a fast, disk space saving package management tool
npm i -g pnpm
# 淘宝源
pnpm config set registry https://registry.npm.taobao.org
pnpm config set disturl https://npm.taobao.org/dist
pnpm config set NVM_NODEJS_ORG_MIRROR http://npm.taobao.org/mirrors/node
pnpm config set NVM_IOJS_ORG_MIRROR http://npm.taobao.org/mirrors/iojs
pnpm config set PHANTOMJS_CDNURL https://npm.taobao.org/dist/phantomjs
pnpm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/
pnpm config set SASS_BINARY_SITE http://npm.taobao.org/mirrors/node-sass
pnpm config set SQLITE3_BINARY_SITE http://npm.taobao.org/mirrors/sqlite3
pnpm config set PYTHON_MIRROR http://npm.taobao.org/mirrors/python
3. Install the latest version of vite and vite-plugin-vue2
pnpm add vite vite-plugin-vue2 -D
Fourth, create a new vite.conf.js in the root directory
import { defineConfig } from 'vite'
// vue2的vite插件
import { createVuePlugin } from 'vite-plugin-vue2'
export default ({ mode }) => {
return defineConfig({
plugins: [
createVuePlugin({
jsx: true
})
]
})
})
Five, index.html modification
- Move public/index.html to the code root directory (same level as package.json)
Add the following to the body tag:
<!-- 指明加载main.js --> <script type="module" src="/src/main.js"></script>
Replace variables injected by htmlWebpackPlugin plugin
htmlWebpackPlugin is a webpack plugin, so it can no longer be used, vite provides vite-plugin-html plugin to inject variables into index.html
Install vite-plugin-html
pnpm add vite-plugin-html -D
- Modify vite.config.js, add configuration
plugins: [ // ... createHtmlPlugin({ minify: true, inject: { data: { title: 'Ant Design Pro', cdn: { css: [], js: [ '//cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js', '//cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js', '//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js', '//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js' ] } } } }), // ... ]
Modify index.html
Modify title
<title><%= title %></title>
Modify css and js to import
<!-- require cdn assets css --> <% for (var i in cdn.css) { %> <link rel="stylesheet" href="<%= cdn.css[i] %>" /> <% } %> <!-- require cdn assets js --> <% for (var i in cdn.js) { %> <script type="text/javascript" src="<%= cdn.js[i] %>"></script> <% } %>
6. Environment variable replacement
For security reasons, vite can only recognize environment variables starting withVITE_
. The original VUE_ environment variable is not valid, and at the same time,process.env.xxx
cannot be used to read environment variables. . Need to modify the vite.conf.js configuration, manually addprocess.env.xxx
environment variable
Modify the vite.conf.js configuration and add environment variables
import { defineConfig, loadEnv } from 'vite' export default ({ mode }) => { const env = loadEnv(mode, process.cwd()) return defineConfig({ define: { 'process.env': { ...env } }, }) })
- Replace all environment variables beginning with
VUE_
withVITE_
- Change all
process.env.NODE_ENV
toimport.meta.env.MODE
- Change everything that starts with
process.env.
toimport.meta.env.
7. Ant-Design-Vue is introduced on demand
- Install the vite-plugin-style-import plugin
# 注意本插件必须采用1.4.1版本,不能采用最新版2.0.0
pnpm add vite-plugin-style-import@^1.4.1 -D
Add vite.conf.js configuration
plugins: [ // ... styleImport({ libs: [ { libraryName: 'ant-design-vue', esModule: true, resolveStyle: (name) => { return `ant-design-vue/es/${name}/style/index` }, } ], }), // ... ]
Eight, Ant-Design-Vue introduces moment problem
The reason is that the bottom layer of antdv adopts:
import * as moment from "moment";
Not compatible with ESM writing, refer to github issue: chore: v1 support vite
This article refers to the [] plugin and wrote a vite plugin to modify the introduction of moment at the bottom of antdv and change it to: import moment from moment
Install dependencies
pnpm add rollup@">=1.20.0 <2.0.0 || >=2.0.0 <3.0.0" -D pnpm add @rollup/plugin-replace -D
- Modify vite.conf.js configuration
import path from 'path-browserify'
import fs from 'fs'
import replace from '@rollup/plugin-replace'
// 参考vite-plugin-antdv1-momentjs-resolver插件,修改正则表达式,兼容Windows路径
// https://github.com/carl-jin/vite-plugin-antdv1-momentjs-resolver/blob/main/src/index.js
// 将moment_util.js中import * as moment from moment修改import moment from moment
// 原正则表达式
// const antdvDefaultReg = /ant-design-vue\/[\w-\\\/]*\.js$/
// 修改后正则表达式
// const antdvDefaultReg = /ant-design-vue[\/|\\][\w-\\\/]*\.js$/
const AntdMomentResolver = (reg = /ant-design-vue[\/|\\][\w-\\\/]*\.js$/) => {
return {
name: 'vite-plugin-antdv1-momentjs-resolver',
configResolved(config) {
// 以来预构建时候替换 esbuild
config.optimizeDeps.esbuildOptions.plugins = config.optimizeDeps.esbuildOptions.plugins
? config.optimizeDeps.esbuildOptions.plugins
: []
config.optimizeDeps.esbuildOptions.plugins.push({
name: 'replace-code',
setup(build) {
build.onLoad(
{
filter: reg,
},
(args) => {
// 首先获取源代码内容
let source = fs.readFileSync(args.path, 'utf8')
if (source.indexOf('import * as moment from')) {
source = source.replace(/import\s\*\sas\smoment\sfrom/g, 'import moment from')
}
return {
contents: source,
}
}
)
},
})
// 添加打包时的替换 rollup
config.plugins.push(
replace({
values: {
'import * as moment from': (id) => {
return 'import moment from'
},
},
include: [reg],
preventAssignment: true,
})
)
},
}
}
// 引入插件
export default ({ mode }) => {
return defineConfig({
plugins: [
// ...
AntdMomentResolver(),
// ...
]
})
}
9. Add an agent
install path-browserify
pnpm add path-browserify -D
Add vite.conf.js configuration
plugin: [], // ... server: { port: 8000, //proxy: { // '/api': { // target: 'https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro', // changeOrigin: true, // ws: false, // rewrite: (path) => path.replace(/^\/api/, ''), // } //}, },
Ten, package.json script command modification
Modify the script command as follows:
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
Eleven, postcss configuration
Install the plugin
pnpm add postcss autoprefixer -D
12. Add eslint plugin
Install the plugin
pnpm remove eslint eslint-plugin-html eslint-plugin-vue pnpm add eslint eslint-plugin-html eslint-plugin-vue eslint-config-prettier eslint-plugin-prettier prettier -D # vite-eslint插件 pnpm add vite-plugin-eslint -D
Add vite.conf.js configuration
import eslintPlugin from 'vite-plugin-eslint' export default ({ mode }) => { return defineConfig({ plugins: [ // ... eslintPlugin(), // ... ] }) }
13. Add lang="jsx" to the file with jsx syntax
<script lang="jsx">
...
</script>
14. Add @alias
Modify vite.conf.js configuration
export default ({ mode }) => {
return defineConfig({
resolve: {
// ...
alias: [
{
find: /@\/.+/,
replacement: (val) => {
return val.replace(/^@/, path.resolve(__dirname, './src/'))
},
},
]
},
)
}
15. Static file introduction
Introducing dynamic components
const modules = import.meta.glob('../views/**/*.vue') const currentRouter { ... // component: constantRouterComponents[item.component || item.key] || (() => import(`/src/views/${item.component}`)), component: constantRouterComponents[item.component || item.key] || modules[`../views/${item.component}.vue`], ... }
Importing static images
Direct
import
image<template> <img :src="LogoImg" /> </template> <script> import LogoImg from '/src/assets/img/logo.svg' export default { data() { return { LogoImg } } } </script>
Adopt
import.meta.globEager
- image loading
<template>
<img :src="getImg('../../assets/img/log.svg')" />
</template>
<script>
export default { methods: { getImg(path) { const modules = import.meta.globEager('../../assets/img/*.svg') return modules[path].default } } }
</script>
* 2. require.context替换
// before fixing
// const req = require.context('./svg', false, /.svg$/)
// const requireAll = requireContext => requireContext.keys().map(requireContext)// after modification
const req = import.meta.globEager('./svg/*.svg')
const requireAll = (requireContext) => Object.keys(requireContext).map((key) => requireContext[key].default)
### 十六、其他
Problem: fim.js dependency package reference problem
Solution: delete the viser-vue dependency package, you can use the official G2 package library @antv/g2plot instead
pnpm remove viser-vue pnpm add @antv/g2plot
Problem: ant-design-vue component List reference problem, List.Item is undefined
Solution 1: Replace the code
// 替换List组件代码,List.Item为undefined if (source.indexOf('Vue.component(List.Item.name, List.Item);')) { source = source.replace( 'Vue.component(List.Item.name, List.Item);', 'Vue.component("AListItem", Item);' ) } if (source.indexOf('Vue.component(List.Item.Meta.name, List.Item.Meta);')) { source = source.replace( 'Vue.component(List.Item.Meta.name, List.Item.Meta);', 'Vue.component("AListItemMeta", Item.Meta);' ) }
Solution 2: Refer to List.Item separately
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。