10

image.png

background

I recently migrated Vue2 projects from vue-cli(webpack) vite .

After doing this for the third time, I made some detailed records of the migration process and will summarize it in this article.

Article directory:

  • package.json
  • index.html
  • vite.config.js
  • test case
  • Lint
  • Published by
  • Visualization Bundle
  • some indicators
  • Conclusion

text

package.json

devDependencies

Remove @vue/cli-service dependency and replace with vite 🚀

Add vite dev dependency, v2.1.3 at the time of writing.png

npm un @vue/cli-service
npm i vite -D

You can also delete any other @vue/cli-plugin-xxx , because they will no longer work, for example:

image.png

npm un vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-unit-jest

If you are using Vue2 , we have to add vite-plugin-vue2 , this will be used in vite.config.js :

image.png

npm i vite-plugin-vue2 -D

In addition, if you are using git hooks , you may need to explicitly install yorkie to make everything work as before.

image.png

npm i yorkie -D

scripts

We will replace the vue-cli script with the corresponding script in vite for serve:

image.png

Of course, you can also keep serve.

Other scripts, such as build, jest, lint , will be discussed later.

index.html

Go ahead and move public/index.html to the root directory of the project. 1️⃣

We will also add the entry points required by vite:

<script type="module" src="/src/main.js"></script> 2️⃣

Finally, we will use our alternative path icon <%= BASE_URL %> favicon.ico (vite will find this icon for you in your public folder). 3️⃣

image.png

vite.config.js

We need to convert the previous version vue.config.js to the new version vite.config.js .

Let's start with the following lines:

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
export default defineConfig({
  plugins: [
    createVuePlugin(),
  ],
})

When migrating, keep the development as transparent as possible. Some configurations should be consistent with the previous ones, such as ports:

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
export default defineConfig({
  [...],
  server: {
    port: 8080,
  }
})

You will find all possible configuration options here: https://vitejs.dev/config/#config-file

'@' alias

If you used an alias to import the file in webpack, you now need to recreate it:

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
export default defineConfig({
  [...],
  resolve: {
    alias: [
      {
        find: '@',
        replacement: path.resolve(__dirname, 'src')
      }
    ]
  },
})

".vue" import path

Using webpack, you can ignore the .vue file suffix, but it does not work in vite, you need to bring it.

// From
import DotsLoader from '@/components/DotsLoader'

// to
import DotsLoader from '@/components/DotsLoader.vue'

Simplified routing delay loading

In the Route statement, you can safely delete any comments that webpackChunkName may have, such as this line:

{
  path: '/links',
  name: 'linksPage',
  component: () => import(/* webpackChunkName: "links" */ './views/LinksPage.vue'),
},

Simplified to:

{
  path: '/links',
  name: 'linksPage',
  component: () => import'./views/LinksPage.vue'),
},

I am not an expert here, but if you really want to customize the name of the block, you can do so by covering the summary output.entryFileNames .

See also vite build.rollupOptions to learn how to pass certain options directly to rollup.

Environment variable

Vite does not recognize process.env , instead: import.meta.env.

for example:

image.png

image.png

It should be noted that to ensure NODE_ENV=production , you need to set it in the .env file or production environment variables.

See official document: https://vitejs.dev/guide/env-and-mode.html#env-variables-and-modes

As for custom environment variables, we no longer need to prefix them with VUE_APP as before, but now we need to use VITE .

Any VITE_xxx needs to be provided in the code.

image.png

For example, a variable in the .env.local

VITE_APP_BACKEND_URL=http://localhost:3001

Test case

Now we can no longer use vue-cli-service test:unit , let's reconfigure.

First, you can update the test script:

image.png

If your babel.config.js file contains similar content:

presets: ['@vue/cli-plugin-babel/preset'],

Need to be replaced with:

presets: ['@babel/preset-env']

I also have an error with the import.meta.env statement.

Unfortunately, there is currently no ready-made setup for unit testing, but this comment helped me:

https://github.com/vitejs/vite/issues/1149#issuecomment-775033930

