Vue2从Webpack 迁移到 vite
vue2项目要从webpack
迁移到 vite
需要完成以下几步
- 安装
vite
的依赖包 - 添加
vite
的配置文件vite.config.js
- 修改文件,包入口
index.html
和 其他文件 - 运行
vite
和vite build
根据报错,修改文件 - 删除无用的文件和依赖包
安装vite的依赖包
如果 vue
的版本 >= 2.7.0
使用 @vitejs/plugin-vue2
否则使用 vite-plugin-vue2
yarn add vite vite-plugin-vue2 -D
添加 vite 配置文件
项目根目录下添加 vite.config.js
文件
import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
export default defineConfig({
plugins: [
createVuePlugin({
jsx: true // 如果有sfc组件需要添加这一行
}),
viteCommonjs()
]
})
迁移 vue.config.js
配置
迁移 devServer
在 vite.config.js
中支持配置 serve
,和 webpack
的 devServer
差不多,区别是 rewrite
,在 vite
中是一个函数,返回重写后的值.
vite
默认不能通过 ip
访问,需要设置 host: '0.0.0.0'
server: {
host: '0.0.0.0',
proxy: {
'/test1': {
target: 'http://localhost:8080',
changeOrigin: true,
secure: false,
},
'/test2': {
target: 'http://localhost:8081',
changeOrigin: true,
secure: false,
}
}
}
迁移 svg-sprite-loader
在 vite
中使用 vite-plugin-svg-icons
实现和 webpack
中的 svg-sprite-loader
相同的功能
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
{
plugins: [
createSvgIconsPlugin({
// 这个目录直接配置成 .svg 文件所在的目录
iconDirs: [path.resolve("src/icons/svg")],
symbolId: "icon-[name]",
})
],
}
在 main.js
中添加 import 'virtual:svg-icons-register'
删除手动引入 svg
目录下的 *.svg
的代码
const req = require.context('./svg', false, /.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
配置 @
别名
{
resolve: {
alias: {
"@": path.resolve("src")
}
}
}
配置使用jsx
语法
{
esbuild: {
loader: {
".js": "jsx"
}
}
}
修改文件
修改入口文件
vite的入口文件默认是项目根目录下的 index.html
,所以需要把 public
目录下的 index.html
移动到项目根目录下
注意事项
- Vite 不支持
index.html
中的ejs
模版,删除<%= htmlWebpackPlugin.options.title %>
等语法。 - Vite 需要在
index.html
引入入口js文件,即添加<script type="module" src="/src/main.js"></script>
修改文件中的 require.context
require.context
替换成 import.meta.globEager
,例如
// require.context
const modulesFiles = require.context('./modules', true, /.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^./(.*).\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
// import.meta.glob
const modulesFiles = import.meta.globEager("./modules/*.js");
const modules = Object.keys(modulesFiles).reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^./modules/(.*).\w+$/, '$1')
const value = modulesFiles[modulePath]
modules[moduleName] = value.default
return modules
}, {})
修改文件中的 process.env
在 vite
中没有 process.env
,所有环境变量都通过 import.meta.env
获取,并且 import.meta.env
不能解构
自定义环境变量只能以 VITE_
开头,所以这里还需要修改 .env.*
的文件
// process.env
process.env.VUE_APP_BASE_API
// import.meta.env
import.meta.env.VITE_APP_BASE_API
修改 scss
文件名
这一步不是必须的,但是如果你在 js
中使用 scss
的变量,那么 scss
文件名必须是以 .module.scss
结尾的
使用 .module.scss
结尾之后,文件会被 postcss-modules
插件处理,最后的类名会被修改掉,稳妥一点的办法是新建一个.module.scss
后缀的文件,导入原来的文件,并导出需要给 js
使用的变量
@import "./variables.scss";
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
修改命令
{
"serve": "vite",
"build": "vite build"
}
运行 serve
和 build
运行之后一定会出现一些异常,先根据报错提示修复一波,下面列出了一些常见的错误.
删除不需要的资源
- 删除文件
vue.config.js
- 删除不需要的依赖包
@vue/cli-service
、@vue/cli-plugin-eslint
删除包之后,在启动的时候可能会提示缺少依赖包,在根据报错安装上对应的包就可以了
异常处理
-
EISDIR: illegal operation on a directory, read
-
出现这个问题是因为有访问的资源不存在,比如
src=""
或者href=""
-
引入
vue
文件的时候,没有加.vue
的后缀,或者没有index.vue
的文件路径关于这个问题还有一个解决方案:添加
vite
的扩展名.vue
-
{
resolve: {
extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json', '.vue']
}
}
- 使用
@import "~element-ui/packages/theme-chalk/src/index";
错误
vite
解析不了 scss
文件路径前面的~
,所以要删掉
- warning: Component /Users/aibee/workspace/ar-manager-platform/src/components/ai-design/ai-input/ai-input.vue uses lang html for template. Please install the language preprocessor.
因为在 .vue
文件的 template
上添加了 lang="html"
,要删掉
- Sfc 组件需要在script block中加上
lang=jsx
的标识 - Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/path-to-regexp.js?v=ff233f48' does not provide an export named 'default'
使用的模块没有默认的导出,使用 * as
方式倒入,例如 import * as pathToRegexp from 'path-to-regexp'
- Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/core-js_modules_es__function__name__js.js?v=a268d058' does not provide an export named 'default'
在 browserslist
中添加 not ie 11
, browserslist
在 package.json
中或者 .browserslist
文件中
- Uncaught ReferenceError: Cannot access 'Layout' before initialization
注意这里可能是出现了循环引用,如果是组件引用导致的,可以把组件引用改成懒加载的方式
- Error in render: "Error: Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code.
使用 path-browserify
模块 yarn add path-browserify -S
把 import path from 'path'
都改成 import path from 'path-browserify'
转载自:https://juejin.cn/post/7231448641976811577