Element-UI + Vue2 Migrate from Vue-cli to Vite

One: Delete related dependencies in the package.json file

1: Delete vue-cli related dependencies

 "@vue/cli-plugin-babel": "~4.5.0",
  "@vue/cli-plugin-eslint": "~4.5.0",
  "@vue/cli-service": "~4.5.0",

2: Delete babel related dependencies

 "babel-eslint": "^10.1.0",
    "babel-plugin-component": "^1.1.1",
    "babel-plugin-lodash": "^3.3.4",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
    "@vue/babel-preset-jsx": "^1.2.4",

3: Delete webpack related dependencies

 "hard-source-webpack-plugin": "^0.13.1",
    "compression-webpack-plugin": "^6.1.1",
    "lodash-webpack-plugin": "^0.11.6",
    "webpack-bundle-analyzer": "^4.4.2"
    "webpack-cli": "^4.3.0"

Two: Install pnpm

pnpm requires the node version to be greater than 16.14.0. If you need to be compatible with old projects and use lower versions of node, it is recommended to install nvm.

npm i -g pnpm
# taobaoyuan
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

Three: Install vite related dependencies

Install vite and vite-plugin-vue2

pnpm add vite vite-plugin-vue2 -D

Four: Create new vite.config.js in the project root directory to replace vue.config.js

import { defineConfig } from 'vite'

import { createVuePlugin } from 'vite-plugin-vue2'
?
export default ({ mode }) => {
  return defineConfig({
    plugins: [
      createVuePlugin({
        jsx: true
      })
    ]
  })
})

5: Move the index.html file to the project root directory

1: Move public/index.html to the code root directory (at the same level as the package.json file)

Add the following to the body tag:

<!-- Specify loading main.js -->
<script type="module" src="/src/main.js"></script>

Replace the variables injected by the htmlWebpackPlugin plugin

htmlWebpackPlugin is a webpack plug-in, so it can no longer be used. Vite provides the vite-plugin-html plug-in to inject variables into index.html

Install vite-plugin-html

pnpm add vite-plugin-html -D

2. Modify vite.config.js and add the configuration to inject variables into index.html

import {
createHtmlPlugin
} from 'vite-plugin-html'

export default ({mode}) => {
return defineConfig({
plugins: [
createHtmlPlugin({
minify: true,
inject: {
data: {
title: 'xxx',
cdn: {
css: [],
js: []
}
}
}
})
]
})
}

Modify index.html

<title><%= title %></title>
<% for (var i in cdn.css) { %>
    <link href="<%= cdn.css[i] %>" rel="stylesheet">
<% } %>
<% for (var i in cdn.js) { %>
    <script src="<%= cdn.js[i] %>"></script>
<% } %>

Six: Replace environment variables

For security reasons, vite can only recognize environment variables starting with VITE_. The original VUE_ environment variable is no longer effective. At the same time, process.env.xxx cannot be used. Let’s read the environment variables. It is necessary to modify the vite.conf.js configuration and manually add the process.env.xxx environment variable

Modify 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 starting with VUE_ with VITE_
  • Change all process.env.NODE_ENV to import.meta.env.MODE
  • Change everything starting with process.env. to import.meta.env.

Seven: Add proxy

Install path-browserify

pnpm add path-browserify -D

Add vite.conf.js configuration

plugins: [],
//
server: {
    port: 8000,
    proxy: {
        '/api': {
            target: 'https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro',
            changeOrigin: true,
ws: false,
rewrite: (path) => path.replace(/^\/api/, ''),
}
},
},
//

Eight: package.json command modification

 "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },

9: Install postcss

pnpm add postcss autoprefixer -D

Ten: Add lang=”jsx” to the file with jsx syntax

<script lang="jsx">
    ...
</script>

Eleven: Add @path alias

// vite.config.js

import path from 'path-browserify'

resolve: {
    alias: [
        {
            find: /@\/. + /,
replacement: (val) => {
return val.replace(/^@/, path.join(__dirname, './src/'))
},
},
{
// this is required for the SCSS modules
find: /^~(.*)$/,
replacement: '$1'
}
],
extensions: ['.js','.jsx','.vue','.json']
}

Twelve: Handling error reports

1.The following dependencies are imported but could not be resolved

If vue-quill-editor v-viewer is installed and depends on it, an error will be reported if you directly import quill/dist/quill.snow.css. This can be solved by using an alias. Similar problems can also be handled in this way.

