background
Recently, a collection of pain points and optimizable items in the Among them,
time-consuming construction and slow project compilation have appeared several times.
With the rapid development of business, the volume of many of our projects has rapidly expanded. Then comes problems such as slow packaging.
Improving research and development efficiency is the eternal pursuit of technical people.
Our project also has the problem of slow start-up, which has been mentioned by my colleagues several times. I happened to have done similar exploration and optimization before, so I took this opportunity to transform the project, solve the problem of time-consuming startup.
Yesterday afternoon (2021.4.7 23:00), Vite was successfully embedded, the project start time was about 190s => 20s
, and the hot update time was shortened to 2s
.
I stepped on some pits in the middle, but fortunately, I climbed out at the end. The relevant technical points will be presented below.
FBI Warning: The following text is just some superficial experience that I have combined with my own actual projects. If there are errors, please correct me :)
Today’s main content:
Why does Vite start so fast
How to install Vite in my project
I encountered problems during the renovation process
Some thoughts on Vite development, packaging and launching
related codes and conclusions
text
Why does Vite start so fast
In terms of the underlying implementation, Vite is based on esbuild's pre-built dependencies.
esbuild is written in go, and is 10-100 times faster than the packager pre-built dependencies written in js.
Because js is too slow compared to go, the general operation of js is in milliseconds, and go is in nanoseconds.
In addition, the startup methods of the two are also different.
webpack startup method
Vite startup method
Webpack will first, then start the development server, and directly give the packaging result when requesting the server.
In Vite, directly starts the development server, and which module is requested to
real time.
Since modern browsers natively support ES Module, they will automatically send requests to dependent Modules.
Vite takes full advantage of this, and treats the module files in the development environment as the files to be executed by the browser, instead of the package and merge like Webpack.
does not need to be packaged when Vite is started, it means that
does not need to analyze module dependencies, and
does not need to be compiled.
Therefore, the startup speed is very fast. When the browser requests a module, it compiles the content of the module as needed.
This on-demand dynamic compilation method greatly reduces compilation time. 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, only the browser needs to request the module again. Unlike webpack, which requires all dependent modules of the module to be compiled once, it is more efficient.
From the actual development experience, in Vite mode, the development environment can be started instantly, but it will take a while to wait until the page comes out.
How to install Vite in my project
new project
Creating a new Vite project is relatively simple:
yarn create @vitejs/app
After it is generated, just start it directly:
Existing project
The migration of existing projects is slightly more cumbersome.
First, add the relevant configuration of Vite. Here I used a cli tool: wp2vite
.
After installation, directly execute:
In this step, the Vite configuration file will be automatically generated and related dependencies will be introduced.
Install the dependency and start it.
If there are no accidents, you will a bunch of errors with 16076b6216b0a6.
Congratulations, enter the happy and joyful stepping on the pit.
The problems I encountered during the renovation
1. alias error
There are some aliases configured in the project code, which cannot be recognized by vite, so aliases need to be configured in vite as well:
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
},
2. Unable to recognize less global variables
Solution:
vite.config.js
inject the custom global variables from the outside, and add them directly to the css option of 06076b6216b170:
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true;@import '${resolve('./src/vars.less')}';`,
...themeVariables,
},
javascriptEnabled: true,
},
},
},
3. Uncaught Error: Target container is not a DOM element.
The root element was not found.
The reason is: In the index.html generated by default:
<div id="root"></div>
id is root, and the logic is #app
, here it can be changed directly to id=app
.
4. The typings file cannot be found
typings file was not found.
This mistake, at first glance, was confusing.
Go in and take a look at the source code and compiled code:
Source code:
After compilation:
Isn't the typings file here? Why can't I find it?
Thought for a while: Vite doesn't know that the typings file does not need to be compiled, and needs to tell the compiler not to compile this file.
Finally found the answer in the official TS documentation:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html
Type-Only Imports and ExportThis 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 };
Need to introduce types separately, so change the code to:
At the same time, it should be noted that if a file has multiple exports, they must be imported separately:
The only painful thing is: the overall situation needs to be changed again, manual work.
So far, the typings problem is perfectly solved.
5. Unrecognized svg
When we use svg as an icon component, it is generally:
import Icon from '@ant-design/icons';
import ErrorSvg from '@/assets/ico_error.svg';
const ErrorIcon = (props: any) => <Icon component={ErrorSvg} />;
// ...
<ErrorIcon />
The browser reports an error:
error occurred in the </src/assets/ico_error.svg> component
Obviously, here is the file path as a component.
What we need to do now is: replace this file path with a recognizable component.
After searching, I found a plug-in: vite-plugin-react-svg
Join configuration:
const reactSvgPlugin = require('vite-plugin-react-svg');
plugins: [
reactSvgPlugin(),
],
import MyIcon from './svgs/my-icon.svg?component';
function App() {
return (
<div>
<MyIcon />
</div>
);
}
Note that: The imported svg file needs to be suffixed ?component
Looking at the source code, this suffix is used as an identifier,
If the suffix matches component
, the file is parsed, cached, and the result is returned:
After knowing the principle, you need to put all .svg
=> .svg?component
.
One-click replacement of vscode is fine, but be careful not to replace the node_module as well.
6. global is not defined
global
is a variable in Node. Will it report an error on the client?
Looking at it layer by layer, it turns out that the imported third-party package uses global.
Look at the Client Types mentioned in the vite documentation:
Append to tsconfig
:
"compilerOptions": {
"types": ["node", "jest", "vite/client"],
}
Then, there is no misuse. . .
There is no way, but to window
Dafa.
Add in the entry index.tsx:
(window as any).global = window;
Refresh, that's it.
7. [Unsolved] Replace HtmlWebpackPlugin
Also need to inject some external variables, modify the entry html, favicon, title and so on.
Found a plugin: vite-plugin-singlefile
But it is of no use.
Anyone who understands, please leave a message for advice.
At this point, the entire app can be run locally, and the build is no problem.
7. Memory overflow during online packaging and construction
It can run locally, and there is no problem with packing. Of course, I will put it on the line for a run.
Arrange now!
If the memory is insufficient, I will add something for you:
Get it done!
Some thoughts on Vite development, packaging and launching
From the actual use point of view, vite still cannot completely replace webpack in some functions.
After all, it is a rising star, and the related ecology needs to be continuously improved.
In my opinion, a relatively safe way at present is:
- Keep webpack dev & build capabilities,
vite is only used as a development aid
Wait for the related tools to be more perfect, and then consider the complete migration.
Related code and conclusion
A complete Vite demo
Warehouse address: https://github.com/beMySun/react-hooks-i18n-template/tree/test-wp2vite
Vite.config.js complete configuration of 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',
'@': 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',
'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,
},
},
},
});
At last
Using Vite can greatly shorten project construction time and improve development efficiency.
However, it is necessary to make reasonable choices based on the actual situation of the project.
For this project of mine, it is quite useful to use Vite as a way to assist in development.
It is expected that Vite will continue to improve and improve the efficiency of research and development.
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!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。