-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathvite.config.ts
More file actions
154 lines (140 loc) · 5.11 KB
/
vite.config.ts
File metadata and controls
154 lines (140 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { defineConfig, loadEnv, Plugin, ResolvedConfig, searchForWorkspaceRoot } from 'vite';
import react from '@vitejs/plugin-react-swc';
import { PolyfillOptions, nodePolyfills } from 'vite-plugin-node-polyfills';
import fs from 'fs';
import path from 'path';
// Unfortunate, but needed due to https://github.com/davidmyersdev/vite-plugin-node-polyfills/issues/81
// Suspected to be because of the yarn workspace setup, but not sure
const nodePolyfillsFix = (options?: PolyfillOptions | undefined): Plugin => {
return {
...nodePolyfills(options),
/* @ts-ignore */
resolveId(source: string) {
const m = /^vite-plugin-node-polyfills\/shims\/(buffer|global|process)$/.exec(source);
if (m) {
return `./node_modules/vite-plugin-node-polyfills/shims/${m[1]}/dist/index.cjs`;
}
},
};
};
/**
* Lightweight chunk size validator plugin
* Checks chunk sizes after build completes and fails if limits are exceeded
*/
interface ChunkSizeLimit {
/** Pattern to match chunk file names (e.g., /assets\/index-.*\.js$/) */
pattern: RegExp;
/** Maximum size in kilobytes */
maxSizeKB: number;
/** Optional description for logging */
description?: string;
}
const chunkSizeValidator = (limits: ChunkSizeLimit[]): Plugin => {
let config: ResolvedConfig;
return {
name: 'chunk-size-validator',
enforce: 'post',
apply: 'build',
configResolved(resolvedConfig) {
config = resolvedConfig;
},
closeBundle() {
const outDir = this.meta?.watchMode ? null : 'dist';
if (!outDir) return; // Skip in watch mode
const logger = config.logger;
const violations: string[] = [];
const checkDir = (dir: string, baseDir: string = '') => {
const files = fs.readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const relativePath = path.join(baseDir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
checkDir(filePath, relativePath);
} else if (stat.isFile()) {
const sizeKB = stat.size / 1024;
for (const limit of limits) {
if (limit.pattern.test(relativePath)) {
const desc = limit.description ? ` (${limit.description})` : '';
logger.info(` ${relativePath}: ${sizeKB.toFixed(2)} KB / ${limit.maxSizeKB} KB${desc}`);
if (sizeKB > limit.maxSizeKB) {
violations.push(
` ❌ ${relativePath}: ${sizeKB.toFixed(2)} KB exceeds limit of ${limit.maxSizeKB} KB${desc}`,
);
}
}
}
}
}
};
logger.info('\n📦 Validating chunk sizes...');
checkDir(path.resolve(process.cwd(), outDir));
if (violations.length > 0) {
logger.error('\n❌ Chunk size validation failed:\n');
violations.forEach(v => logger.error(v));
logger.error('\n');
throw new Error('Build failed: chunk size limits exceeded');
} else {
logger.info('✅ All chunks within size limits\n');
}
},
};
};
// https://vite.dev/config/
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '');
// Profiling (zone.js-based async context tracking) runs only in dev.
// V8's "fast await" optimization bypasses user-space Promise.prototype.then
// for native `async function` bodies, breaking zone.js propagation. By
// lowering the esbuild/SWC target to es2016 in dev, we force async/await
// to be transpiled to Promise-based state machines that DO go through
// user-level .then() — which zone.js can hook. Prod keeps esnext for speed.
const isDev = command === 'serve';
const esTarget = isDev ? 'es2016' : 'esnext';
return {
base: './',
logLevel: process.env.CI ? 'error' : undefined,
esbuild: { target: esTarget },
build: { target: esTarget },
server: {
// Headers needed for bb WASM to work in multithreaded mode
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
fs: {
allow: [searchForWorkspaceRoot(process.cwd())],
},
},
optimizeDeps: {
exclude: ['@aztec/noir-acvm_js', '@aztec/noir-noirc_abi', '@aztec/bb.js'],
include: ['@gregojuice/embedded-wallet/ui'],
esbuildOptions: { target: esTarget },
},
plugins: [
react({
jsxImportSource: '@emotion/react',
// Match esbuild target in dev so async/await gets transpiled for zone.js.
...(isDev ? { devTarget: 'es2016' as const } : {}),
}),
nodePolyfillsFix({ include: ['buffer', 'path'] }),
chunkSizeValidator([
{
pattern: /assets\/index-.*\.js$/,
maxSizeKB: 1700,
description: 'Main entrypoint, hard limit',
},
{
pattern: /.*/,
maxSizeKB: 8000,
description: 'Detect if json artifacts or bb.js wasm get out of control',
},
]),
],
define: {
'process.env': JSON.stringify({
LOG_LEVEL: env.LOG_LEVEL,
}),
},
};
});