1- import { defineConfig , loadEnv , searchForWorkspaceRoot } from 'vite' ;
1+ import { defineConfig , loadEnv , searchForWorkspaceRoot , Plugin , ResolvedConfig } from 'vite' ;
22import react from '@vitejs/plugin-react-swc' ;
33import { PolyfillOptions , nodePolyfills } from 'vite-plugin-node-polyfills' ;
4- import bundlesize from 'vite-plugin-bundlesize' ;
4+ import fs from 'fs' ;
5+ import path from 'path' ;
56
67// Only required for alternative bb wasm file, left as reference
78//import { viteStaticCopy } from 'vite-plugin-static-copy';
@@ -21,6 +22,79 @@ const nodePolyfillsFix = (options?: PolyfillOptions | undefined): Plugin => {
2122 } ;
2223} ;
2324
25+ /**
26+ * Lightweight chunk size validator plugin
27+ * Checks chunk sizes after build completes and fails if limits are exceeded
28+ */
29+ interface ChunkSizeLimit {
30+ /** Pattern to match chunk file names (e.g., /assets\/index-.*\.js$/) */
31+ pattern : RegExp ;
32+ /** Maximum size in kilobytes */
33+ maxSizeKB : number ;
34+ /** Optional description for logging */
35+ description ?: string ;
36+ }
37+
38+ const chunkSizeValidator = ( limits : ChunkSizeLimit [ ] ) : Plugin => {
39+ let config : ResolvedConfig ;
40+
41+ return {
42+ name : 'chunk-size-validator' ,
43+ enforce : 'post' ,
44+ apply : 'build' ,
45+ configResolved ( resolvedConfig ) {
46+ config = resolvedConfig ;
47+ } ,
48+ closeBundle ( ) {
49+ const outDir = this . meta ?. watchMode ? null : 'dist' ;
50+ if ( ! outDir ) return ; // Skip in watch mode
51+
52+ const logger = config . logger ;
53+ const violations : string [ ] = [ ] ;
54+ const checkDir = ( dir : string , baseDir : string = '' ) => {
55+ const files = fs . readdirSync ( dir ) ;
56+
57+ for ( const file of files ) {
58+ const filePath = path . join ( dir , file ) ;
59+ const relativePath = path . join ( baseDir , file ) ;
60+ const stat = fs . statSync ( filePath ) ;
61+
62+ if ( stat . isDirectory ( ) ) {
63+ checkDir ( filePath , relativePath ) ;
64+ } else if ( stat . isFile ( ) ) {
65+ const sizeKB = stat . size / 1024 ;
66+
67+ for ( const limit of limits ) {
68+ if ( limit . pattern . test ( relativePath ) ) {
69+ const desc = limit . description ? ` (${ limit . description } )` : '' ;
70+ logger . info ( ` ${ relativePath } : ${ sizeKB . toFixed ( 2 ) } KB / ${ limit . maxSizeKB } KB${ desc } ` ) ;
71+
72+ if ( sizeKB > limit . maxSizeKB ) {
73+ violations . push (
74+ ` ❌ ${ relativePath } : ${ sizeKB . toFixed ( 2 ) } KB exceeds limit of ${ limit . maxSizeKB } KB${ desc } ` ,
75+ ) ;
76+ }
77+ }
78+ }
79+ }
80+ }
81+ } ;
82+
83+ logger . info ( '\n📦 Validating chunk sizes...' ) ;
84+ checkDir ( path . resolve ( process . cwd ( ) , outDir ) ) ;
85+
86+ if ( violations . length > 0 ) {
87+ logger . error ( '\n❌ Chunk size validation failed:\n' ) ;
88+ violations . forEach ( v => logger . error ( v ) ) ;
89+ logger . error ( '\n' ) ;
90+ throw new Error ( 'Build failed: chunk size limits exceeded' ) ;
91+ } else {
92+ logger . info ( '✅ All chunks within size limits\n' ) ;
93+ }
94+ } ,
95+ } ;
96+ } ;
97+
2498// https://vite.dev/config/
2599export default defineConfig ( ( { mode } ) => {
26100 const env = loadEnv ( mode , process . cwd ( ) , '' ) ;
@@ -47,7 +121,7 @@ export default defineConfig(({ mode }) => {
47121 } ,
48122 plugins : [
49123 react ( { jsxImportSource : '@emotion/react' } ) ,
50- nodePolyfillsFix ( { include : [ 'buffer' , 'path' ] } ) ,
124+ nodePolyfillsFix ( { include : [ 'buffer' , 'path' , 'process' , 'net' , 'tty' ] } ) ,
51125 // This is unnecessary unless BB_WASM_PATH is defined (default would be /assets/barretenberg.wasm.gz)
52126 // Left as an example of how to use a different bb wasm file than the default lazily loaded one
53127 // viteStaticCopy({
@@ -58,18 +132,21 @@ export default defineConfig(({ mode }) => {
58132 // },
59133 // ],
60134 // }),
61- bundlesize ( {
135+ chunkSizeValidator ( [
62136 // Bump log:
63137 // - AD: bumped from 1600 => 1680 as we now have a 20kb msgpack lib in bb.js and other logic got us 50kb higher, adding some wiggle room.
64138 // - MW: bumped from 1700 => 1750 after adding the noble curves pkg to foundation required for blob batching calculations.
65- limits : [
66- // Main entrypoint, hard limit
67- { name : 'assets/index-*' , limit : '1750kB' } ,
68- // This limit is to detect wheter our json artifacts or bb.js wasm get out of control. At the time
69- // of writing, all the .js files bundled in the app are below 4MB
70- { name : '**/*' , limit : '4000kB' } ,
71- ] ,
72- } ) ,
139+ {
140+ pattern : / a s s e t s \/ i n d e x - .* \. j s $ / ,
141+ maxSizeKB : 1750 ,
142+ description : 'Main entrypoint, hard limit' ,
143+ } ,
144+ {
145+ pattern : / .* / ,
146+ maxSizeKB : 4000 ,
147+ description : 'Detect if json artifacts or bb.js wasm get out of control' ,
148+ } ,
149+ ] ) ,
73150 ] ,
74151 define : {
75152 'process.env' : JSON . stringify ( {
@@ -81,9 +158,5 @@ export default defineConfig(({ mode }) => {
81158 BB_WASM_PATH : env . BB_WASM_PATH ,
82159 } ) ,
83160 } ,
84- build : {
85- // Required by vite-plugin-bundle-size
86- sourcemap : 'hidden' ,
87- } ,
88161 } ;
89162} ) ;
0 commit comments