Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/cmd/vite/generate-bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const fs = require('fs-extra');
const path = require('path');
const { globSync } = require('glob');
const { getConfigValue } = require('../../config-file-helpers');
const { generateViteEnvInit } = require('./generate-env-init');

const CWD = process.cwd();
const CLAY_DIR = path.join(CWD, '.clay');
Expand Down Expand Up @@ -106,6 +107,8 @@ mountComponentModules().catch(console.error);
* @returns {Promise<string>} absolute path to the written bootstrap file
*/
async function generateViteBootstrap() {
await generateViteEnvInit();

const clientFiles = [
...globSync(path.join(CWD, 'components', '**', 'client.js')),
...globSync(path.join(CWD, 'layouts', '**', 'client.js')),
Expand Down Expand Up @@ -152,6 +155,8 @@ ${stickyListeners}
? "import './_globals-init.js';\n"
: '// no global/js — skipping _globals-init\n';

const envInitImport = "import './_env-init.js';\n";

// Clay-kiln's preloader does `Object.keys(window.modules)` to find
// component model.js / kiln.js registrations that Browserify's megabundler
// assigns there at page load. Under Vite there is no Browserify runtime,
Expand All @@ -174,6 +179,7 @@ ${stickyListeners}
'// present on the current page — keeping initial parse cost low.',
'',
kilnCompatStub,
envInitImport,
globalsImport,
stickyShimBlock,
'const _clayClientModules = {',
Expand Down
56 changes: 56 additions & 0 deletions lib/cmd/vite/generate-env-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

const fs = require('fs-extra');
const path = require('path');

const CWD = process.cwd();
const CLAY_DIR = path.join(CWD, '.clay');
const ENV_INIT_FILE = path.join(CLAY_DIR, '_env-init.js');

/**
* Generate .clay/_env-init.js — runtime hydration for window.process.env.
*
* Why:
* - Universal modules can be evaluated before late env injection in some
* browser paths under ESM (especially edit-mode/kiln startup), and any
* top-level `const X = process.env.X` captures undefined permanently.
* - Hydrating window.process.env in a dedicated side-effect module imported
* first by Vite entries ensures env is present before those modules run.
*
* Sources (in priority order):
* 1) window.kiln.preloadData._envVars (authoritative edit-mode payload from amphora-html)
* 2) existing window.process.env (if already injected by any earlier script)
*
* @returns {Promise<string>} absolute path to the generated file
*/
async function generateViteEnvInit() {
const content = [
'// AUTO-GENERATED — clay vite env init (do not edit)',
`// ${new Date().toISOString()}`,
';(function clayViteEnvInit() {',
' if (typeof window === "undefined") return;',
'',
' var fromKiln = window.kiln && window.kiln.preloadData && window.kiln.preloadData._envVars;',
' var existing = window.process && window.process.env;',
'',
' var source = (fromKiln && typeof fromKiln === "object")',
' ? fromKiln',
' : ((existing && typeof existing === "object") ? existing : {});',
'',
' window.process = window.process || {};',
' window.process.env = Object.assign({}, source, window.process.env || {});',
'}());',
'',
].join('\n');

await fs.ensureDir(CLAY_DIR);
await fs.writeFile(ENV_INIT_FILE, content, 'utf8');

return ENV_INIT_FILE;
}

module.exports = {
generateViteEnvInit,
ENV_INIT_FILE,
};

4 changes: 4 additions & 0 deletions lib/cmd/vite/generate-kiln-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const fs = require('fs-extra');
const path = require('path');
const { globSync } = require('glob');
const { generateViteEnvInit } = require('./generate-env-init');

const CWD = process.cwd();
const CLAY_DIR = path.join(CWD, '.clay');
Expand All @@ -27,6 +28,8 @@ const KILN_EDIT_ENTRY_KEY = '.clay/vite-kiln-edit-init';
* @returns {Promise<string>} absolute path to the generated file
*/
async function generateViteKilnEditEntry() {
await generateViteEnvInit();

const modelFiles = [
...globSync(path.join(CWD, 'components', '**', 'model.js')),
...globSync(path.join(CWD, 'layouts', '**', 'model.js')),
Expand Down Expand Up @@ -54,6 +57,7 @@ async function generateViteKilnEditEntry() {
// Use namespace imports (import * as) so both CJS modules (which @rollup/plugin-commonjs
// gives a namespace object with a .default property) and ESM modules work uniformly.
// Then resolve the actual export via _resolveDefault() at runtime.
lines.push('import \'./_env-init.js\';');
modelFiles.forEach((f, i) => lines.push(`import * as _m${i} from ${JSON.stringify(toRel(f))};`));
kilnjsFiles.forEach((f, i) => lines.push(`import * as _k${i} from ${JSON.stringify(toRel(f))};`));
if (hasKilnPlugin) {
Expand Down
Loading