background

The project itself is vue2 family bucket, code almost a year ago, the library involved is not a lot, compare the standard background admin project

Every day looked at vite good vite fast, some articles even reached the development environment 10 times, and then look at the article change is not much, the heart is ready to move 0 0

During this period of time this year, I have time to upgrade vite to the second generation, breaking away from the strong dependence of VUe3, so I tried to migrate non-main process company business from VUE-CLI to Vite

The topic outside

Look at everyone’s posts about how easy it is, how many changes there are, our project is too strange?

In the process of basic is a pit step, as expected or their own too dish TT

The migration process

1. Configure files and process vUE

The configuration file, like webpack, creates viet.config.ts in the root directory

npm i -D vite
Copy the code

The configuration file is also very much like vue.config

import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    // ...
  ],
})
Copy the code

Awesome-vite plugin address find vue’s corresponding plugin vite-plugin-vue2 here

NPM i-d vite-plugin-vue2... Plugins: [createVuePlugin({JSX: true,}),]... plugins: [createVuePlugin({JSX: true,}),]...Copy the code
Q1: How does the Vue plugin JSX work and what issues can be handled, seems to be babel-PRESET – JSX? To deal with the

2. Entry and HTML files

A little different from WebPack, Vite also requires entry files, but uses HTML to enter them

<! DOCTYPEhtml>
<html lang="zh-CN">

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="Width = 1024, initial - scale = 1.0" />
  <title>Xi xi xi</title>
</head>

<script>
  window.process = {}; // This fixes the path import error
</script>

<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
  <! -- built files will be auto injected -->
</body>

</html>
Copy the code

Since the original project HTML file is under the public file rack and has multiple entries, the configuration file needs to modify the corresponding entries

 build: {
    rollupOptions: {
      input: {
        main: path.resolve(__dirname, 'public/index.html')
      },
    },
  }
Copy the code

Oh, come on! No! Wonder why. Eventually, though, I put the main index in the root directory

Q2: We’ll look at that later as well
Q3: window.process = {}; If I don’t add this, my path will report an error without process

3. Environment variables

Webpack provides process.env to access environment variables and differentiate between different environments

const PRO_HOST = process.env.PRO === 'xxx'
  ? 'aaa'
  : 'bbb';
Copy the code

Vite still supports the use of environment variables, but it provides another set of import.meta.env to access environment variables instead of process.env: it also provides the root. Env file to add additional environment variables

4. Replace CommonJS and various introduction issues

1. Replace commonJs with commonJs, which is a reference to another nugget

2. Style introduced substitutions

@import '~@/styles/mixin.scss';
@import '~@/styles/variables.scss';
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
Copy the code

Write @import ‘@/styles/ variable. SCSS ‘; You don’t need the tilde anymore

$--font-path: 'element-ui/lib/theme-chalk/fonts';
@import "element-ui/packages/theme-chalk/src/index";
Copy the code

3. / deep/support

Vite provides plug-in support for CSS preprocessors, but requires preprocessors to be installed. Sass-loader does not support /deep/, so use the latest :: V-deep loader. Along the way, I’ve gained a deeper understanding of this VUe-specific syntax

4.Glob import (encountered many pits here)

In order to solve the problem of routing and store, in the convenience of Webpack, the previous route is written according to the folder automatically imported, the following code:

export const basicRoutes = require
  .context('@/views/basic'.true./\/index\.vue$/)
  .keys()
  .map(url= > url.replace(/ ^ \ \ / /.' ').replace(/\/index\.vue$/.' '))
  .map(pathName= > {
    return {
      path: ` /${pathName}`.name: pathName,
      component: () = >
        import(/* webpackChunkName: "[request]" */ `@/views/basic/${pathName}/index.vue`),}; });Copy the code

After switching from webpack to Vite, require.context is no longer available, so check the documentation to find import.meta.globEager

Again, look at the code and tell the problem later

let files = import.meta.globEager('/src/views/division/*/index.vue');
export const divisionRoutes = Object.keys(files)
  .map(url= >
    url
      .replace(/\/index\.vue$/.' ')
      .replace(/src([a-zA-Z\_]*\/)*/.' ')
      .replace(/ / / /.' ')// Forgive my ugly regular
  )
  .map(pathName= > {
    return {
      path: ` /${pathName}`.name: pathName,
      component: files[`/src/views/division/${pathName}/index.vue`].default,
    };
  });
Copy the code

There are two problems here, and there should be a better solution, but it just barely works out of solving the problem first

  1. import.meta.globEager('/src/views/division/*/index.vue')The introduction of modules is an object composed of modules, and the original path is not quite the same
  2. The component import starts with an import and then runs into problems

The installation@rollup/plugin-dynamic-import-varsAfter the plug-in in

import dynamicImportVars from '@rollup/plugin-dynamic-import-vars'; Plugins: [createVuePlugin({JSX: true,}), injectHtml({injectData: {title: 'User management system ',},}), dynamicImportVars(),],Copy the code

Instead, an error was reported. Since the error is reported in Vite, so I want to introduce modules directly, simply introduce it, so there is the above code, successfully solve the problem

component: files[`/src/views/division/${pathName}/index.vue`].default,
Copy the code
Q4: The solution here needs to be discussed. Try to solve it after learning

5. JSX problem

Vue-cli is automatically introduced into Babel, so JSX can be used directly in it, as shown in the following code

vnodes.push(<svg-icon icon-class={icon} />);
Copy the code

But this is not recognized in Vite

At the beginning, I mentioned that the vue2 plug-in was introduced. I found that there were JSX options in it, but it didn’t work after I opened it. Maybe I opened it in the wrong way

createVuePlugin({
   jsx: true.// I don't think so. It's just the way I use it
}),
Copy the code

The final solution is to change the createElement method

render(h, context) {
    const { icon, title } = context.props;
    const vnodes = [];

    if (icon) {
      const elHtml = h('svg-icon', {
        attrs: {
          'icon-class': icon,
        },
      });
      vnodes.push(elHtml);
    }

    if (title) {
      const elHtml = h(
        'span',
        {
          attrs: {
            slot: title,
            class: 'system-menu-title',
          },
        },
        title
      );
      vnodes.push(elHtml);
    }
    return vnodes;
  },
Copy the code
Q5: Try to pass laterrollup-plugin-babelplus@vue/babel-preset-jsxSupport for JSX through plug-ins

6. Use of method decorators

The original project in order to achieve some control requests for repeated submission and other requirements, through the way of decorator to write some methods, when used directly on the method is good

However, I encountered problems in Vite, checked relevant materials and changed the build.target, and found that it still did not work. Now I have to comment out and deal with other problems

Q6. Use of decorators
@debounceDecorator()
async getSearchList() {}
Copy the code

5.alias

Without further ado, vite provides the configuration, as required to add good

  resolve: {
    alias: {
      '@': path.resolve(__dirname, '/src'),
    },
  },
Copy the code

7. Production environment

Waiting for update ingCopy the code

8.babel plugin

I’m going to try plug-in solutions to some of the above problems

The results of

Almost now it can be used, there are some styles covered are small problems, check the basic functions are in, tomorrow we will focus on the decoration and JSX problems

Overall, there is no big difference in the use experience, the compilation speed is indeed much faster, but the default prompt for reload does not contain time, followed by xN to represent the number, only one sentence, and it is very fast, not very used

Initial compilation

That’s a lot faster than seven or eight seconds,

Browser connection time:

For the time being, well, it smells good. 0, 0, 0, 0, 0, 0