UNPKG

vike

Version:

(Replaces Next.js/Nuxt) 🔨 Composable framework to build advanced applications with flexibility and stability.

185 lines (181 loc) • 7.91 kB
export { generateVirtualFileGlobalEntryWithOldDesign }; import { assert } from '../../../../utils/assert.js'; import { isVersionMatch } from '../../../../utils/assertVersion.js'; import { debugGlob } from '../../../../utils/debugGlob.js'; import { scriptFileExtensionPattern } from '../../../../utils/isScriptFile.js'; import { assertPosixPath } from '../../../../utils/path.js'; import { parseVirtualFileId } from '../../../../shared-server-node/virtualFileId.js'; import { version as viteVersion } from 'vite'; import { fileTypes } from '../../../../shared-server-client/getPageFiles/fileTypes.js'; import path from 'node:path'; import { generateVirtualFileGlobalEntry } from './generateVirtualFileGlobalEntry.js'; import { getVikeConfigInternal } from '../../shared/resolveVikeConfigInternal.js'; import { getOutDirs } from '../../shared/getOutDirs.js'; import { isViteServerSide_extraSafe } from '../../shared/isViteServerSide.js'; import { resolveIncludeAssetsImportedByServer } from '../../../../server/runtime/renderPageServer/getPageAssets/retrievePageAssetsProd.js'; import { VIRTUAL_FILE_ID_constantsGlobalThis } from '../pluginReplaceConstantsGlobalThis.js'; import '../../assertEnvVite.js'; async function generateVirtualFileGlobalEntryWithOldDesign(id, options, config, env, isDev) { const idParsed = parseVirtualFileId(id); assert(idParsed && idParsed.type === 'global-entry'); const { isForClientSide, isClientRouting } = idParsed; assert(isForClientSide === !isViteServerSide_extraSafe(config, env, options)); const code = await getCode(config, isForClientSide, isClientRouting, isDev, id); return code; } async function getCode(config, isForClientSide, isClientRouting, isDev, id) { const { command } = config; assert(command === 'serve' || command === 'build'); const isBuild = command === 'build'; assert(isDev === !isBuild); let content = ''; if (!isForClientSide) { content += `import '${VIRTUAL_FILE_ID_constantsGlobalThis}';\n`; } { const globRoots = getGlobRoots(config); debugGlob('Glob roots: ', globRoots); content += await generateGlobImports(globRoots, isBuild, isForClientSide, isClientRouting, isDev, id); } debugGlob(`Glob imports for ${isForClientSide ? 'client' : 'server'}:\n`, content); return content; } function determineInjection({ fileType, isForClientSide, isClientRouting, isPrerendering, isBuild, }) { if (!isForClientSide) { return { includeImport: fileType === '.page.server' || fileType === '.page' || fileType === '.page.route', includeExportNames: isPrerendering && isBuild ? fileType === '.page.client' || fileType === '.page.server' || fileType === '.page' // We extensively use `PageFile['exportNames']` while pre-rendering, in order to avoid loading page files unnecessarily, and therefore reducing memory usage. : fileType === '.page.client', }; } else { const includeImport = fileType === '.page.client' || fileType === '.css' || fileType === '.page'; if (!isClientRouting) { return { includeImport, includeExportNames: false, }; } else { return { includeImport: includeImport || fileType === '.page.route', includeExportNames: fileType === '.page.client' || fileType === '.page.server' || fileType === '.page', }; } } } async function generateGlobImports(globRoots, isBuild, isForClientSide, isClientRouting, isDev, id) { let fileContent = `// Generated by Vike export const pageFilesLazy = {}; export const pageFilesEager = {}; export const pageFilesExportNamesLazy = {}; export const pageFilesExportNamesEager = {}; export const pageFilesList = []; export const neverLoaded = {}; ${await generateVirtualFileGlobalEntry(isForClientSide, isDev, id, isClientRouting)} `; const vikeConfig = await getVikeConfigInternal(); // Old design => no + files => only to enable pre-rendering is setting `vike({prerender})` in vite.config.js const isPrerendering = !!vikeConfig.config.prerender; fileTypes .filter((fileType) => fileType !== '.css') .forEach((fileType) => { const { includeImport, includeExportNames } = determineInjection({ fileType, isForClientSide, isClientRouting, isPrerendering, isBuild, }); if (includeImport) { fileContent += getGlobs(globRoots, isBuild, fileType, null); } if (includeExportNames) { fileContent += getGlobs(globRoots, isBuild, fileType, 'extractExportNames'); } }); const includeAssetsImportedByServer = resolveIncludeAssetsImportedByServer(vikeConfig.config); if (includeAssetsImportedByServer && isForClientSide) { fileContent += getGlobs(globRoots, isBuild, '.page.server', 'extractAssets'); } return fileContent; } function getGlobs(globRoots, isBuild, fileType, query) { const isEager = isBuild && (query === 'extractExportNames' || fileType === '.page.route'); let pageFilesVar; if (query === 'extractExportNames') { if (!isEager) { pageFilesVar = 'pageFilesExportNamesLazy'; } else { pageFilesVar = 'pageFilesExportNamesEager'; } } else if (query === 'extractAssets') { assert(!isEager); pageFilesVar = 'neverLoaded'; } else if (!query) { if (!isEager) { pageFilesVar = 'pageFilesLazy'; } else { // Used for `.page.route.js` files pageFilesVar = 'pageFilesEager'; } } else { assert(false); } const varNameSuffix = (fileType === '.page' && 'Isomorph') || (fileType === '.page.client' && 'Client') || (fileType === '.page.server' && 'Server') || (fileType === '.page.route' && 'Route'); assert(varNameSuffix); const varName = `${pageFilesVar}${varNameSuffix}`; const varNameLocals = []; return [ ...globRoots.map((globRoot, i) => { const varNameLocal = `${varName}${i + 1}`; varNameLocals.push(varNameLocal); const globIncludePath = `'${getGlobPath(globRoot.includeDir, fileType)}'`; const globExcludePath = globRoot.excludeDir ? `'!${getGlobPath(globRoot.excludeDir, fileType)}'` : null; const globOptions = { eager: isEager }; if (query) { const isNewViteInterface = isVersionMatch(viteVersion, ['5.1.0']); if (isNewViteInterface) { globOptions.query = `?${query}`; } else { globOptions.as = query; } } const globPaths = globExcludePath ? `[${globIncludePath}, ${globExcludePath}]` : `[${globIncludePath}]`; const globLine = `const ${varNameLocal} = import.meta.glob(${globPaths}, ${JSON.stringify(globOptions)});`; return globLine; }), `const ${varName} = {${varNameLocals.map((varNameLocal) => `...${varNameLocal}`).join(',')}};`, `${pageFilesVar}['${fileType}'] = ${varName};`, '', ].join('\n'); } function getGlobRoots(config) { const globRoots = [ { includeDir: '/', excludeDir: path.posix.relative(config.root, getOutDirs(config, undefined).outDirRoot), }, ]; return globRoots; } function getGlobPath(globRootDir, fileType) { assertPosixPath(globRootDir); let globPath = [...globRootDir.split('/'), '**', `*${fileType}.${scriptFileExtensionPattern}`] .filter(Boolean) .join('/'); if (!globPath.startsWith('/')) { globPath = '/' + globPath; } return globPath; }