UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

214 lines (213 loc) 9.78 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.requireResolveOptional = requireResolveOptional; exports.requireResolveOptionalDir = requireResolveOptionalDir; exports.requireResolveNpmPackage = requireResolveNpmPackage; exports.requireResolveVikeDistFile = requireResolveVikeDistFile; exports.getVikeNodeModulesRoot = getVikeNodeModulesRoot; const assert_js_1 = require("./assert.js"); const assertIsNotBrowser_js_1 = require("./assertIsNotBrowser.js"); const assertSetup_js_1 = require("./assertSetup.js"); const path_js_1 = require("./path.js"); const isScriptFile_js_1 = require("./isScriptFile.js"); const node_module_1 = require("node:module"); const node_path_1 = __importDefault(require("node:path")); const parseNpmPackage_js_1 = require("./parseNpmPackage.js"); const isNullish_js_1 = require("./isNullish.js"); const debug_js_1 = require("./debug.js"); // @ts-ignore `file:///${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js. const importMetaUrl = `file:///${__filename.split('\\').join('/')}`; (0, path_js_1.assertPosixPath)(importMetaUrl); (0, assertIsNotBrowser_js_1.assertIsNotBrowser)(); (0, assertSetup_js_1.assertIsNotProductionRuntime)(); const debug = (0, debug_js_1.createDebugger)('vike:resolve'); // - We still can't use import.meta.resolve() as of 23.1.0 (November 2024) because `parent` argument requires an experimental flag. // - https://stackoverflow.com/questions/54977743/do-require-resolve-for-es-modules#comment139581675_62272600 // - Passing context to createRequire(context) isn't equivalent to passing it to the `paths` argument of require.resolve() // - https://github.com/brillout/require-test // - In practice, I guess it doesn't make a difference? It just seems to be small Node.js weirdness. // - The argument createRequire(argument) seems to be overridden by the `paths` argument require.resolve() // - For example, passing an empty array to `paths` kills the argument passed to `createRequire()` // - Thus, when `paths` is defined, then the context needs to be passed to both createRequire() as well as the `paths` argument of require.resolve() function requireResolve_(importPath, importerFilePath, userRootDir, doNotHandleFileExtension = false) { (0, path_js_1.assertPosixPath)(importPath); const contexts = importerFilePath ? [importerFilePath] : [userRootDir ? getFakeImporterFile(userRootDir) : importMetaUrl]; addExtraContextForNpmPackageImport(contexts, importPath, userRootDir); let importPathResolvedFilePath; let failure; for (const context of contexts) { (0, path_js_1.assertPosixPath)(context); const contextNode = makeNodeFriendly(ensureFilePrefix(context)); let importPathNode = makeNodeFriendly(importPath); const require_ = (0, node_module_1.createRequire)(contextNode); if (!doNotHandleFileExtension) { addFileExtensionsToRequireResolve(require_); importPathNode = removeFileExtension(importPathNode); } try { importPathResolvedFilePath = require_.resolve(importPathNode); } catch (err) { if (debug.isActivated) { const stack = new Error().stack; debug('ERROR', { err, importPath, context }, stack); } failure ?? (failure = { err }); } if (importPathResolvedFilePath) break; } if (!importPathResolvedFilePath) { (0, assert_js_1.assert)(failure); if (debug.isActivated) { debug('FAILURE', { importPath, importerFilePath, userRootDir, doNotHandleFileExtension, importMetaUrl, contexts, }); } return { importPathResolvedFilePath: undefined, err: failure.err, hasFailed: true }; } else { if (failure && debug.isActivated) { debug('SUCCESS', { importPath, contexts, }); } (0, assert_js_1.assert)(importPathResolvedFilePath); importPathResolvedFilePath = (0, path_js_1.toPosixPath)(importPathResolvedFilePath); return { importPathResolvedFilePath, err: undefined, hasFailed: false }; } } function requireResolveOptional({ importPath, importerFilePath, userRootDir, }) { const res = requireResolve_(importPath, importerFilePath, userRootDir); if (res.hasFailed) return null; return res.importPathResolvedFilePath; } function requireResolveOptionalDir({ importPath, importerDir, userRootDir, }) { const importerFilePath = getFakeImporterFile(importerDir); const res = requireResolve_(importPath, importerFilePath, userRootDir); if (res.hasFailed) return null; return res.importPathResolvedFilePath; } function requireResolveNpmPackage({ importPathNpmPackage, userRootDir, }) { (0, parseNpmPackage_js_1.assertIsImportPathNpmPackage)(importPathNpmPackage); const importerFilePath = getFakeImporterFile(userRootDir); const res = requireResolve_(importPathNpmPackage, importerFilePath, userRootDir); if (res.hasFailed) throw res.err; return res.importPathResolvedFilePath; } function requireResolveVikeDistFile(vikeDistFile) { const vikeNodeModulesRoot = getVikeNodeModulesRoot(); (0, path_js_1.assertPosixPath)(vikeNodeModulesRoot); (0, path_js_1.assertPosixPath)(vikeDistFile); const importPathResolvedFilePath = makeNodeFriendly(node_path_1.default.posix.join(vikeNodeModulesRoot, vikeDistFile)); // Double check { const res = requireResolve_(importPathResolvedFilePath, // No context needed: importPathResolvedFilePath is already resolved and absolute null, null, true); if (res.hasFailed) throw res.err; (0, assert_js_1.assert)(res.importPathResolvedFilePath === importPathResolvedFilePath); } return importPathResolvedFilePath; } function addExtraContextForNpmPackageImport(contexts, importPath, userRootDir) { // We should add extra context only for npm packages, but unfortunately we cannot always disambiguate between npm package imports and path aliases. if (!(0, parseNpmPackage_js_1.isImportPathNpmPackageOrPathAlias)(importPath)) return; const userRootDirFakeFile = userRootDir && getFakeImporterFile(userRootDir); [ // Workaround for monorepo resolve issue: https://github.com/vikejs/vike-react/pull/161/commits/dbaa6643e78015ac2797c237552800fef29b72a7 userRootDirFakeFile, // I can't think of a use case where this would be needed, but let's add one extra last chance to successfully resolve some complex monorepo setups importMetaUrl, ] .filter(isNullish_js_1.isNotNullish) .forEach((context) => { const alreadyHasContext = contexts.includes(context) || contexts.includes(ensureFilePrefix(context)); if (alreadyHasContext) return; contexts.push(context); }); } function removeFileExtension(importPath) { // Skip for Bun: https://github.com/vikejs/vike/issues/2204 //@ts-ignore if (typeof Bun !== 'undefined') { // https://bun.sh/guides/util/detect-bun (0, assert_js_1.assert)(process.versions.bun); return importPath; } for (const ext of isScriptFile_js_1.scriptFileExtensionList) { const suffix = `.${ext}`; if (importPath.endsWith(suffix)) { return importPath.slice(0, -1 * suffix.length); } } return importPath; } function addFileExtensionsToRequireResolve(require_) { const added = []; isScriptFile_js_1.scriptFileExtensionList.forEach((ext) => { (0, assert_js_1.assert)(!ext.includes('.')); ext = `.${ext}`; if (!require_.extensions[ext]) { require_.extensions[ext] = require_.extensions['.js']; added.push(ext); } }); } function getVikeNodeModulesRoot() { // [RELATIVE_PATH_FROM_DIST] Current file: vike/dist/esm/utils/requireResolve.js (0, assert_js_1.assert)(importMetaUrl.includes('/dist/esm/') || importMetaUrl.includes('/dist/cjs/')); const vikeNodeModulesRoot = node_path_1.default.posix.join(removeFilePrefix(importMetaUrl), '../../../../'); return vikeNodeModulesRoot; } function getFakeImporterFile(dirPath) { (0, path_js_1.assertPosixPath)(dirPath); (0, assert_js_1.assert)(!dirPath.startsWith('file')); // The file:// prefix is bogus when used with path.posix.join() const importerFilePath = node_path_1.default.posix.join(dirPath, 'fakeFileForNodeResolve.js'); return importerFilePath; } function ensureFilePrefix(filePath) { (0, path_js_1.assertPosixPath)(filePath); const filePrefix = getFilePrefix(); if (!filePath.startsWith(filePrefix)) { (0, assert_js_1.assert)(!filePath.startsWith('file')); filePath = filePrefix + filePath; } (0, assert_js_1.assert)(filePath.startsWith(filePrefix)); return filePath; } function removeFilePrefix(filePath) { const filePrefix = getFilePrefix(); if (filePath.startsWith(filePrefix)) { filePath = filePath.slice(filePrefix.length); } (0, assert_js_1.assert)(!filePath.startsWith('file')); return filePath; } function getFilePrefix() { let prefix = 'file://'; if (process.platform === 'win32') prefix += '/'; return prefix; } function makeNodeFriendly(filePath) { // https://github.com/vikejs/vike/issues/2436#issuecomment-2849145340 return decodeURIComponent(filePath); }