It started because the company had a core project that ran through almost all of its business. So even with another project, there’s a lot of business to iterate on. A project with nearly a thousand pages is such an old technology stack, and a multi-page project. Start speed can be imagined… I decided to move it to Vite because I couldn’t stand the efficiency of just getting the project started

Let me first tell you the efficiency changes after the successful migration:

Originally, the startup time of a single project was reduced from 265s to 56s. The hot update time was reduced from 38s to almost instantaneous. And the original multi-page development mode is realized by starting multiple HTTP-Servers, if you start two large projects at the same time, it will basically be stuck. This pattern is no longer needed in Vite. Because we can completely configure multiple entrances, and not afraid of the lag.

introduce

Based on the background of the project, I only reconstructed the development environment construction logic. That is to say, the production environment packaging is still webpack. The main reason for this is that the project is very large and the cost of refactoring the production environment logic is too high. Assuming you want a big upgrade overall, you’d better assess the risks.

Why vite?

  • The performance principle is not explained in detail, and there are many articles on the web that simply summarize as “load on demand “.

  • Out of the box, yes, you can build it without even looking at the documentation (which I did)

  • Ecologically, mainly because Vite will provide a first priority update to Vue’s technology stack, we will be ecologically well protected

  • Plugin development for Vite and Rollup is much friendlier, and you can write your own plugin to resolve problems that ecology can’t solve

Does it have to be Vite?

  • Of course not. LatelyWebAssemblyThe rise of this concept is actuallyWebpack5There are some qualitative leaps in performance as well, and I recommend that you learn about this concept. 😝

The migration process

If your project is big enough, I’m sure you’ll be scratching your head in the potholes along the way. However, when I saw the normal start of the project, I was full of sense of achievement.

Directly to the project:

$ yarn add vite -D
Copy the code

Then configure the vite.config.js file

import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'