My babel.config.js file now looks like:

module.exports = {
  presets: ['@babel/preset-env'],
  // For Jest not to be annoyed by 'import.meta.xxx'
  plugins: [
    function () {
      return {
        visitor: {
          MetaProperty(path) {
            path.replaceWithSourceString('process')
          },
        },
      }
    },
  ],
}

Or, you can use this Babel plug-in, which can also solve the problem of import.meta in the test:
https://github.com/javiertury/babel-plugin-transform-import-meta

Here, you can follow some discussions about vite and Jest:
https://github.com/vitejs/vite/issues/1955

“regeneratorRuntime” error

  49 | export const actions = {
> 50 |   init: async ({ commit }, routeContext) => {
ReferenceError: regeneratorRuntime is not defined

regenerator-runtime is installed and referenced in my setupTests.js , it seems to have solved the problem.

npm i regenerator-runtime -D

'jest.config.js':

module.exports = {
  moduleFileExtensions: [
    'js',
    'json',
    // tells Jest to handle `*.vue` files
    'vue',
  ],
  transform: {
    // process `*.vue` files with `vue-jest`
    '.*\\.(vue)$': 'vue-jest',
    // process `*.js` files with `babel-jest`
    '.*\\.(js)$': 'babel-jest',
  },
  setupFiles: ['./setupTests'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  collectCoverage: false,
};

Then the first line of my "setupTests.js":

import 'regenerator-runtime/runtime';

Lint

You only need to replace two lint-related scripts:

lint.png

release

In this example, my application is provided by S3/CloudFront.

I have two production environments: preprod and prod.

So, I have two .env files:

  1. .env.preprod
  2. .env.prod

When building with rollup, vite will replace our environment variable with its value according to the mode used when calling the build script.

This is very similar to vue-cli, so updating our package.json script is very straightforward:

image.png

For more detailed information on this, please elaborate here:
https://vitejs.dev/guide/env-and-mode.html#modes

Tips must also cover the size of the largest package in "vite.config.js":

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
export default defineConfig({
  [...],
  build: {
    chunkSizeWarningLimit: 700, // Default is 500
  },
})

Visualization Bundle

"build:report": "vue-cli-service build --report",

I use rollup-plugin-visualizer to complete this function.

Import this plugin and reference it vite.config.js

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import visualizer from 'rollup-plugin-visualizer'
export default defineConfig({
  plugins: [
    createVuePlugin(),
    visualizer(),
  ],
  [...],
})

When opening the newly generated stats.html file, this is my result:

visualizer.png

This is similar to our commonly used webpack-bundle-analyzer

image.png

Some indicators

Start Time

  • Start with vite: ~ 4 seconds (even if the project continues to grow, it should remain the same 🙌)
  • Start with vue-cli/webpack: about 30 seconds (as we add more files to the project, it will continue to increase 😢)

Hot update

vite:

Simple changes (HTML tags, CSS classes...): take effect immediately.

Complex changes (renaming JS functions, adding components...): Not sure, sometimes I prefer to refresh myself.

vue-cli/webpack:

Simple change: ~4sec😕

More complicated changes: I never wait, but manually refresh the page.

First page request

When vite started, a complex page with many components is requested for the first time. Let's take a look at the network tag in Chrome DevTools:

  • vite: ~1430 JS file request, completed in ~ 11 seconds😟
  • vue-cli/webpack: about 23 JS file requests, completed in about 6 seconds👍

request pool.png

In this respect, some optimization plans can be adopted, such as lazy loading of components.

in conclusion

In general, so far, the development experience using vite is very good, 🌟 🌟 🌟 🌟 🌟

For projects that still use webpack, the situation may become more and more difficult.

Okay, that's all there is to it, I hope it will be helpful to everyone.

Ability to learn, if there are any mistakes, please correct me.

Thank you.

Finally, if you find the content helpful, you can follow my official account, keep up with the latest developments, and learn together!

image.png


皮小蛋
8k 声望12.8k 粉丝

积跬步,至千里。