vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
208 lines (207 loc) • 10.8 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareViteApiCall = prepareViteApiCall;
exports.getViteRoot = getViteRoot;
exports.assertViteRoot = assertViteRoot;
exports.normalizeViteRoot = normalizeViteRoot;
const vite_1 = require("vite");
const context_js_1 = require("./context.js");
const resolveVikeConfigInternal_js_1 = require("../vite/shared/resolveVikeConfigInternal.js");
const node_path_1 = __importDefault(require("node:path"));
const utils_js_1 = require("./utils.js");
const picocolors_1 = __importDefault(require("@brillout/picocolors"));
const globalContext_js_1 = require("../runtime/globalContext.js");
const getEnvVarObject_js_1 = require("../vite/shared/getEnvVarObject.js");
const globalObject = (0, utils_js_1.getGlobalObject)('api/prepareViteApiCall.ts', {});
async function prepareViteApiCall(options, operation) {
clear();
(0, context_js_1.setContextApiOperation)(operation, options);
const viteConfigFromUserApiOptions = options.viteConfig;
return resolveConfigs(viteConfigFromUserApiOptions, operation);
}
// For subsequent API calls, e.g. calling prerender() after build()
function clear() {
(0, context_js_1.clearContextApiOperation)();
(0, globalContext_js_1.clearGlobalContext)();
}
async function resolveConfigs(viteConfigFromUserApiOptions, operation) {
const viteInfo = await getViteInfo(viteConfigFromUserApiOptions, operation);
(0, resolveVikeConfigInternal_js_1.setVikeConfigContext)({
userRootDir: viteInfo.root,
isDev: operation === 'dev',
vikeVitePluginOptions: viteInfo.vikeVitePluginOptions,
});
const vikeConfig = await (0, resolveVikeConfigInternal_js_1.getVikeConfigInternal)();
const viteConfigFromUserEnhanced = applyVikeViteConfig(viteInfo.viteConfigFromUserEnhanced, vikeConfig);
const { viteConfigResolved } = await assertViteRoot2(viteInfo.root, viteConfigFromUserEnhanced, operation);
return {
vikeConfig,
viteConfigResolved, // ONLY USE if strictly necessary. (We plan to remove assertViteRoot2() as explained in the comments of that function.)
viteConfigFromUserEnhanced,
};
}
// Apply +vite
// - For example, Vike extensions adding Vite plugins
function applyVikeViteConfig(viteConfigFromUserEnhanced, vikeConfig) {
const viteConfigs = vikeConfig._from.configsCumulative.vite;
if (!viteConfigs)
return viteConfigFromUserEnhanced;
viteConfigs.values.forEach((v) => {
(0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(v.value), `${v.definedAt} should be an object`);
viteConfigFromUserEnhanced = (0, vite_1.mergeConfig)(viteConfigFromUserEnhanced ?? {}, v.value);
(0, utils_js_1.assertUsage)(!findVikeVitePlugin(v.value), "Using the +vite setting to add Vike's Vite plugin is forbidden");
});
return viteConfigFromUserEnhanced;
}
async function getViteRoot(operation) {
if (!globalObject.root)
await getViteInfo(undefined, operation);
(0, utils_js_1.assert)(globalObject.root);
return globalObject.root;
}
async function getViteInfo(viteConfigFromUserApiOptions, operation) {
let viteConfigFromUserEnhanced = viteConfigFromUserApiOptions;
// Precedence:
// 1) viteConfigFromUserEnvVar (highest precedence)
// 2) viteConfigFromUserVikeConfig
// 2) viteConfigFromUserApiOptions
// 3) viteConfigFromUserViteFile (lowest precedence)
// Resolve Vike's +mode setting
{
const viteConfigFromUserVikeConfig = (0, utils_js_1.pick)((0, resolveVikeConfigInternal_js_1.getVikeConfigFromCliOrEnv)().vikeConfigFromCliOrEnv, ['mode']);
if (Object.keys(viteConfigFromUserVikeConfig).length > 0) {
viteConfigFromUserEnhanced = (0, vite_1.mergeConfig)(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserVikeConfig);
}
}
// Resolve VITE_CONFIG
const viteConfigFromUserEnvVar = (0, getEnvVarObject_js_1.getEnvVarObject)('VITE_CONFIG');
if (viteConfigFromUserEnvVar) {
viteConfigFromUserEnhanced = (0, vite_1.mergeConfig)(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserEnvVar);
}
// Resolve vite.config.js
const viteConfigFromUserViteFile = await loadViteConfigFile(viteConfigFromUserEnhanced, operation);
// Correct precedence, replicates Vite:
// https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
const viteConfigResolved = (0, vite_1.mergeConfig)(viteConfigFromUserViteFile ?? {}, viteConfigFromUserEnhanced ?? {});
const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
globalObject.root = root;
// - Find options `vike(options)` set in vite.config.js
// - TODO/next-major: remove
// - Add Vike's Vite plugin if missing
let vikeVitePluginOptions;
const found = findVikeVitePlugin(viteConfigResolved);
if (found) {
vikeVitePluginOptions = found.vikeVitePluginOptions;
}
else {
// Add Vike to plugins if not present.
// Using a dynamic import because the script calling the Vike API may not live in the same place as vite.config.js, thus vike/plugin may resolved to two different node_modules/vike directories.
const { plugin: vikePlugin } = await Promise.resolve().then(() => __importStar(require('../vite/index.js')));
viteConfigFromUserEnhanced = {
...viteConfigFromUserEnhanced,
plugins: [...(viteConfigFromUserEnhanced?.plugins ?? []), vikePlugin()],
};
const res = findVikeVitePlugin(viteConfigFromUserEnhanced);
(0, utils_js_1.assert)(res);
vikeVitePluginOptions = res.vikeVitePluginOptions;
}
(0, utils_js_1.assert)(vikeVitePluginOptions);
return { root, vikeVitePluginOptions, viteConfigFromUserEnhanced };
}
function findVikeVitePlugin(viteConfig) {
let vikeVitePluginOptions;
let vikeVitePuginFound = false;
viteConfig?.plugins?.forEach((p) => {
if (p && '_vikeVitePluginOptions' in p) {
vikeVitePuginFound = true;
const options = p._vikeVitePluginOptions;
vikeVitePluginOptions ?? (vikeVitePluginOptions = {});
Object.assign(vikeVitePluginOptions, options);
}
});
if (!vikeVitePuginFound)
return null;
return { vikeVitePluginOptions };
}
// Copied from https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L961-L1005
async function loadViteConfigFile(viteConfigFromUserApiOptions, operation) {
const [inlineConfig, command, defaultMode, _defaultNodeEnv, isPreview] = getResolveConfigArgs(viteConfigFromUserApiOptions, operation);
let config = inlineConfig;
let mode = inlineConfig.mode || defaultMode;
const configEnv = {
mode,
command,
isSsrBuild: command === 'build' && !!config.build?.ssr,
isPreview,
};
let { configFile } = config;
if (configFile !== false) {
const loadResult = await (0, vite_1.loadConfigFromFile)(configEnv, configFile, config.root, config.logLevel, config.customLogger);
return loadResult?.config;
}
return null;
}
function getResolveConfigArgs(viteConfig = {}, operation) {
const inlineConfig = viteConfig;
const command = operation === 'build' || operation === 'prerender' ? 'build' : 'serve';
const defaultMode = operation === 'dev' ? 'development' : 'production';
const defaultNodeEnv = defaultMode;
const isPreview = operation === 'preview';
return [inlineConfig, command, defaultMode, defaultNodeEnv, isPreview];
}
function normalizeViteRoot(root) {
// `path.resolve(viteConfigFromUserViteFile.configFile, root)` could be more intuitive than `path.resolve(process.cwd(), root)` but we replicate Vite's behavior (`vite.config.js` should follow Vite's API), see:
// https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1063
return (0, utils_js_1.toPosixPath)(
// Equivalent to `path.resolve(process.cwd(), root)`
node_path_1.default.resolve(root));
}
const errMsg = `A Vite plugin is modifying Vite's setting ${picocolors_1.default.cyan('root')} which is forbidden`;
async function assertViteRoot2(root, viteConfigFromUserEnhanced, operation) {
const args = getResolveConfigArgs(viteConfigFromUserEnhanced, operation);
// We can eventually remove this resolveConfig() call (along with removing the whole assertViteRoot2() function which is redundant with the assertViteRoot() function) so that Vike doesn't make any resolveConfig() (except for pre-rendering and preview which is required). But let's keep it for now, just to see whether calling resolveConfig() can be problematic.
const viteConfigResolved = await (0, vite_1.resolveConfig)(...args);
(0, utils_js_1.assertUsage)(normalizeViteRoot(viteConfigResolved.root) === normalizeViteRoot(root), errMsg);
return { viteConfigResolved };
}
function assertViteRoot(root, config) {
if (globalObject.root)
(0, utils_js_1.assert)(normalizeViteRoot(globalObject.root) === normalizeViteRoot(root));
(0, utils_js_1.assertUsage)(normalizeViteRoot(root) === normalizeViteRoot(config.root), errMsg);
}