1
头图

I. Introduction

Not long ago, the ant-design-vue-pro project was migrated. Reference article: The most hard-core Ant-Design-Vue in the entire network migrated from Vue-cli to Vite (1) . The migrated project address: GitHub - Seals -Studio/ant-design-vue-pro-vite

In this issue, the Element-UI library is migrated, and the vue-element-admin project is used as an example to migrate. The element-ui version is 2.13.2. At the same time, the migrated warehouse is provided, welcome Star~

GitHub - Seals-Studio/vue-element-admin-vite

2. Background

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.

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

3. Delete package.json related dependencies

  1. Remove @vue and babel related

     {
        "@vue/cli-plugin-babel": "4.4.4",
        "@vue/cli-plugin-eslint": "4.4.4",
        "@vue/cli-plugin-unit-jest": "4.4.4",
        "@vue/cli-service": "4.4.4",
        "@vue/test-utils": "1.0.0-beta.29",
        "babel-eslint": "10.1.0",
        "babel-jest": "23.6.0",
        "babel-plugin-dynamic-import-node": "2.3.3",
    }
  2. Remove loader (webpack plugin) and webpack

     {
        "html-webpack-plugin": "3.2.0",
          "script-ext-html-webpack-plugin": "2.1.3",
        "sass-loader": "8.0.2",
        "svg-sprite-loader": "4.1.3",
    }
  3. delete babel.conf.js and jsconfig.json
  4. 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

Fourth, install the latest version of vite and vite-plugin-vue2

 pnpm add vite vite-plugin-vue2 -D

5. 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
      })
    ]
  })
})

Six, 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
    1. Install vite-plugin-html

       pnpm add vite-plugin-html -D
    2. Modify vite.config.js, add configuration
     plugins: [
          // ...
          createHtmlPlugin({
            minify: true,
            inject: {
              data: {
                title: 'vue Element Admin',
                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'
                  ]
                }
              }
            }
          }),
          // ...
        ]
    1. 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>
            <% } %>

Seven, environment variable replacement

For security reasons, vite can only recognize environment variables starting with VITE_ . The original VUE_ environment variable does not take effect. At the same time, process.env.xxx cannot be used to read environment variables. . Need to modify the vite.conf.js configuration, manually add process.env.xxx environment variables
  • 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 starting with VUE_ with VITE_
  • Change all process.env.NODE_ENV to import.meta.env.MODE
  • Change everything that starts with process.env. to import.meta.env.

8. Element-UI is introduced on demand

  1. Install the vite-plugin-style-import plugin
 # 注意本插件必须采用1.4.1版本,不能采用最新版2.0.0
pnpm add vite-plugin-style-import@^1.4.1 -D
  1. Add vite.conf.js configuration

     plugins: [
        // ...
        styleImport({
            libs: [
              {
                libraryName: 'element-ui',
                // styleLibraryName: 'theme-chalk',
                esModule: true,
                resolveStyle: (name) => {
                  return `theme-chalk/${name}.css`
                }
              }
            ],
          }),
        // ...
    ]

9. Add an agent

  1. install path-browserify

     pnpm add path-browserify -D
  2. 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

  1. Install the plugin

     pnpm add postcss autoprefixer -D

12. Add eslint plugin

  1. 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
  2. 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/'))
              },
           },
           {
             // this is required for the SCSS modules
             find: /^~(.*)$/,
             replacement: '$1'
           }
         ]
       },
    )
}

15. Static file introduction

  1. 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`],
        ...
    }
  2. Importing static images

    • Direct import Picture

       <template>
          <img :src="LogoImg" />
      </template>
      
      <script>
          import LogoImg from '/src/assets/img/logo.svg'
          export default {
              data() {
                  return {
                      LogoImg
                  }
              }
          }
      </script>
    • Using import.meta.globEager

        1. 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)

     ### 十六、雪碧图加载svg-sprite-loader替换
  3. Install vite-plugin-svg-icons plugin

     pnpm add vite-plugin-svg-icons -D
  4. configure vite.config.js

     import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
    
    defineConfig({
     plugins: [
         // ...
         // 雪碧图
     createSvgIconsPlugin({
         // 指定需要缓存的图标文件夹
         iconDirs: [path.resolve(__dirname, './src/icons/svg')],
         // 指定symbolId格式
         symbolId: 'icon-[dir]-[name]',
    
         /**
          * 自定义插入位置
          * @default: body-last
          */
         inject: 'body-last' | 'body-first',
    
         /**
          * custom dom id
          * @default: __svg__icons__dom__
          */
         customDomId: '__svg__icons__dom__'
       })
     ]
    })
  5. add in main.js


silianpan
160 声望9 粉丝

专注于web前端,spring boot,微服务架构。坚持原创技术分享,为开源贡献力量。