Skip to content

Commit c7d528f

Browse files
committed
docs: Vite 疑难杂症
1 parent 44cb8f5 commit c7d528f

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

src/_posts/vite/qa.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: Vite 疑难杂症
3+
date: 2025-04-15 10:52:55
4+
category:
5+
tags:
6+
cover:
7+
---
8+
9+
在 2022 年初投产了第一个 Vite 应用到产线,陆续处理的问题 Case,挑选一些记录下来。
10+
11+
## 应用中需要支持 `require` 语法
12+
13+
应用代码中,通常不再建议使用 `require`,应当都替换为 `import`.
14+
15+
但是,若为迁移旧代码或其它原因,社区有多款插件可以选用。
16+
17+
简单的场景推荐:https://github.com/wangzongming/vite-plugin-require
18+
19+
如果是三方依赖包的产物中包含了 `require()` 代码呢?
20+
21+
这种场景更加复杂一些,在 esbuild 预构建时可能遇到模块导出的值不符合预期,在调研对比多个社区方案后,推荐考虑使用以下插件:
22+
23+
https://github.com/vite-plugin/vite-plugin-commonjs
24+
25+
## lib 模式编译,如何引入 polyfill?
26+
27+
在打包 App 应用时可以依靠 [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) 处理 Polyfill,而 lib 模式编译类库时,不会引入 Polyfill。
28+
29+
推荐使用 Rollup 插件,通过 Babel 在最后阶段再处理 Polyfill。
30+
31+
```typescript
32+
import { defineConfig } from 'vite';
33+
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
34+
35+
export default defineConfig({
36+
build: {
37+
rollupOptions: {
38+
plugins: [
39+
/**
40+
* Running Babel on the generated code:
41+
* https://github.com/rollup/plugins/blob/master/packages/babel/README.md#running-babel-on-the-generated-code
42+
*
43+
* Transforming ES6+ syntax to ES5 is not supported yet, there are two ways to do:
44+
* https://github.com/evanw/esbuild/issues/1010#issuecomment-803865232
45+
* We choose to run Babel on the output files after esbuild.
46+
*
47+
* @vitejs/plugin-legacy does not support library mode:
48+
* https://github.com/vitejs/vite/issues/1639
49+
*/
50+
getBabelOutputPlugin({
51+
allowAllFormats: true,
52+
presets: [
53+
[
54+
'@babel/preset-env',
55+
{
56+
useBuiltIns: false,
57+
exclude: ['transform-typeof-symbol'],
58+
modules: false,
59+
},
60+
],
61+
],
62+
plugins: [
63+
[
64+
'@babel/plugin-transform-runtime',
65+
{
66+
corejs: false,
67+
// version: require('@babel/runtime').version,
68+
},
69+
],
70+
].filter(Boolean),
71+
}),
72+
],
73+
},
74+
},
75+
});
76+
```
77+
78+
## Vite lib 模式打包时,静态资源会被内联([官方解释](https://cn.vite.dev/config/build-options.html#build-assetsinlinelimit)),如何处理?
79+
80+
当我们使用 Vite 编译组件、类库时,此问题暴露尤其明显。例如组件中使用的某几张图片,留待使用该组件的应用打包应属最佳,否则,大量的图片被内联在 js 代码中,会严重影响加载速度。
81+
82+
在我们的场景下此问题十分重要,社区内没有可使用的方案,layne 同学编写了以下插件完美解决问题。
83+
84+
https://github.com/laynezh/vite-plugin-lib-assets
85+
86+
- `iife` 资源路径转拼接指定的 `publicUrl`
87+
- `esm` 转换为相对路径引入
88+
- `commonjs` 转换为相对路径引入
89+
90+
```typescript
91+
import { defineConfig } from 'vite';
92+
import assetsPlugin from '@laynezh/vite-plugin-lib-assets';
93+
94+
export default defineConfig({
95+
plugins: [
96+
assetsPlugin({
97+
name: '[name].[contenthash:8].[ext]',
98+
limit: 1024 * 8,
99+
publicUrl: undefined,
100+
}),
101+
],
102+
});
103+
```
104+
105+
## commonjs 模块中引用的资源应原样输出
106+
107+
```typescript
108+
import { defineConfig } from 'vite';
109+
110+
export default defineConfig({
111+
build: {
112+
commonjsOptions: {
113+
/**
114+
* https://github.com/rollup/plugins/tree/master/packages/commonjs#requirereturnsdefault
115+
*
116+
* require('./images/123.png') => import Img123 from './images/123.png'
117+
*
118+
* and './images/123.png' 会被 vite 处理成 base64 格式实现载入
119+
*/
120+
requireReturnsDefault(id) {
121+
const [pureId] = id.split('?', 2);
122+
return commonjsAssetsFilter(pureId);
123+
},
124+
},
125+
},
126+
});
127+
```
128+
129+
## 修改 lib 模式输出的样式文件名
130+
131+
不同于修改 js 文件输出的名称,样式文件需要不一样的处理方式。
132+
133+
```typescript
134+
import defineConfig from 'vite';
135+
136+
export default defineConfig({
137+
build: {
138+
rollupOptions: {
139+
output: {
140+
assetFileNames(assetInfo) {
141+
// https://github.com/vitejs/vite/issues/4863
142+
if (!ignoreStyles && assetInfo.name === 'style.css') {
143+
return `${fileName}.css`;
144+
}
145+
return assetInfo.name;
146+
},
147+
},
148+
},
149+
},
150+
});
151+
```

0 commit comments

Comments
 (0)