vike
Version:
The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.
178 lines (177 loc) • 8.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.importUserCode = importUserCode;
const vite_1 = require("vite");
const getVirtualFilePageConfigValuesAll_js_1 = require("./v1-design/virtual-files/getVirtualFilePageConfigValuesAll.js");
const getVirtualFileImportUserCode_js_1 = require("./getVirtualFileImportUserCode.js");
const utils_js_1 = require("../../utils.js");
const virtual_files_js_1 = require("../../../shared/virtual-files.js");
const virtualFilePageConfigValuesAll_js_1 = require("../../../shared/virtual-files/virtualFilePageConfigValuesAll.js");
const virtualFileImportUserCode_js_1 = require("../../../shared/virtual-files/virtualFileImportUserCode.js");
const getVikeConfig_js_1 = require("./v1-design/getVikeConfig.js");
const picocolors_1 = __importDefault(require("@brillout/picocolors"));
const loggerNotProd_js_1 = require("../../shared/loggerNotProd.js");
const getFilePath_js_1 = require("../../shared/getFilePath.js");
const globalContext_js_1 = require("../../../runtime/globalContext.js");
const crawlPlusFiles_js_1 = require("./v1-design/getVikeConfig/crawlPlusFiles.js");
function importUserCode() {
let config;
let vikeConfig;
return {
name: 'vike:importUserCode',
async configResolved(config_) {
vikeConfig = await (0, getVikeConfig_js_1.getVikeConfig)(config_);
config = config_;
// TODO/v1-release: remove
if (!(0, getVikeConfig_js_1.isV1Design)(config))
config.experimental.importGlobRestoreExtension = true;
},
resolveId(id) {
if ((0, virtual_files_js_1.isVirtualFileId)(id)) {
return (0, virtual_files_js_1.resolveVirtualFileId)(id);
}
},
async handleHotUpdate(ctx) {
try {
return await handleHotUpdate(ctx, config);
}
catch (err) {
// Vite swallows errors thrown by handleHotUpdate()
console.error(err);
throw err;
}
},
async load(id, options) {
if (!(0, virtual_files_js_1.isVirtualFileId)(id))
return undefined;
id = (0, virtual_files_js_1.getVirtualFileId)(id);
const isDev = config._isDev;
(0, utils_js_1.assert)(typeof isDev === 'boolean');
if ((0, virtualFilePageConfigValuesAll_js_1.isVirtualFileIdPageConfigValuesAll)(id)) {
const code = await (0, getVirtualFilePageConfigValuesAll_js_1.getVirtualFilePageConfigValuesAll)(id, isDev, config);
return code;
}
if ((0, virtualFileImportUserCode_js_1.isVirtualFileIdImportUserCode)(id)) {
const code = await (0, getVirtualFileImportUserCode_js_1.getVirtualFileImportUserCode)(id, options, vikeConfig, config, isDev);
return code;
}
},
configureServer(server) {
handleFileAddRemove(server, config);
}
};
}
function handleFileAddRemove(server, config) {
server.watcher.prependListener('add', (f) => listener(f, false));
server.watcher.prependListener('unlink', (f) => listener(f, true));
return;
async function listener(file, isRemove) {
file = (0, vite_1.normalizePath)(file);
if ((0, crawlPlusFiles_js_1.isPlusFile)(file) || (await isVikeConfigDependency(file, server.moduleGraph))?.modifiesVikeVirtualFiles) {
invalidateVikeVirtualFiles(server);
reloadConfig(file, config, isRemove ? 'removed' : 'created');
}
}
}
function invalidateVikeVirtualFiles(server) {
const vikeVirtualFiles = getVikeVirtualFiles(server);
vikeVirtualFiles.forEach((mod) => {
server.moduleGraph.invalidateModule(mod);
});
}
async function handleHotUpdate(ctx, config) {
const { file, server } = ctx;
const isVikeConfig = await isVikeConfigDependency(ctx.file, ctx.server.moduleGraph);
if (isVikeConfig) {
if (isVikeConfig.modifiesVikeVirtualFiles) {
/* Tailwind breaks this assertion, see https://github.com/vikejs/vike/discussions/1330#discussioncomment-7787238
const isViteModule = ctx.modules.length > 0
assert(!isViteModule)
*/
// Ensure server.ssrLoadModule() loads fresh Vike virtual files (`reloadConfig()` > `updateUserFiles()` > `server.ssrLoadModule()`)
invalidateVikeVirtualFiles(server);
reloadConfig(file, config, 'modified');
// Triggers a full page reload
const vikeVirtualFiles = getVikeVirtualFiles(server);
return vikeVirtualFiles;
}
else {
// Ensure we invalidate `file` *before* server.ssrLoadModule() in updateUserFiles()
// Vite already invalidates it, but possibly *after* handleHotUpdate() and thus after server.ssrLoadModule()
ctx.modules.forEach((mod) => server.moduleGraph.invalidateModule(mod));
(0, globalContext_js_1.updateUserFiles)();
}
}
}
async function isVikeConfigDependency(filePathAbsoluteFilesystem, moduleGraph) {
// Check config-only files, for example all pages/+config.js dependencies. (There aren't part of Vite's module graph.)
(0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
const vikeConfigObject = await (0, getVikeConfig_js_1.getVikeConfigOptional)();
if (vikeConfigObject) {
const { vikeConfigDependencies } = vikeConfigObject;
vikeConfigDependencies.forEach((f) => (0, utils_js_1.assertPosixPath)(f));
if (vikeConfigDependencies.has(filePathAbsoluteFilesystem))
return { modifiesVikeVirtualFiles: true };
}
// Check using Vite's module graph, for example all +htmlAttributes dependencies.
// Alternatively, simply call updateUserFiles() on every handleHotUpdate() call.
const importers = getImporters(filePathAbsoluteFilesystem, moduleGraph);
const isPlusValueFileDependency = Array.from(importers).some((importer) => importer.file && (0, crawlPlusFiles_js_1.isPlusFile)(importer.file));
if (isPlusValueFileDependency)
return { modifiesVikeVirtualFiles: false };
return null;
}
function reloadConfig(filePath, config, op) {
{
const filePathToShowToUserResolved = (0, getFilePath_js_1.getModuleFilePathAbsolute)(filePath, config);
const msg = `${op} ${picocolors_1.default.dim(filePathToShowToUserResolved)}`;
(0, loggerNotProd_js_1.logConfigInfo)(msg, 'info');
}
(0, getVikeConfig_js_1.reloadVikeConfig)(config);
(0, globalContext_js_1.updateUserFiles)();
}
function getVikeVirtualFiles(server) {
const vikeVirtualFiles = Array.from(server.moduleGraph.urlToModuleMap.keys())
.filter((url) => (0, virtualFilePageConfigValuesAll_js_1.isVirtualFileIdPageConfigValuesAll)(url) || (0, virtualFileImportUserCode_js_1.isVirtualFileIdImportUserCode)(url))
.map((url) => {
const mod = server.moduleGraph.urlToModuleMap.get(url);
(0, utils_js_1.assert)(mod);
return mod;
});
return vikeVirtualFiles;
}
// Get all transitive importers (including the module itself)
function getImporters(file, moduleGraph) {
const importers = new Set();
const mods = moduleGraph.getModulesByFile(file);
if (!mods)
return importers;
for (const mod of mods) {
getModuleImporters(mod).forEach((importer) => {
if (importer)
importers.add(importer);
});
}
return importers;
}
function getModuleImporters(mod, seen = new Set()) {
if (seen.has(mod))
return new Set();
seen.add(mod);
const importers = new Set();
if (mod.id)
importers.add(mod);
// Traverse through the importers (modules that import this module)
for (const importer of mod.importers) {
if (importer.id)
importers.add(importer);
getModuleImporters(importer, seen).forEach((importerTransitive) => {
if (importerTransitive)
importers.add(importerTransitive);
});
}
return importers;
}