Skip to content

Commit 3626773

Browse files
committed
generate env json
1 parent e09491a commit 3626773

1 file changed

Lines changed: 90 additions & 25 deletions

File tree

lib/cmd/vite/scripts.js

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,36 @@ function baseViteConfig(viteCfg) {
448448

449449
// ── Build passes ────────────────────────────────────────────────────────────
450450

451+
/**
452+
* Return the output.manualChunks / output.experimentalMinChunkSize entry for
453+
* rollupOptions.output based on whether the codebase is fully ESM.
454+
*
455+
* CJS mode (clientFilesESM:false): @rollup/plugin-commonjs injects \0-prefixed
456+
* virtual proxy modules into the graph which inflate apparent module sizes and
457+
* add phantom importer edges. Rollup's native experimentalMinChunkSize would
458+
* produce inaccurate merges in this environment. viteManualChunksPlugin guards
459+
* against virtual modules explicitly and uses info.code.length as an honest size
460+
* proxy for pre-minification CJS source.
461+
*
462+
* ESM mode (clientFilesESM:true): the graph is clean — no proxy modules, no CJS
463+
* wrapper boilerplate. Rollup's native experimentalMinChunkSize is accurate and
464+
* optimal; viteManualChunksPlugin is no longer needed. manualChunksMinSize maps
465+
* directly to the native threshold (0 = no merging if the site leaves it unset).
466+
*
467+
* @param {object} viteCfg
468+
* @returns {object}
469+
*/
470+
function buildChunkingOutput(viteCfg) {
471+
const minSize = viteCfg.manualChunksMinSize ?? 0;
472+
473+
if (viteCfg.clientFilesESM) {
474+
return { experimentalMinChunkSize: minSize };
475+
}
476+
477+
return { manualChunks: viteManualChunksPlugin(minSize, CWD) };
478+
}
479+
480+
451481
/**
452482
* Pass 1 — view mode (splitting pass).
453483
*
@@ -492,21 +522,8 @@ async function runViewBuild(viteCfg) {
492522
format: 'esm',
493523
entryFileNames: '[name]-[hash].js',
494524
chunkFileNames: 'chunks/[name]-[hash].js',
495-
// CJS mode (clientFilesESM:false): @rollup/plugin-commonjs injects \0-prefixed
496-
// virtual proxy modules into the graph which inflate apparent module sizes and
497-
// add phantom importer edges. Rollup's native experimentalMinChunkSize would
498-
// produce inaccurate merges in this environment. viteManualChunksPlugin guards
499-
// against virtual modules explicitly and uses info.code.length as a honest size
500-
// proxy for pre-minification CJS source.
501-
//
502-
// ESM mode (clientFilesESM:true): the graph is clean — no proxy modules, no CJS
503-
// wrapper boilerplate. Rollup's native experimentalMinChunkSize is accurate and
504-
// optimal; viteManualChunksPlugin is no longer needed. manualChunksMinSize maps
505-
// directly to the native threshold (0 = no merging if the site leaves it unset).
506-
...(viteCfg.clientFilesESM
507-
? { experimentalMinChunkSize: viteCfg.manualChunksMinSize ?? 0 }
508-
: { manualChunks: viteManualChunksPlugin(viteCfg.manualChunksMinSize ?? 0, CWD) }
509-
),
525+
// See buildChunkingOutput() for CJS vs ESM branching rationale.
526+
...buildChunkingOutput(viteCfg),
510527
},
511528
onwarn: suppressWarning,
512529
};
@@ -650,6 +667,56 @@ async function buildJS(options = {}) {
650667

651668
exports.buildJS = buildJS;
652669

670+
// ── Client env ──────────────────────────────────────────────────────────────
671+
672+
/**
673+
* Scan source JS/Vue files for `process.env.VAR_NAME` references and write
674+
* `client-env.json` — an array of unique env var names.
675+
*
676+
* amphora-html's `addEnvVars()` call in renderers.js reads this file at server
677+
* startup to know which `process.env` values need to be forwarded to the
678+
* browser. Without it the server never exposes those values and client-side
679+
* code that reads `process.env.FOO` gets undefined at runtime.
680+
*
681+
* @returns {Promise<string[]>} sorted list of env var names written
682+
*/
683+
async function generateClientEnv() {
684+
const SOURCE_GLOBS = [
685+
path.join(CWD, 'components', '**', '*.js'),
686+
path.join(CWD, 'layouts', '**', '*.js'),
687+
path.join(CWD, 'services', '**', '*.js'),
688+
path.join(CWD, 'global', '**', '*.js'),
689+
path.join(CWD, 'amphora', '**', '*.js'),
690+
path.join(CWD, 'app.js'),
691+
path.join(CWD, 'components', '**', '*.vue'),
692+
path.join(CWD, 'layouts', '**', '*.vue'),
693+
];
694+
695+
const files = globSync(SOURCE_GLOBS, { nodir: true });
696+
const found = new Set();
697+
const ENV_VAR_RE = /process\.env\.([A-Z_][A-Z0-9_]*)/g;
698+
699+
for (const file of files) {
700+
let src;
701+
702+
try {
703+
src = await fs.readFile(file, 'utf8');
704+
} catch (e) {
705+
continue;
706+
}
707+
708+
for (const match of src.matchAll(ENV_VAR_RE)) {
709+
found.add(match[1]);
710+
}
711+
}
712+
713+
const vars = [...found].sort();
714+
715+
await fs.outputJson(path.join(CWD, 'client-env.json'), vars, { spaces: 2 });
716+
717+
return vars;
718+
}
719+
653720
// ── Full build (JS + assets in parallel) ────────────────────────────────────
654721

655722
/**
@@ -742,11 +809,12 @@ async function buildAll(options = {}) {
742809
}
743810

744811
await Promise.all([
745-
step('js', () => buildJS(options)),
746-
step('styles', () => buildStyles(options)),
747-
step('fonts', () => buildFonts()),
748-
step('templates', () => buildTemplates(options)),
749-
step('vendor', () => copyVendor()),
812+
step('js', () => buildJS(options)),
813+
step('styles', () => buildStyles(options)),
814+
step('fonts', () => buildFonts()),
815+
step('templates', () => buildTemplates(options)),
816+
step('vendor', () => copyVendor()),
817+
step('client-env', () => generateClientEnv()),
750818
]);
751819

752820
if (timer) { clearInterval(timer); timer = null; }
@@ -852,11 +920,8 @@ async function watch(options = {}) {
852920
format: 'esm',
853921
entryFileNames: '[name]-[hash].js',
854922
chunkFileNames: 'chunks/[name]-[hash].js',
855-
// Same CJS/ESM branching as runViewBuild — see that function for full rationale.
856-
...(viteCfg.clientFilesESM
857-
? { experimentalMinChunkSize: viteCfg.manualChunksMinSize ?? 0 }
858-
: { manualChunks: viteManualChunksPlugin(viteCfg.manualChunksMinSize ?? 0, CWD) }
859-
),
923+
// See buildChunkingOutput() for CJS vs ESM branching rationale.
924+
...buildChunkingOutput(viteCfg),
860925
},
861926
onwarn: suppressWarning,
862927
watch: {

0 commit comments

Comments
 (0)