background

We have a project built with UMI and have been iteratively adding functions. More and more third-party libraries have been introduced into the project, and the local development webpack is becoming slower and slower to start dev-Server. Take the 14-inch Macbook Pro I use for example, it takes about one minute with M1 Pro chip, and about 3 seconds for hot update. The machine used by other front-end partners takes 3 minutes to start, and hot update takes more than 10 seconds, which greatly affects the development experience and efficiency. At present, besides WebPack, there are esBuild and SWC construction tools, and currently EsBuild-based Vite is a very good choice, so I have the power to migrate Vite

vite VS webpack

I’m sure you’ve all heard about Vite since 2022, but I won’t go over the pros and cons of Vite and WebPack:

vite Webpack
Start the development server Use the browser’s native ESM to load the source code module, start processing a dependency pre-build, second start seconds open, visit the browser native parsing dependency Recursive dependency analysis, conversion code, compilation, packaging output mainstream browsers can directly execute JS files, browser access directly render
Build packer Written using Go based on ESBuild, it builds 10-100 times faster than NodeJS Webpack is written in javascript and runs in a NodeJS environment, which is inefficient
Hot update Update the modified ESM module accurately Files need to be rebuilt after modification, which takes longer as the size of the application increases
ecological The Vite ecosystem is barely functional, and some features may need to be compromised or implemented yourself Loader and Plugin ecology rich, complete solutions
The production environment Esbuild itself has some limitations, so the production environment uses rollup Relying on rich ecology, stable and reliable

Vite is like apple just out of the M1 chip that kind of new generation of feeling, the first feeling is fast, after the use is really sweet, but ecology is a small regret, the future can be expected.

Summarize the advantages and disadvantages:

Vite has an absolute advantage in starting development server and hot update. However, rollup has no obvious advantage compared with Webpack in the scenario of ecological and production environment construction. Rollup is more suitable for project packaging of class library, so I still choose Webpack for production environment construction and ecological consideration

So from the comparison, both vite and Webpack’s strengths perfectly satisfy each other’s weaknesses. Is this the destined partner? Then why not learn from each other’s strengths and combine their strengths

vite + webpack

We only need to use Vite in the development environment and WebPack in the production environment to complement each other, which can improve the development efficiency and ensure stable production. It is worth noting that the two sets of construction tools should be executed normally in the same set of code.

Vite has special requirements for file structure (modular style file name must have. Module), and the configuration form is very different from webPack, so you need an Adapter, and only use one configuration form to implement the normal execution of two sets of build tools.

This adapter, is from ali Feibing team ice.js’, ice.js from 2.0 at the same time support Webpack@5 and Vite@2 two modes, only a set of specific configuration form, as long as through the environment variables can achieve the development environment with Vite, production environment with Webpack.

Implement Vite + Webpack

We can quickly initialize an ice.js project:

$ npm init ice <projectName>
# or
$ yarn create ice <projectName>
Copy the code

Select the template you want according to the interactive prompts. After creating the template, you can enter the project to install the dependency boot:

$ cd <projectName>
# install dependencies
$ npm install
# Start a project
$ npm start
Copy the code

After executing the preceding command, a browser window opens automatically to visit http://localhost:3333, and you should see the default page.

Then configure the startup command in package.json to distinguish the development environment using Vite mode, production environment using Webpack mode:

 "scripts": {
    "start": "icejs start --mode vite"."build": "icejs build --mode webpack". },Copy the code

Personalized customization

Due to ice. Js built a lot of stereotypes about ability of a third party (routing, state management, request library, permissions, encapsulation of entry, etc.), and I have migrated from the old project is not compatible with writing, so I want to give up the built-in functions, not stereotypes about file structure, write their own entry, access route, its motion library, state management, and other functions, Ice.js also supports this, and you need to turn these functions off in the ICE configuration:

Store: false, // Disable the built-in status management auth: false, // disable the built-in permission control Request: false, // disable the built-in Request disableRuntime: false, // disable all runtime capabilitiesCopy the code

Lipten/ICE-Vitepack-project: SRC /app. TSX entry code: SRC /app. TSX entry code Icejs2.0 + ANTD + DVA.js Initial project for custom Entry and project configuration (github.com)

Q&A

Third-party libraries are not compatible with esModules:

Vite can only load ESModule files. For other module files, special processing is required. By default, vite’s dependency prebuild will automatically handle compatible writing by looking for package.json dependencies. Add the local library using yarn add./ SRC/XXX

This will automatically have the following dependencies in package.json

"xxx": "./src/libs/xxx",
Copy the code

Replace the require statement with Import XXX from ‘XXX’

Some static resources may use the require statement and need to be written in ESM

Dynamic path load file address

When vite requires require(@/assets/images/${imgPath}) dynamic path loading, replace it with the following:

// Only relative paths are supported
new URL(`.. /.. /.. /src/${path}`.import.meta.url).href
Copy the code

Can do a compatible Webpack processing

export const importAssetsPath = (path: string) = > {
  return window.IS_VITE ? new URL(`.. /.. /.. /src/assets/${path}`.import.meta.url).href : require(`.. /assets/${path}`);
};

Copy the code

Dynamically loading modules import().then()

Vite does not support dynamic loading of modules import(‘ XXXX ‘).then()

/* @vite-ignore */ import(‘ XXXX ‘).then()

Error @ant-design/compatible was introduced

Because @ant-Design /compatible relies on draft-js to use the global variable, browsers will get an error, just assign global to the entry js

window.global = window
Copy the code

Require () must have SRC/XXX as a static path when using dynamic paths

Webpack may need to identify SRC and paths as static string directories when analyzing require paths

The following code does not parse properly:

const path = 'assets/images/xxx.png'
require(` @ /${path}`)
require(`.. /${path}`)
require(`~/src/${path}`)
Copy the code

The path should be written as follows:

const path = 'images/xxx.png'
require(`@/assets/${path}`)
require(`.. /assets/${path}`)
require(`~/src/assets/${path}`)
Copy the code