{
    find: /quill/,
replacement: (val) => {
return val.replace(/quill/,'vue-quill-editor')
}
},
{
find: /viewer/,
replacement: (val) => {
return val.replace(/viewer/,'v-viewer')
}
}
2.the requested module ‘xx’ does not provide an export named ‘default’

Reason for the error: The imported library does not use export default to export, but directly uses export to export some properties and methods, so [import xxx from ”xxx’] cannot be used.

import * as VDistpicker from "@/libs/v-distpicker";

Solution: Through [import * as alias from ‘xxx’], you can access it through the alias

3.require is not defined


You cannot use require to import resources in vite, use the import method

import imgUrl from 'picture path'

export default {
    data:{imgUrl}
}
module ‘path’ has been externalized for browser compatibility

The original path module cannot be used in vite and needs to be replaced with the path-browserify module installed above.

4.svg does not display problem

Install vite-plugin-svg-icons

pnpm add vite-plugin-svg-icons -D

Introduced in main.js

import 'virtual:svg-icons-register'

Folder to store svg images

Configure in vite.config.js

import path from 'path-browserify'
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons'
 
export default defineConfig((command) => {
 return {
    plugins: [
      createSvgIconsPlugin({
        iconDirs: [path.join(process.cwd(), 'src/icons/svg')],
        symbolId: 'icon-[dir]-[name]'
      })
    ],
}
 
})

Encapsulating svg components

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use class="svg-use" :href="symbolId" />
  </svg>
</template>
 
<script>
  import { defineComponent, computed } from 'vue'
 
  export default defineComponent({
    name: 'SvgIcon',
    props: {
      prefix: {
        type: String,
        default: 'icon'
      },
      name: {
        type: String,
        required: true
      },
      className: {
        type: String,
        default: ''
      }
    },
    setup(props) {
      const symbolId = computed(() => `#${props.name}`)
      const svgClass = computed(() => {
        if (props.className) {
          return `svg-icon ${props.className}`
        }
        return 'svg-icon'
      })
      return { symbolId, svgClass }
    }
  })
</script>
<style scope>
  .svg-icon {
    vertical-align: -0.1em; /* Since the icon size is set to be consistent with the font size, and the lower edge of labels such as span will be aligned with the baseline of the font, a downward offset ratio needs to be set to correct the visual The misalignment effect*/
    fill: currentColor; /* Define the color of the element. currentColor is a variable. The value of this variable represents the color value of the current element. If the color value is not set for the current element, it is inherited from the parent element */
    overflow: hidden;
  }
</style>

Add in main.js

import svgIcon from './components/svgIcon/index.vue'
 
createApp(App).component('svg-icon', svgIcon)

Usage example

<SvgIcon name="issue"></SvgIcon>

<SvgIcon name="components-issue"></SvgIcon>

<SvgIcon name="charge-issue"></SvgIcon>

Note: If there are subfolders in the svg file, they need to be used in the manner of [folder name]-[svg file name]
For example use src/icons/svg/components/add.svg
Then pass the name attribute in the encapsulated svg component to components-add

5.element-ui table is not displayed and no error is reported

The problem lies in package.json, the vue version is 2.6.11, while the actual installed version is 2.7.15

Check that the vue version in node_modules is actually 2.7.15

For vue2.7 and later, you need to install @vitejs/plugin-vue2.
Uninstall vite-plugin-vue2 and install @vitejs/plugin-vue2

pnpm uninstall vite-plugin-vue2

pnpm add @vitejs/plugin-vue2
// vite.config.js
import vue from '@vitejs/plugin-vue2'
import { defineConfig } from 'vite'

export default({mode}) => {
    return defineConfig({
        plugins: [vue()]
    })
}
6: jsx file error

Install @vitejs/plugin-vue2-jsx

pnpm add @vitejs/plugin-vue2-jsx -D

vite.config.js

import vueJsx from '@vitejs/plugin-vue2-jsx'
plugins: [
vueJsx()
]
7.moment does not use the Chinese language pack
import 'moment/locale/zh-cn'

// Replace with

import 'moment/dist/locale/zh-cn'

Reference documents:

1. The most hard-core Element-UI on the entire network is migrated from Vue-cli to Vite

2. Use SVG images through vite-plugin-svg-icons

3. Remember a strange problem: Vite + Vue 2.7 + Element-UI el-table cannot be rendered.

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Vue entry skill treeVue-clivue-cli scaffolding installation 39,500 people are learning the system