background
Recently, we did a collection of pain points and optimizable items in the front-end development process. The words “build time” and “slow project compilation” appeared several times.
With the rapid development of our business, the volume of many of our projects has expanded rapidly. With that comes the problem of slow packing.
Improving research and development efficiency is the eternal pursuit of technologists.
Our project also has the problem of slow start, which has been mentioned several times by colleagues. I happened to have done similar exploration and optimization before, so I took this opportunity to transform the project and solve the problem of start-up time.
On yesterday afternoon (2021.4.7 23:00), Vite was successfully embedded, and the project startup time was shortened from about 190s => 20s, and the hot update time was shortened to 2s.
I stepped in a few holes in the middle, but I managed to climb out. The technical points are presented below.
FBI Warning: The following text is just a summary of my experience based on my actual project
Today’s main content:
Why does Vite start so fast
How does my project embed Vite
The problems I encountered during the renovation process
Vite development, packaging online some thinking
Relevant code and conclusions
The body of the
Why does Vite start so fast
The underlying implementation of Vite is based on esBuild pre-build dependencies.
Esbuild is written using GO and is 10-100 times faster than a wrapper written in JS to pre-build dependencies.
Because JS is so slow compared to Go, js usually operates in milliseconds and GO in nanoseconds.
There are also differences in how they start.
Webpack startup mode
Vite boot mode
Webpack packs, starts the development server, and gives the package results directly when the server is requested.
Vite directly starts the development server and asks which module to compile the module in real time.
Since modern browsers naturally support ES Modules, they automatically make requests to dependent modules.
Vite takes full advantage of this by treating module files in the development environment as files to be executed by the browser, rather than being packaged and merged like EBPack.
Since Vite doesn’t need to be packaged at startup, that means there’s no need to analyze module dependencies and compile. So it starts very fast. When a browser requests a module, the content is compiled as needed.
This dynamic compilation on demand greatly reduces the compilation time, and the more complex the project and the more modules, the more obvious the advantages of Vite.
In TERMS of HMR (hot update), when a module is changed, you only need to ask the browser to request the module again, unlike WebPack, which needs to compile all the relevant dependent modules of the module once, which is more efficient.
From a practical development experience, in Vite mode, the development environment can be launched instantaneously, but once the page comes out, it takes a while.
How does my project embed Vite
The new project
Creating a new Vite project is simple:
yarn create @vitejs/app
Copy the code
Once generated, you can start it directly:
Existing projects
The migration of existing projects is slightly more tedious.
First, add the Vite configuration. Here I used a CLI tool: wp2vite.
After installation, directly execute:
In this step, the Vite configuration file is automatically generated and related dependencies are introduced.
Install the dependency and start it up.
If nothing unexpected happens, you’ll get a bunch of errors.
Congratulations, you’re on your way to the fun pit.
The problems I encountered during the renovation process
1. The alias error
There are some aliases in the project code that vite cannot recognize, so we need to configure alias in vite as well:
resolve: {
alias: {
The '@': resolve(__dirname, 'src'),}},Copy the code
2. The less global variable cannot be recognized
Solutions:
To inject custom global variables from the outside, add the following to the CSS option of vite.config.js:
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import '${resolve('./src/vars.less')}'; `. themeVariables, },javascriptEnabled: true,}}},Copy the code
3. Uncaught Error: Target container is not a DOM element.
The root element was not found.
The reason for this is that in the index.html generated by default:
<div id="root"></div>
Copy the code
#app = root #app = root #app = root
4. The typings file cannot be found
The Typings file was not found.
This mistake, at first glance, is confusing.
Take a look at the source code and the compiled code:
The source code:
The compiled:
The typings file is here. Why can’t I find it?
Come to think of it: Vite doesn’t know that the Typeings file doesn’t need to be compiled and needs to tell the compiler not to compile it.
Finally, I found the answer in the official TS document:
www.typescriptlang.org/docs/handbo…
Type-Only Imports and Export
This feature is something most users may never have to think about; however, if you’ve hit issues under –isolatedModules, TypeScript’s transpileModule API, or Babel, this feature might be relevant.
TypeScript 3.8 adds a new syntax for type-only imports and exports.
import type { SomeThing } from "./some-module.js";
export type { SomeThing };
Copy the code
Types need to be introduced separately, so change the code to:
Also note that if a file has more than one export, it should be imported separately:
The only painful thing is: the whole situation needs to be changed again, physical work.
At this point, the Typeings problem is solved perfectly.
5. SVG cannot be recognized
When we use SVG as an icon component, we typically use:
import Icon from '@ant-design/icons';
import ErrorSvg from '@/assets/ico_error.svg';
const ErrorIcon = (props: any) = > <Icon component={ErrorSvg} />;
// ...
<ErrorIcon />
Copy the code
Browser error:
error occurred in the </src/assets/ico_error.svg> component
Copy the code
It is obvious that the file path is used as a component.
Now all you have to do is replace this file path with an identifiable component.
A bit of searching turned up a plugin: viet-plugin-react-svg
Add configuration:
const reactSvgPlugin = require('vite-plugin-react-svg');
plugins: [
reactSvgPlugin(),
],
Copy the code
import MyIcon from './svgs/my-icon.svg? component';
function App() {
return (
<div>
<MyIcon />
</div>
);
}
Copy the code
Note that imported SVG files need to add? Component as the suffix.
Looking at the source code, this suffix is used as an identifier,
If the suffix matches component, the file is parsed and cached, and the result is returned:
SVG =>.svg? Component.
Vscode can be replaced with one click, but be careful not to replace node_module.
6. Global is undefined
Global is a variable in Node.
Layer by layer, it turns out that an imported third-party package uses Global.
The vite documentation mentions Client Types:
Append to tsconfig:
"compilerOptions": {
"types": ["node"."jest"."vite/client"],}Copy the code
And then, there’s no messing around…
We had no choice but to use the Window method.
Add the following to the entry index. TSX:
(window as any).global = window;
Copy the code
Refresh. Okay.
7. [unresolved] Replace HtmlWebpackPlugin
You also need to inject some external variables, modify the entry HTML, favicon, title, etc.
Find a plugin: vite-plugin-singleFile
But it didn’t help.
Have understanding of the students please leave a message to give advice.
At this point, the entire app is running locally, and the build is fine.
7. Memory overflow during an online package build
Local can run, pack is no problem, behind of course is put on the line to run.
Arrange it immediately!
I’m running out of memory, so I’ll fill it up for you:
Done!
Vite development, packaging online some thinking
In practice, Vite doesn’t completely replace WebPack in some functions.
After all, it is an up-and-comer, and the relevant ecology still needs continuous improvement.
Personally, at present, a relatively safe way is:
- Retain webPack Dev & Build capability,
Vite is only used as a development aid
And then consider migrating completely.
Relevant code and conclusions
A full Vite demo
Warehouse address: github.com/beMySun/rea…
The complete configuration of viet.config.js for the business project
import { defineConfig } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
import legacyPlugin from '@vitejs/plugin-legacy';
import { resolve } from 'path';
const fs = require('fs');
const lessToJS = require('less-vars-to-js');
const themeVariables = lessToJS(fs.readFileSync(resolve(__dirname, './src/antd-custom.less'), 'utf8'));
const reactSvgPlugin = require('vite-plugin-react-svg');
// https://cn.vitejs.dev/config/
export default defineConfig({
base: '/'.root: '/'.resolve: {
alias: {
'react-native': 'react-native-web'.The '@': resolve(__dirname, 'src'),}},define: {
'process.env.REACT_APP_IS_LOCAL': '\'true\''.'window.__CID__': JSON.stringify(process.env.cid || 'id'),},server: {
port: 8080.proxy: {
'/api': {
target: 'https://stoku.test.shopee.co.id/'.changeOrigin: true.cookieDomainRewrite: {
'stoku.test.shopee.co.id': 'localhost',},},},},build: {
target: 'es2015'.minify: 'terser'.manifest: false.sourcemap: false.outDir: 'build'.rollupOptions: {},},esbuild: {},
optimizeDeps: {},
plugins: [
// viteSingleFile({
// title: 'dynamic title', // doesn't work
// }),
reactSvgPlugin(),
reactRefresh(),
legacyPlugin({
targets: [
'Android > 39'.'Chrome >= 60'.'Safari > = 10.1'.'the iOS > = 10.3'.'Firefox >= 54'.'Edge >= 15',]}),// vitePluginImp({
// libList: [
/ / {
// libName: 'antd',
// style: (name) => `antd/es/${name}/style`,
/ /},
/ /,
// }),].css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import '${resolve('./src/vars.less')}'; `. themeVariables, },javascriptEnabled: true,},},},});Copy the code
The last
Using Vite can significantly reduce project build time and improve development efficiency.
However, a reasonable choice should also be made based on the actual situation of the project.
For this project, I found Vite useful as a way to aid in development.
Look forward to Vite can continue to improve, improve efficiency for research and development.
Well, that’s about it. I hope it’s helpful.
If there are mistakes, welcome to correct.
thank you
Finally, if you think the content is helpful, you can pay attention to my public account (front-end skin small egg), master the latest developments, learn together!