export default defineConfig({
        plugins: [
            createVuePlugin({
                jsx: true.// JSX syntactically compatible processing, actually does not use... I'll talk about that later})]})Copy the code

Package. The json file

{
    "scripts": {
        "vite": "vite"}}Copy the code

Just run. Congratulations, you’ll get a lot of flips.

Error logging

I’ve only posted a few mistakes here, but I won’t post some that are easy to fix. There are plenty of solutions online

The index.js folder in the imported module cannot be resolved

Not only that title, but when I switch to Vite, there are three things I can’t recognize

case1: src/demo1/index.vue
case2: src/demo2/index.js
case3: src/demo3.vue
Copy the code
// ❌ in vite,👌 in webpack
import demo1 from 'src/demo1'
import demo2 from 'src/demo2'
import demo3 from 'src/demo3'
Copy the code

That is, vite will not find the index.js, index.vue folder and you omit the extension name. Vue in webpack by default, will not find the file. If you have a very small number of files, you can add them manually, but if you have too many files, it’s hard to solve

Here I’ve written a plugin of my own to address these situations. You can also use my plugin vite-plugin-path-resolve directly

// vite.config.js
import pathResolve from 'vite-plugin-path-resolve'
function getPath(dir) {
    return path.resolve(path.dirname(fileURLToPath(import.meta.url)), dir)
}

export default defineConfig({
    plugins: [
        pathResolve({ src: getPath('src')]}}))Copy the code

Vue2 uses JSX problems

The JSX syntax extension is not currently enabled

In the script module of the vue2 component, if you use JSX syntax, vite will not be able to tell. So far I have found the following solutions:

At present, the following solutions should be put wrong:

  • Vite configuration file with this plugin(useless for me)
vite.config.js => plugins: [createVuePlugin({ jsx: true })]
Copy the code
  • If it is injsFile withjsxSyntax, is changed to.jsxExtension file
.js(has jsx) => .jsx
Copy the code
  • If it is in.vueFile with JSX syntax, then inscriptAdd the label under the label
.vue(has jsx) => <script lang="jsx">
Copy the code

All of the above solutions work for me, but I have hundreds of files… It’s impossible to change them one by one. I personally searched the Internet for developed plug-ins, but they are not applicable to my project. I wrote my own script to actually help me tag.vue files with JSX syntax automatically. NPM search: vite-vue2-script-jsx


Element could not find its dependency module:async-validator

ERROR: [plugin: vite:dep-pre-bundle] Failed to resolve entry for package “async-validator”. The package may have incorrect main/module/exports specified in its package.json: Failed to resolve entry for package “async-validator”. The package may have incorrect main/module/exports specified in its package.json.

If you can’t find a reference module, you can use a path alias to solve the problem.

// vite.config.js
alias: [{find: 'async-validator'.replacement: 'node_modules/async-validator/dist-web/index.js'},].Copy the code

The problem of less

This problem is mainly due to somelessThe global module could not be found. invite.config.jsThe configuration:

css: {
        preprocessorOptions: {
            less: { additionalData: `@import "${getPath('src')}/assets/less/theme.less"; `}}},Copy the code

[vite] Internal server error: ‘~@/assets/less/global.less’ wasn’t found. Tried – /Users/xxxx/xx-project/boss-admin/src/project/system/~@/assets/less/global.less,node_modules/~@/assets/less/global.less, ~@/assets/less/global.less

This problem is simple, change ~@ to @ is ok


Commonjs import error

[vite] Internal server error: Failed to resolve import “vertx” from “node_modules/.vite/es6-promise.js? v=7253cf1d”. Does the file exist?

Error thrown when using plugins,

import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
Copy the code
  • By the way this plugin is used to solve the problem used in the codecommonJs, butviteThe problem of not supporting. This is easy to solve, I will not mention

Add a skipPreBuild to the plug-in configuration

plugins: [
    // This plugin is customized to solve the path problem
    viteCommonjs({ skipPreBuild: true}),].Copy the code

The worst mistake

[vite] Internal server error: CssSyntaxError: /Users/xxxx/xxxx-project/xxxx-admin/src/project/system/components/channel-select/index.vue? vue&type=style&index=0&rel=stylesheet%2Fless&lang.less:1:0: Unknown word

😭 this bug is my most bizarre, because his error is very weird, I debug source code, and even went to the official mentionissueI didn’t solve the problem until it turned out THAT I had delayedvite-plugin-vue2“Was implemented because it wanted to solve JSX syntax problems, and eventually abandoned that solution

plugins: [
    {
        enforce: 'pre'.// dont do that. createVuePlugin({jsx: true,})}],Copy the code

The globally registered UI component library is invalid

The ElementUI component library that was imported globally by the project is not registered in the component file. I used one of the big guys’ plugins to make ElementUI automatically import on demand

import OptimizationPersist from 'vite-plugin-optimize-persist'
import PkgConfig from 'vite-plugin-package-config'

Components({
  resolvers: [ElementUiResolver()],
  include: [/\.vue$/./\.vue\? vue/./\.md$/],}).Copy the code

Failed to load source map for /node_modules/.vite/vite.js

Since the project started, this warning has been put on, resulting in a lag. I haven’t figured out why, but I found a way to tell Vite which packages should be pre-loaded. You can use this plug-in here to solve this problem.

import OptimizationPersist from 'vite-plugin-optimize-persist'

plugins: [
    OptimizationPersist(),
],
Copy the code

Uncaught ReferenceError: parcelRequire is not defined

My solution is to go directly towindowObject to add aparcelRequireattribute

vite.config.js

Finally, I posted a complete configuration map for your reference

import path from 'path'
import { fileURLToPath } from 'url'
import { defineConfig } from 'vite'
import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
import { createVuePlugin } from 'vite-plugin-vue2'
import Inspect from 'vite-plugin-inspect'
import aliasDefualt from './vite-script/plugins/vite-plugin-alias-defualt.js'
import Components from 'unplugin-vue-components/vite'
import { ElementUiResolver } from 'unplugin-vue-components/resolvers'
import OptimizationPersist from 'vite-plugin-optimize-persist'
import PkgConfig from 'vite-plugin-package-config'
// Multi-page entry
import projects from './vite-script/options/project-input'
// Project proxy file
import proxies from './vite-script/options/proxy'

function getPath(dir) {
    return path.resolve(path.dirname(fileURLToPath(import.meta.url)), dir)
}

const projectPath = (projectName) = > getPath(`src/project/${projectName}`)

export default defineConfig({
    build: {
        rollupOptions: {
            input: projects,
        },
    },
    plugins: [
        // These two packages mainly solve the problem of relying on on-demand loading.
        PkgConfig(),
        OptimizationPersist(),
        // This plugin is customized to solve the path problem
        aliasDefualt({ src: getPath('src') }),
        createVuePlugin({
            jsx: true,}).// Automatic on-demand import of UI frames
        Components({
            resolvers: [ElementUiResolver()],
            include: [/\.vue$/./\.vue\? vue/./\.md$/],}).// common transform to ES6 Module
        viteCommonjs({ skipPreBuild: true }),
        Inspect(),
    ],
    resolve: {
        alias: [{find: The '@'.replacement: getPath('src')},/** The async-Validator module cannot be found inside element UI */
            { find: 'async-validator'.replacement: 'node_modules/async-validator/dist-web/index.js' },
            { find: 'v-viewer'.replacement: 'node_modules/v-viewer'},],},server: {
        open: '/index.html'.proxy: {
            ...proxies,
            '/web-socket': {
                target: 'https://dev.www.xxx.com.cn'.secure: false.changeOrigin: true.ws: true,}}},css: {
        preprocessorOptions: {
            less: { additionalData: `@import "${getPath('src')}/assets/less/theme.less"; `}},},define: {
        global: {},}})Copy the code

Thank 😘


If you find the content helpful:

  • ❤️ welcome to focus on praise oh! I will do my best to produce high-quality articles

Contact author: Linkcyd 😁 Previous:

  • Interviewer, I totally understand the difference between computed and Watch
  • React Get started with 6 brain maps
  • Interviewer: Come on, hand write a promise
  • Prototype and Prototype Chain: How to implement Call, Bind, New yourself
  • That’s all you need to know about regular expressions