convert a webpack project to a vite project
- download
git clone https://github.com/originjs/webpack-to-vite.git
cd webpack-to-vite
- install
with npm, run
npm install
npm run build
with yarn, run
yarn
yarn build
- convert
node ./bin/index -d <project path>
The following is a list of projects that successfully converted from a webpack project to a vite project using the tool
- helloworld-vue2
- helloworld-vue3
- helloworld-webpack
- vue-manage-system-vite
- newbee-mall-vue3-app-vite
- vue-realworld-example-app-vite
- vue-uploader-vite
- douban-vite
- vue-manage-system -> vue-manage-system-vite
- newbee-mall-vue3-app -> newbee-mall-vue3-app-vite
- vue-realworld-example-app -> vue-realworld-example-app-vite
The following is a list of configuration items that need to convert
Legend of annotations:
Mark | Description |
---|---|
✅ | auto convert by webpack-to-vite |
need manual convert | |
❌ | not support now |
- ✅ B01: add required devDependencies and dependencies in
package.json
- required:
vite-plugin-env-compatible
,vite
, - Vue2 required:
vite-plugin-vue2
- Vue3 required:
@vue/compiler-sfc
,@vitejs/plugin-vue
,@vitejs/plugin-vue-jsx
- required:
- ✅ B02: add vite entry file
index.html
to root directory- add entry point like:
<script type="module" src="/src/main.js"></script>
, don't need to adddev-client
entry point because vite support hmr default
- add entry point like:
- ✅ B03: add vite config file
vite.config.js
to root directory - ✅ B04: import and use required plugins in
vite.config.js
- required
vite-plugin-env-compatible
- Vue2 required:
vite-plugin-vue2
, pass{ jsx: true }
option to enablejsx
support default - Vue3 required:
@vitejs/plugin-vue
,@vitejs/plugin-vue-jsx
- required
- ✅ B05: support imports that omit
.vue
extension- in
vite.config.js
, add.vue
toresolve.extensions
to default configuration, then you may encounter issue like 'Problems caused by using alisaes and omitting file suffixes at the same time', we use patch to fix this issue, in case of vite didn't accept relate PR
- in
- ✅ B06: sass support
- if using
node-sass
dependency before, convert tosass
dependency
- if using
- ✅ B07: postcss 8 support
- if using postcss 8 before, add
postcss
dependency
- if using postcss 8 before, add
Vue-CLI conversion are base on
vue.config.js
, map configuration tovite.config.js
- ✅ V01: base public path
process.env.PUBLIC_URL
orpublicPath
orbaseUrl
->base
- ✅ V02: css options
css.loaderOptions
->css.preprocessorOptions
css.loaderOptions.less.lessOptions.modifyVars
->css.preprocessorOptions.less.modifyVars
- if there is only
css.loaderOptions.sass
options, convert tocss.preprocessorOptions.sass
andcss.preprocessorOptions.sass
. Thesass
configuration takes effect bothsass
andscss
in Vue-CLI while vite need configure they respectively
- ✅ V03: server options
- default set
server.strictPort = false
process.env.PORT
ordevServer.port
->server.port
process.env.DEV_HOST
ordevServer.public
ordevServer.host
->server.host
, and replacehttp://
orhttps://
to''
devServer.open
,devServer.https
->server.open
,server.https
devServer.proxy
->server.proxy
, in proxy configuration, convertpathRewrite
->rewrite
- default set
- ✅ V04: build options
outputDir
->build.outDir
css.extract
->build.cssCodeSplit
- if
process.env.MODERN === 'true'
, setbuild.minify = esbuild
- if
process.env.GENERATE_SOURCEMAP === 'true'
orvueConfig.productionSourceMap
orcss.sourceMap
->build.sourcemap
- ✅ V05:
resolve.alias
options- add default alias options
resolve: { alias: [ { find: '/^~/', replacement: ''}, { find: '@', replacement: path.resolve(__dirname,'src') } ] }
- convert webpack alias options to match format above
- ✅ V06: default values exposed by plugins or client-side env variables
- replace jsp scriptlet tags in
index.html
to exact values
- replace jsp scriptlet tags in
Webpack conversion are base on
webpack.config.js
orwebpack.base.js、webpack.dev.js、webpack.prod.js|webpack.build.js|webpack.production.js
, map configuration tovite.config.js
Note: if you are not using configuration file above, you need to convert configuration manually instead using tool
- ✅ W01: build input options
- if
entry
isstring
type,entry
->build.rollupOptions.input
- if
entry
isobject
type, convert each object property and each array element tobuild.rollupOptions.input
- if
entry
isfunction
type, convert function execute result tobuild.rollupOptions.input
- if
- ✅ W02: outDir options
output.path
->build.outDir
- ✅ W03:
resolve.alias
options- add default alias options
resolve: { alias: [ { find: '@', replacement: path.resolve(__dirname,'src') } ] }
- convert webpack alias options to match format above
resolve.alias
options key has trailing$
, need to remove '$' and re-assign an exact path value
- ✅ W04: server options
devServer.host
,devServer.port
,devServer.proxy
,devServer.https
,devServer.contentBase
->server.host
,server.port
,server.proxy
,server.https
,server.base
- ✅ W05: define options
new webpack.DefinePlugin()
->define
⚠️ O01: use CommonJS syntax, e.g.require('./')
- add vite plugin
@originjs/vite-plugin-commonjs
, see detail: https://github.com/originjs/vite-plugins/tree/main/packages/vite-plugin-commonjs
- add vite plugin
- ❌ O02: use ElementUI, see detail: vitejs/vite#3370
[vite] Uncaught TypeError: Cannot read property '$isServer' of undefined at node_modules/[email protected]@element-ui/lib/utils/dom.js (:8080/node_modules/.vite/element-ui.js?v=675d2c77:1189) at __require (:8080/node_modules/.vite/chunk-6VNJZP5B.js?v=675d2c77:12) at node_modules/[email protected]@element-ui/lib/utils/popup/popup-manager.js (:8080/node_modules/.vite/element-ui.js?v=675d2c77:1478) at __require (:8080/node_modules/.vite/chunk-6VNJZP5B.js?v=675d2c77:12) at node_modules/[email protected]@element-ui/lib/utils/popup/index.js (:8080/node_modules/.vite/element-ui.js?v=675d2c77:1701) at __require (:8080/node_modules/.vite/chunk-6VNJZP5B.js?v=675d2c77:12) at node_modules/[email protected]@element-ui/lib/utils/vue-popper.js (:8080/node_modules/.vite/element-ui.js?v=675d2c77:2546) at __require (:8080/node_modules/.vite/chunk-6VNJZP5B.js?v=675d2c77:12) at Object.5 (:8080/node_modules/.vite/element-ui.js?v=675d2c77:6861) at __webpack_require__ (:8080/node_modules/.vite/element-ui.js?v=675d2c77:6547)
⚠️ O03: css automatic imports- if use
style-resources-loader
before, try to replace byadditionalData
. Example:
->pluginOptions: { 'style-resources-loader': { preProcessor: 'less', patterns: [ resolve('src/styles/var.less'), resolve('src/styles/mixin.less') ] } }
css: { preprocessorOptions: { less: { additionalData: `@import 'src/styles/var.less';` + `@import 'src/styles/mixin.less';` } } }
- if use
⚠️ O04: imports path include multiple alias like:@import '~@/styles/global.scss'
, which is includes alias~
and@
- add an alias configure
{ find: /^~@/, replacement: path.resolve(__dirname, 'src') }
toresolve.alias
options, and place it on first
- add an alias configure
⚠️ O05: usejsx
syntax in.vue
file- make sure enable
jsx
support, Vue2 add pluginvite-plugin-vue2
and pass{ jsx: true }
option, Vue3 add plugin@vitejs/plugin-vue-jsx
- add attribute
lang="jsx"
toscript
label, e.g.<script lang="jsx"></script>
- If the following error occurs
add config to3:54:29 PM [vite] Internal server error: /Users/Chieffo/Documents/project/Vue-mmPlayer/src/base/mm-icon/mm-icon.vue?vue&type=script&lang.tsx: Duplicate declaration "h" (This is an error on an internal node. Probably an internal error.) Plugin: vite-plugin-vue2 File: /Users/Chieffo/Documents/project/Vue-mmPlayer/src/base/mm-icon/mm-icon.vue?vue&type=script&lang.tsx at File.buildCodeFrameError (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/core/lib/transformation/file/file.js:244:12) at Scope.checkBlockScopedCollisions (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/scope/index.js:421:22) at Scope.registerBinding (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/scope/index.js:581:16) at Scope.registerDeclaration (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/scope/index.js:523:14) at Object.BlockScoped (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/scope/index.js:240:12) at Object.newFn (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/visitors.js:212:17) at NodePath._call (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/path/context.js:36:14) at NodePath.visit (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/path/context.js:90:31) at TraversalContext.visitQueue (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/context.js:99:16) at TraversalContext.visitMultiple (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/context.js:68:17) at TraversalContext.visit (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/context.js:125:19) at Function.traverse.node (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/index.js:76:17) at NodePath.visit (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/path/context.js:97:18) at TraversalContext.visitQueue (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/context.js:99:16) at TraversalContext.visitSingle (/Users/Chieffo/Documents/project/Vue-mmPlayer/node_modules/@babel/traverse/lib/context.js:73:19)
babel.config.js
->module.exports = { presets: [ '@vue/app' ] }
module.exports = { presets: [ ['@vue/app', { useBuiltIns: 'entry', jsx: { injectH: false } }] ] }
- make sure enable
⚠️ O06: use webpack apirequire.context
- add vite plugin
@originjs/vite-plugin-require-context
, see detail: https://github.com/originjs/vite-plugins/tree/main/packages/vite-plugin-require-context
- add vite plugin
- ✅ O07: fix issue 'Compiling error when the template of the .vue file has the attribute lang="html"'
- remove
lang="html"
attribute fromtemplate
label, see detail: vuejs/vue-loader#1443
- remove
- ❌ O08: use webpack api
require.ensure
⚠️ O09: convert dynamic imports that paths include alias to absolute path or relative path, see detail: see detail: https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations->() => import('@/components/views/test.vue')
() => import('./components/views/test.vue')