vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
631 lines (630 loc) • 29.6 kB
JavaScript
import '../assertEnvServer.js';
// Public use
export { getGlobalContext };
export { getGlobalContextSync };
export { getGlobalContextAsync };
// Internal use
export { getGlobalContextServerInternal };
export { getGlobalContextServerInternalOptional };
export { getViteDevServer };
export { getViteConfig };
export { initGlobalContext_renderPage };
export { initGlobalContext_runPrerender };
export { initGlobalContext_getPagesAndRoutes };
export { setGlobalContext_viteDevServer };
export { setGlobalContext_viteConfig };
export { setGlobalContext_isPrerendering };
export { setGlobalContext_prerenderContext };
export { setGlobalContext_isProductionAccordingToVite };
export { setGlobalContext_prodBuildEntry }; // production entry
export { clearGlobalContext };
export { assertBuildInfo };
export { updateUserFiles };
export { vikeConfigErrorRecoverMsg };
// The core logic revolves around:
// - virtualFileExportsGlobalEntry is the main requirement
// - In production: globalObject.prodBuildEntry which is the production entry set by @brillout/vite-plugin-server-entry
// - loadProdBuildEntry() sets globalObject.prodBuildEntry and then sets virtualFileExportsGlobalEntry
// - With vike-server it's set at server start: @brillout/vite-plugin-server-entry injects `import './entry.mjs'` (the production entry generated by @brillout/vite-plugin-server-entry) as first line of code of dist/server/index.mjs while dist/server/entry.mjs calls setGlobalContext_prodBuildEntry()
// - Without vike-server it's manually loaded here using importServerProductionEntry() which uses @brillout/vite-plugin-server-entry's autoImporter or crawler
// - In development: globalObject.viteDevServer which is Vite's development server
// - globalObject.viteDevServer is used by updateUserFiles() which then sets virtualFileExportsGlobalEntry
import { PROJECT_VERSION } from '../../utils/PROJECT_VERSION.js';
import { assert, assertUsage, assertWarning } from '../../utils/assert.js';
import { assertIsNotBrowser } from '../../utils/assertIsNotBrowser.js';
import { isPlainObject } from '../../utils/isPlainObject.js';
import { objectReplace } from '../../utils/objectReplace.js';
import { genPromise } from '../../utils/genPromise.js';
import { createDebug } from '../../utils/debug.js';
import { getViteRPC } from '../../utils/getViteRPC.js';
import { isRunnableDevEnvironment } from '../../utils/isRunnableDevEnvironment.js';
import { isNonRunnableDevProcess } from '../../utils/isNonRunnableDevProcess.js';
import { onSetupRuntime, setNodeEnvProductionIfUndefined } from '../../utils/assertSetup.js';
import { checkType } from '../../utils/checkType.js';
import { getGlobalObject } from '../../utils/getGlobalObject.js';
import { hasProp } from '../../utils/hasProp.js';
import { isObject } from '../../utils/isObject.js';
import { objectAssign } from '../../utils/objectAssign.js';
import { importServerProductionEntry } from '@brillout/vite-plugin-server-entry/runtime';
import { virtualFileIdGlobalEntryServer } from '../../shared-server-node/virtualFileId.js';
import pc from '@brillout/picocolors';
import { loadPageRoutes, loadPageRoutesSync } from '../../shared-server-client/route/loadPageRoutes.js';
import { assertV1Design } from '../../shared-server-node/assertV1Design.js';
import { resolveBase } from '../../shared-server-node/resolveBase.js';
import { createGlobalContextShared, getGlobalContextSyncErrMsg, } from '../../shared-server-client/createGlobalContextShared.js';
import { getGlobalContextPublicShared } from '../../shared-server-client/getGlobalContextPublicShared.js';
import { logRuntimeError, logRuntimeInfo } from './loggerRuntime.js';
import { debugFileChange, getVikeConfigErrorBuild, setVikeConfigError, } from '../../shared-server-node/getVikeConfigError.js';
import { getVikeApiOperation } from '../../shared-server-node/api-context.js';
import { hasAlreadyLogged } from './logErrorServer.js';
const debug = createDebug('vike:globalContext');
const globalObject = getGlobalObject('runtime/globalContext.ts', getInitialGlobalObject());
// Trick to break down TypeScript circular dependency
// https://chat.deepseek.com/a/chat/s/d7e9f90a-c7f3-4108-9cd5-4ad6caed3539
const globalObjectTyped = globalObject;
const vikeConfigErrorRecoverMsg = pc.bold(pc.green('Vike config loaded'));
assertIsNotBrowser();
async function getGlobalContextServerInternal() {
// getGlobalContextServerInternal() should always be called after initGlobalContext()
assert(globalObject.isInitialized);
assertGlobalContextIsDefined();
if (!isProd())
await globalObject.waitForUserFilesUpdate;
const { globalContext } = globalObjectTyped;
assertIsDefined(globalContext);
return { globalContext };
}
function getGlobalContextServerInternalOptional() {
const { globalContext } = globalObjectTyped;
if (!globalContext)
return null;
return globalContext;
}
function assertIsDefined(globalContext) {
if (!globalContext) {
debug('globalContext', globalContext);
debug('assertIsDefined()', new Error().stack);
assert(false);
}
}
function assertGlobalContextIsDefined() {
assertIsDefined(globalObjectTyped.globalContext);
assert(globalObject.globalContext);
}
// We purposely return GlobalContext instead of GlobalContextServer because `import { getGlobalContext } from 'vike'` can resolve to the client-side implementation.
/**
* Get runtime information about your app.
*
* https://vike.dev/getGlobalContext
*/
async function getGlobalContext() {
debug('getGlobalContext()');
const isProduction = isProdOptional();
// This assertion cannot fail for vike-server users (because when using vike-server it's guaranteed that globalObject.isProduction is set before executing any user-land code and any Vike extension code).
assertUsage(isProduction !== null, "The global context isn't set yet, use getGlobalContextAsync() instead.");
return await getGlobalContextAsync(isProduction);
}
/**
* Get runtime information about your app.
*
* https://vike.dev/getGlobalContext
*/
async function getGlobalContextAsync(isProduction) {
debug('getGlobalContextAsync()');
assertUsage(typeof isProduction === 'boolean', `[getGlobalContextAsync(isProduction)] Argument ${pc.cyan('isProduction')} ${isProduction === undefined ? 'is missing' : `should be ${pc.cyan('true')} or ${pc.cyan('false')}`}`);
globalObject.isProductionAccordingToUser = isProduction;
if (!globalObject.globalContext)
await initGlobalContext_getGlobalContextAsync();
if (!isProduction)
await globalObject.waitForUserFilesUpdate;
assertGlobalContextIsDefined();
return getGlobalContextPublic();
}
/**
* Get runtime information about your app.
*
* https://vike.dev/getGlobalContext
*/
function getGlobalContextSync() {
debug('getGlobalContextSync()');
const { globalContext } = globalObjectTyped;
assertUsage(globalContext, getGlobalContextSyncErrMsg);
assertWarning(isProd(),
// - We discourage users from using it in development because `pageContext.globalContext` is safer: I ain't sure but there could be race conditions when using `getGlobalContextSync()` inside React/Vue components upon HMR.
// - I don't see any issues with getGlobalContextSync() in production.
// - getGlobalContextSync() is used in production by vike-vercel
// - https://discord.com/channels/@me/942519153502339072/1389546794676916344 (PM between Rom and Joël)
"getGlobalContextSync() shouldn't be used in development, see https://vike.dev/getGlobalContext", { onlyOnce: true });
return getGlobalContextPublic();
}
function getGlobalContextPublic() {
const { globalContext } = globalObjectTyped;
assert(globalContext);
const globalContextPublic = getGlobalContextPublicShared(globalContext);
return globalContextPublic;
}
async function setGlobalContext_viteDevServer(viteDevServer) {
debug('setGlobalContext_viteDevServer()');
assert(!isNonRunnableDevProcess()); // if `viteDevServer` exists => cannot be inside a non-runnable process
// We cannot cache globalObject.viteDevServer because it's fully replaced when the user modifies vite.config.js => Vite's dev server is fully reloaded and a new viteDevServer replaces the previous one.
if (!globalObject.viteDevServer) {
assertIsNotInitializedYet();
}
assert(globalObject.viteConfig);
globalObject.viteDevServer = viteDevServer;
globalObject.viteDevServerPromiseResolve(viteDevServer);
const { success } = await updateUserFiles();
if (!success)
return;
assertGlobalContextIsDefined();
}
function setGlobalContext_viteConfig(viteConfig, viteConfigRuntime) {
if (globalObject.viteConfig)
return;
assertIsNotInitializedYet();
globalObject.viteConfig = viteConfig;
globalObject.viteConfigRuntime = viteConfigRuntime;
}
function assertIsNotInitializedYet() {
// In development, globalObject.viteDevServer always needs to be awaited for before initializing globalObject.globalContext
assert(!globalObject.globalContext);
}
function setGlobalContext_isPrerendering() {
globalObject.isPrerendering = true;
}
function setGlobalContext_prerenderContext(prerenderContextPublic) {
globalObject.prerenderContextPublic = prerenderContextPublic;
// Ugly redundancy, which we can remove after globalContext is a proxy
const { globalContext } = globalObjectTyped;
if (globalContext)
globalContext.prerenderContext = prerenderContextPublic;
}
function setGlobalContext_isProductionAccordingToVite(isProductionAccordingToVite) {
globalObject.isProductionAccordingToVite = isProductionAccordingToVite;
}
function getViteDevServer() {
return globalObject.viteDevServer ?? null;
}
function getViteConfig() {
return globalObject.viteConfig ?? null;
}
async function initGlobalContext_renderPage() {
debug('initGlobalContext_renderPage()');
globalObject.isAfterFirstRenderPageCall = true;
await initGlobalContext();
}
async function initGlobalContext_runPrerender() {
debug('initGlobalContext_runPrerender()');
assert(globalObject.isPrerendering === true);
assert(isProd());
if (globalObject.initGlobalContext_runPrerender_alreadyCalled)
return;
globalObject.initGlobalContext_runPrerender_alreadyCalled = true;
assert(globalObject.isPrerendering);
assert(globalObject.viteConfig);
// We assume initGlobalContext_runPrerender() to be called before:
// - initGlobalContext_renderPage()
// - initGlobalContext_getGlobalContextAsync()
assertIsNotInitializedYet();
await initGlobalContext();
}
async function initGlobalContext_getGlobalContextAsync() {
debug('initGlobalContext_getGlobalContextAsync()');
await initGlobalContext();
}
async function initGlobalContext_getPagesAndRoutes() {
debug('initGlobalContext_getPagesAndRoutes()');
globalObject.isProductionAccordingToPhotonVercel = true;
await initGlobalContext();
}
async function initGlobalContext() {
const isProduction = isProd();
if (!isProduction) {
if (isProcessSharedWithVite()) {
await globalObject.viteDevServerPromise;
}
else {
assert(isNonRunnableDevProcess());
await updateUserFiles();
}
assert(globalObject.waitForUserFilesUpdate);
await globalObject.waitForUserFilesUpdate;
}
else {
await loadProdBuildEntry(globalObject.viteConfigRuntime?.build.outDir);
}
assertGlobalContextIsDefined();
globalObject.isInitialized = true;
}
function assertViteManifest(manifest) {
assert(isPlainObject(manifest));
/* We should include these assertions but we don't as a workaround for PWA manifests: https://github.com/vikejs/vike/issues/769
Instead, we should rename the vite manifest e.g. with https://vitejs.dev/config/build-options.html#build-manifest
Object.entries(manifest)
// circumvent esbuild bug: esbuild adds a `default` key to JSON upon `require('./some.json')`.
.filter(([key]) => key !== 'default')
.forEach(([_, entry]) => {
assert(isPlainObject(entry))
assert(typeof entry.file === 'string')
})
*/
}
async function loadProdBuildEntry(outDir) {
debug('loadProdBuildEntry()');
if (globalObject.globalContext) {
debug('loadProdBuildEntry() - already done');
return;
}
if (!globalObject.prodBuildEntry) {
debug('importServerProductionEntry()');
// importServerProductionEntry() loads dist/server/entry.mjs which calls setGlobalContext_prodBuildEntry()
await importServerProductionEntry({ outDir });
if (!globalObject.prodBuildEntry) {
debug('globalObject.prodBuildEntryPrevious');
// Needed, for example, when calling the API prerender() then preview() because both trigger a importServerProductionEntry() call but only the first only is applied because of the import() cache. (A proper implementation would be to clear the import() cache, but it probably isn't possible on platforms such as Cloudflare Workers.)
globalObject.prodBuildEntry = globalObject.prodBuildEntryPrevious;
}
assert(globalObject.prodBuildEntry);
// If using `inject` then dist/server/index.js imports dist/server/entry.js and loadProdBuildEntry() isn't needed.
// If dist/server/entry.js isn't imported then this means the user is running the original server entry `$ ts-node server/index.ts`.
assertWarning(
// vike-server => `inject === true`
// vike-node => `inject === [ 'index' ]` => we don't show the warning to vike-node users (I don't remember why).
globalObject.buildInfo?.viteConfigRuntime.vitePluginServerEntry.inject !== true || globalObject.isPrerendering, `Run the built server entry (e.g. ${pc.cyan('$ node dist/server/index.mjs')}) instead of the original server entry (e.g. ${pc.cyan('$ ts-node server/index.ts')})`, { onlyOnce: true });
}
const { prodBuildEntry } = globalObject;
assertProdBuildEntry(prodBuildEntry);
globalObject.assetsManifest = prodBuildEntry.assetsManifest;
globalObject.buildInfo = prodBuildEntry.buildInfo;
await createGlobalContext(prodBuildEntry.virtualFileExportsGlobalEntry);
}
// This is the production entry, see:
// https://github.com/vikejs/vike/blob/8c350e8105a626469e87594d983090919e82099b/packages/vike/node/vite/plugins/pluginBuild/pluginProdBuildEntry.ts#L47
async function setGlobalContext_prodBuildEntry(prodBuildEntry) {
debug('setGlobalContext_prodBuildEntry()');
assert(!isNonRunnableDevProcess());
assertProdBuildEntry(prodBuildEntry);
setNodeEnvProductionIfUndefined();
globalObject.prodBuildEntry = prodBuildEntry;
globalObject.prodBuildEntryPrevious = prodBuildEntry;
assert(globalObject.prodBuildEntry); // ensure no infinite loop
await loadProdBuildEntry();
assertGlobalContextIsDefined();
debug('setGlobalContext_prodBuildEntry() - done');
}
function assertProdBuildEntry(prodBuildEntry) {
assert(isObject(prodBuildEntry));
assert(hasProp(prodBuildEntry, 'virtualFileExportsGlobalEntry', 'object'));
const { virtualFileExportsGlobalEntry } = prodBuildEntry;
assert(hasProp(prodBuildEntry, 'assetsManifest', 'object'));
const { assetsManifest } = prodBuildEntry;
assertViteManifest(assetsManifest);
assert(hasProp(prodBuildEntry, 'buildInfo', 'object'));
const { buildInfo } = prodBuildEntry;
assertBuildInfo(buildInfo);
checkType({ virtualFileExportsGlobalEntry, assetsManifest, buildInfo });
}
function assertBuildInfo(buildInfo) {
assert(isObject(buildInfo));
assert(hasProp(buildInfo, 'versionAtBuildTime', 'string'));
assertVersionAtBuildTime(buildInfo.versionAtBuildTime);
assert(hasProp(buildInfo, 'viteConfigRuntime', 'object'));
assert(hasProp(buildInfo.viteConfigRuntime, '_baseViteOriginal', 'string'));
assert(hasProp(buildInfo.viteConfigRuntime, 'root', 'string'));
assert(hasProp(buildInfo.viteConfigRuntime, 'build', 'object'));
assert(hasProp(buildInfo.viteConfigRuntime.build, 'outDir', 'string'));
assert(hasProp(buildInfo.viteConfigRuntime, 'vitePluginServerEntry', 'object'));
assert(hasProp(buildInfo, 'usesClientRouter', 'boolean'));
}
function assertVersionAtBuildTime(versionAtBuildTime) {
const versionAtRuntime = PROJECT_VERSION;
const pretty = (version) => pc.bold(`vike@${version}`);
assertUsage(versionAtBuildTime === versionAtRuntime, `Re-build your app (you're using ${pretty(versionAtRuntime)} but your app was built with ${pretty(versionAtBuildTime)})`);
}
async function updateUserFiles() {
debugUpdate();
assert(!isProd());
const { viteDevServer } = globalObject;
const isRunnableServer = !!viteDevServer && isRunnableDevServer(viteDevServer);
const isNonRunnableProcess = isNonRunnableDevProcess();
if (!isRunnableServer && !isNonRunnableProcess) {
// Not the runtime process — it's the Vite process and not the non-runnable process
debugUpdate('=> aborted: not runtime');
return { success: false };
}
const { promise, resolve } = genPromise();
globalObject.waitForUserFilesUpdate = promise;
globalObject.waitForUserFilesUpdateResolve ?? (globalObject.waitForUserFilesUpdateResolve = []);
globalObject.waitForUserFilesUpdateResolve.push(resolve);
let hasError = false;
let virtualFileExportsGlobalEntry;
let err;
if (isRunnableServer) {
assert(viteDevServer);
assert(isRunnableDevServer(viteDevServer));
assert(!isNonRunnableProcess);
/* We don't use runner.import() yet, because as of vite@7.0.6 (July 2025) runner.import() unexpectedly invalidates the module graph, which is a unexpected behavior that doesn't happen with ssrLoadModule()
// Vite 6
try {
virtualFileExportsGlobalEntry = await (viteDevServer.environments.ssr as RunnableDevEnvironment).runner.import(
'virtual:vike:global-entry:server',
)
} catch (err_) {
hasError = true
err = err_
}
*/
// Vite 5
try {
virtualFileExportsGlobalEntry = await viteDevServer.ssrLoadModule(virtualFileIdGlobalEntryServer);
}
catch (err_) {
hasError = true;
err = err_;
}
}
else {
assert(isNonRunnableProcess);
assert(!viteDevServer);
try {
// We don't directly use import() because:
// - Avoid Cloudflare Workers (without @cloudflare/vite-plugin) to try to bundle `import('virtual:id')`.
// - Using import() seems to lead to a Vite HMR bug:
// ```js
// assert(false)
// // This line breaks the HMR of regular (runnable) apps, even though (as per the assert() above) it's never run. It seems to be a Vite bug: handleHotUpdate() receives an empty `modules` list.
// import('virtual:vike:global-entry:server')
// ```
virtualFileExportsGlobalEntry = await __VIKE__DYNAMIC_IMPORT('virtual:vike:global-entry:server');
}
catch (err_) {
hasError = true;
err = err_;
}
}
if (isOutdated())
return { success: false };
if (hasError)
return onError(err);
virtualFileExportsGlobalEntry = virtualFileExportsGlobalEntry.default || virtualFileExportsGlobalEntry;
if (getVikeConfigErrorBuild()) {
debugUpdate('=> aborted: build error');
return { success: false };
}
try {
await createGlobalContext(virtualFileExportsGlobalEntry);
}
catch (err_) {
hasError = true;
err = err_;
}
if (isOutdated())
return { success: false };
if (hasError)
return onError(err);
return onSuccess();
function onSuccess() {
debugUpdate('=> onSuccess()');
if (globalObject.vikeConfigHasRuntimeError) {
assert(logRuntimeInfo); // always defined in dev
logRuntimeInfo(vikeConfigErrorRecoverMsg, null, 'error-resolve');
}
globalObject.vikeConfigHasRuntimeError = false;
setVikeConfigError({ errorRuntime: false });
globalObject.waitForUserFilesUpdateResolve.forEach((resolve) => resolve());
globalObject.waitForUserFilesUpdateResolve = [];
resolve();
return { success: true };
}
function onError(err) {
debugUpdate('=> onError()');
if (
// We must check whether the error was already logged to avoid printing it twice, e.g. when +onCreateGlobalContext.js has a syntax error
!hasAlreadyLogged(err)) {
logRuntimeError(err, null);
}
setVikeConfigError({ errorRuntime: { err } });
globalObject.vikeConfigHasRuntimeError = true;
return { success: false };
}
function isOutdated() {
const yes =
// There is a newer call — let the new call supersede the old one.
// We deliberately swallow the intermetidate state (including any potential error) — it's now outdated and has existed only for a very short period of time.
globalObject.waitForUserFilesUpdate !== promise ||
// Avoid race condition: abort if there is a new globalObject.viteDevServer (happens when vite.config.js is modified => Vite's dev server is fully reloaded).
viteDevServer !== globalObject.viteDevServer;
if (yes)
debugUpdate('=> aborted: isOutdated');
return yes;
}
function debugUpdate(...args) {
debug('updateUserFiles()', ...args);
debugFileChange('updateUserFiles()', ...args);
}
}
async function createGlobalContext(virtualFileExportsGlobalEntry) {
debug('createGlobalContext()');
assert(!getVikeConfigErrorBuild());
const globalContextPromise = createGlobalContextShared(virtualFileExportsGlobalEntry, globalObject, addGlobalContext, addGlobalContextTmp, addGlobalContextAsync);
debug('createGlobalContext() - done [sync]');
// We define an early globalContext version synchronously, so that getGlobalContextSync() can be called early.
// - Required by vike-vercel
assert(globalObject.globalContext);
const globalContext = await globalContextPromise;
debug('createGlobalContext() - done [async]');
assertV1Design(
// pageConfigs is PageConfigRuntime[] but assertV1Design() requires PageConfigBuildTime[]
globalContext._pageConfigs.length > 0, globalContext._pageFilesAll);
assertGlobalContextIsDefined();
onSetupRuntime();
objectAssign(globalContext, { prerenderContext: globalObject.prerenderContextPublic });
// Never actually used, only used for TypeScript `ReturnType<typeof createGlobalContext>`
return globalContext;
}
async function addGlobalContextTmp(globalContext) {
debug('addGlobalContextTmp()');
const { pageRoutes, onBeforeRouteHook } = await loadPageRoutes(globalContext._pageFilesAll, globalContext._pageConfigs, globalContext._pageConfigGlobal, globalContext._allPageIds);
return addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook);
}
function addGlobalContext(globalContext) {
debug('addGlobalContext()');
const { pageRoutes, onBeforeRouteHook } = loadPageRoutesSync(globalContext._pageFilesAll, globalContext._pageConfigs, globalContext._pageConfigGlobal, globalContext._allPageIds);
return addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook);
}
function addGlobalContextCommon(globalContext, pageRoutes, onBeforeRouteHook) {
const globalContextBase = {
isClientSide: false,
_pageRoutes: pageRoutes,
_onBeforeRouteHook: onBeforeRouteHook,
};
const { viteDevServer, viteConfig, isPrerendering } = globalObject;
const isProduction = isProd();
if (!isProduction) {
assert(globalContext); // main common requirement
assert(!isPrerendering);
return {
...globalContextBase,
_isProduction: false,
_isPrerendering: false,
assetsManifest: null,
_viteDevServer: viteDevServer,
viteConfig,
};
}
else {
assert(globalObject.prodBuildEntry);
assert(globalContext); // main common requiement
const { buildInfo, assetsManifest } = globalObject;
assert(buildInfo);
assert(assetsManifest);
const globalContextBase2 = {
...globalContextBase,
_isProduction: true,
assetsManifest,
_viteDevServer: null,
_usesClientRouter: buildInfo.usesClientRouter,
};
if (isPrerendering) {
assert(viteConfig);
return {
...globalContextBase2,
_isPrerendering: true,
viteConfig,
};
}
else {
return {
...globalContextBase2,
_isPrerendering: false,
viteConfig: null,
};
}
}
}
async function addGlobalContextAsync(globalContext) {
debug('addGlobalContextAsync()');
let { viteConfigRuntime, buildInfo } = globalObject;
if (!viteConfigRuntime) {
if (buildInfo) {
viteConfigRuntime = buildInfo.viteConfigRuntime;
}
else {
assert(!isProcessSharedWithVite()); // process shared with Vite => globalObject.viteConfigRuntime should be set
assert(!isProd()); // production => globalObject.buildInfo.viteConfigRuntime should be set
assert(isNonRunnableDevProcess());
const rpc = getViteRPC();
viteConfigRuntime = await rpc.getViteConfigRuntimeRPC();
}
}
assert(viteConfigRuntime);
return {
viteConfigRuntime,
...resolveBaseRuntime(viteConfigRuntime, globalContext.config),
};
}
function clearGlobalContext() {
debug('clearGlobalContext()');
objectReplace(globalObject, getInitialGlobalObject(), ['prodBuildEntryPrevious']);
}
function getInitialGlobalObject() {
debug('getInitialGlobalObject()');
const { promise: viteDevServerPromise, resolve: viteDevServerPromiseResolve } = genPromise();
return {
viteDevServerPromise,
viteDevServerPromiseResolve,
};
}
function resolveBaseRuntime(viteConfigRuntime, config) {
const baseViteOriginal = viteConfigRuntime._baseViteOriginal;
const baseServerUnresolved = config.baseServer ?? null;
const baseAssetsUnresolved = config.baseAssets ?? null;
return resolveBase(baseViteOriginal, baseServerUnresolved, baseAssetsUnresolved);
}
function isProcessSharedWithVite() {
const yes = globalThis.__VIKE__IS_PROCESS_SHARED_WITH_VITE ?? false;
if (yes)
assert(!isNonRunnableDevProcess());
return yes;
}
function isRunnableDevServer(viteDevServer) {
assert(!isNonRunnableDevProcess()); // if `viteDevServer` exists => cannot be inside a non-runnable process
const yes =
// Vite 5
!viteDevServer.environments ||
// Vite 6 or above
isRunnableDevEnvironment(viteDevServer.environments.ssr);
return yes;
}
function isProd() {
const isProduction = isProdOptional();
if (isProduction === null) {
if (globalObject.isAfterFirstRenderPageCall) {
// When using a production server without vike-server, there isn't any reliable signal we can use to determine early whether the environment is production or development. If renderPage() was called then some non-negligible amount of time passed — it's likely that, in dev, one of the Vite hooks should have already sent a signal we can use to determine prod/dev.
return true;
}
else {
assert(false);
}
}
return isProduction;
}
function isProdOptional() {
const vikeApiOperation = getVikeApiOperation()?.operation ?? null;
// setGlobalContext_prodBuildEntry() was called
const yes1 = !!globalObject.prodBuildEntry;
const yes2 = globalObject.isPrerendering === true;
// Vike CLI & Vike API
const yes3 = !!vikeApiOperation && vikeApiOperation !== 'dev';
// Vite command
const yes4 = globalObject.isProductionAccordingToVite === true;
// getGlobalContextAsync(isProduction)
const yes5 = globalObject.isProductionAccordingToUser === true;
// vite-plugin-vercel
const yes6 = globalObject.isProductionAccordingToPhotonVercel === true;
const yes7 = globalThis.__VIKE__IS_DEV === false;
const yes = yes1 || yes2 || yes3 || yes4 || yes5 || yes6 || yes7;
const no1 = !!globalObject.viteDevServer;
// Vike CLI & Vike API
const no2 = vikeApiOperation === 'dev';
// Vite command
const no3 = globalObject.isProductionAccordingToVite === false;
// getGlobalContextAsync(isProduction)
const no4 = globalObject.isProductionAccordingToUser === false;
// @cloudflare/vite-plugin
const no5 = isNonRunnableDevProcess();
const no6 = globalThis.__VIKE__IS_DEV === true;
const no = no1 || no2 || no3 || no4 || no5 || no6;
const debug = { yes1, yes2, yes3, yes4, yes5, yes6, yes7, no1, no2, no3, no4, no5, no6 };
assert(typeof yes === 'boolean', debug);
assert(typeof no === 'boolean', debug);
if (yes) {
assert(no === false, debug);
return true;
}
if (no) {
assert(yes === false, debug);
return false;
}
return null;
}