UNPKG

rolldown-require

Version:
1,563 lines (1,541 loc) 48.1 kB
// src/bundler.ts import path6 from "path"; import { pathToFileURL as pathToFileURL2 } from "url"; import { rolldown } from "rolldown"; // src/collect.ts function collectReferencedModules(bundle, fileName, allModules, analyzedModules = /* @__PURE__ */ new Set()) { if (analyzedModules.has(fileName)) { return; } analyzedModules.add(fileName); const chunk = bundle[fileName]; if (!chunk) { return; } for (const mod of chunk.moduleIds) { allModules.add(mod); } for (const imported of chunk.imports) { collectReferencedModules(bundle, imported, allModules, analyzedModules); } for (const imported of chunk.dynamicImports) { collectReferencedModules(bundle, imported, allModules, analyzedModules); } } // src/externalize.ts import fs4 from "fs"; import { createRequire as createRequire3 } from "module"; import path5 from "path"; import { pathToFileURL } from "url"; // src/config.ts var configDefaults = Object.freeze({ resolve: { extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json"] } }); var defaultGetOutputFile = (filepath, _format) => { return filepath; }; // src/plugins/resolve.ts import fs3 from "fs"; import path4 from "path"; import { hasESMSyntax } from "mlly"; import { exports, imports } from "resolve.exports"; // src/constants.ts import { readFileSync } from "fs"; var { version } = JSON.parse( readFileSync(new URL("../package.json", import.meta.url)).toString() ); var DEV_PROD_CONDITION = `development|production`; var OPTIMIZABLE_ENTRY_RE = /\.[cm]?[jt]s$/; var SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/; // src/external.ts import path from "path"; function canExternalizeFile(filePath) { const ext = path.extname(filePath); return !ext || ext === ".js" || ext === ".mjs" || ext === ".cjs"; } // src/packages.ts import fs2 from "fs"; import { createRequire as createRequire2 } from "module"; import path3 from "path"; import process3 from "process"; // src/utils.ts import { exec } from "child_process"; import fs from "fs"; import { builtinModules, createRequire } from "module"; import path2 from "path"; import process2 from "process"; import { createFilter as _createFilter } from "@rollup/pluginutils"; // src/sharedUtils.ts import process from "process"; var isWindows = typeof process !== "undefined" && process.platform === "win32"; var windowsSlashRE = /\\/g; function slash(p) { return p.replace(windowsSlashRE, "/"); } var postfixRE = /[?#].*$/; function cleanUrl(url) { return url.replace(postfixRE, ""); } function splitFileAndPostfix(path11) { const file = cleanUrl(path11); return { file, postfix: path11.slice(file.length) }; } // src/utils.ts var createFilter = _createFilter; var NODE_BUILTIN_NAMESPACE = "node:"; var NPM_BUILTIN_NAMESPACE = "npm:"; var BUN_BUILTIN_NAMESPACE = "bun:"; var nodeBuiltins = builtinModules.filter((id) => !id.includes(":")); var isBuiltinCache = /* @__PURE__ */ new WeakMap(); function isBuiltin(builtins, id) { let isBuiltin2 = isBuiltinCache.get(builtins); if (!isBuiltin2) { isBuiltin2 = createIsBuiltin(builtins); isBuiltinCache.set(builtins, isBuiltin2); } return isBuiltin2(id); } function createIsBuiltin(builtins) { const plainBuiltinsSet = new Set( builtins.filter((builtin) => typeof builtin === "string") ); const regexBuiltins = builtins.filter( (builtin) => typeof builtin !== "string" ); return (id) => plainBuiltinsSet.has(id) || regexBuiltins.some((regexp) => regexp.test(id)); } var nodeLikeBuiltins = [ ...nodeBuiltins, new RegExp(`^${NODE_BUILTIN_NAMESPACE}`), new RegExp(`^${NPM_BUILTIN_NAMESPACE}`), new RegExp(`^${BUN_BUILTIN_NAMESPACE}`) ]; function isNodeLikeBuiltin(id) { return isBuiltin(nodeLikeBuiltins, id); } function isNodeBuiltin(id) { if (id.startsWith(NODE_BUILTIN_NAMESPACE)) { return true; } return nodeBuiltins.includes(id); } function isInNodeModules(id) { return id.includes("node_modules"); } function isOptimizable(id, optimizeDeps) { const { extensions } = optimizeDeps; return OPTIMIZABLE_ENTRY_RE.test(id) || (extensions?.some((ext) => id.endsWith(ext)) ?? false); } var bareImportRE = /^(?![a-z]:)[\w@](?!.*:\/\/)/i; var deepImportRE = /^([^@][^/]*)\/|^(@[^/]+\/[^/]+)\//; function normalizePath(id) { return path2.posix.normalize(isWindows ? slash(id) : id); } function injectQuery(url, queryToInject) { const { file, postfix } = splitFileAndPostfix(url); const normalizedFile = isWindows ? slash(file) : file; return `${normalizedFile}?${queryToInject}${postfix[0] === "?" ? `&${postfix.slice(1)}` : ( /* hash only */ postfix )}`; } function isObject(value) { return Object.prototype.toString.call(value) === "[object Object]"; } function tryStatSync(file) { try { return fs.statSync(file, { throwIfNoEntry: false }); } catch { } } function isFilePathESM(filePath, packageCache) { if (/\.m[jt]s$/.test(filePath)) { return true; } else if (/\.c[jt]s$/.test(filePath)) { return false; } else { try { const pkg = findNearestPackageData(path2.dirname(filePath), packageCache); return pkg?.data.type === "module"; } catch { return false; } } } var currentSafeRealpathSync = isWindows ? windowsSafeRealPathSync : fs.realpathSync.native; function safeRealpathSync(filePath) { return currentSafeRealpathSync(filePath); } var windowsNetworkMap = /* @__PURE__ */ new Map(); function windowsMappedRealpathSync(path11) { const realPath = fs.realpathSync.native(path11); if (realPath.startsWith("\\\\")) { for (const [network, volume] of windowsNetworkMap) { if (realPath.startsWith(network)) { return realPath.replace(network, volume); } } } return realPath; } var parseNetUseRE = /^\w* +(\w:) +([^ ]+)\s/; var firstSafeRealPathSyncRun = false; function windowsSafeRealPathSync(path11) { if (!firstSafeRealPathSyncRun) { optimizeSafeRealPathSync(); firstSafeRealPathSyncRun = true; } return fs.realpathSync(path11); } function optimizeSafeRealPathSync() { const nodeVersion = process2.versions.node.split(".").map(Number); if (nodeVersion[0] < 18 || nodeVersion[0] === 18 && nodeVersion[1] < 10) { currentSafeRealpathSync = fs.realpathSync; return; } try { fs.realpathSync.native(path2.resolve("./")); } catch (error) { if (error.message.includes("EISDIR: illegal operation on a directory")) { currentSafeRealpathSync = fs.realpathSync; return; } } exec("net use", (error, stdout) => { if (error) { return; } const lines = stdout.split("\n"); for (const line of lines) { const m = parseNetUseRE.exec(line); if (m) { windowsNetworkMap.set(m[2], m[1]); } } currentSafeRealpathSync = windowsNetworkMap.size === 0 ? fs.realpathSync.native : windowsMappedRealpathSync; }); } function stripBomTag(content) { if (content.charCodeAt(0) === 65279) { return content.slice(1); } return content; } function getNpmPackageName(importPath) { const parts = importPath.split("/"); if (parts[0][0] === "@") { if (!parts[1]) { return null; } return `${parts[0]}/${parts[1]}`; } else { return parts[0]; } } var dynamicImport = async (id, { format }) => { const fn = format === "esm" ? (file) => import(file) : true ? createRequire(import.meta.url) : __require; return fn(id); }; // src/packages.ts var pnp; if (process3.versions.pnp) { try { pnp = createRequire2(import.meta.url)("pnpapi"); } catch { } } function resolvePackageData(pkgName, basedir, preserveSymlinks = false, packageCache) { if (pnp) { const cacheKey = getRpdCacheKey(pkgName, basedir, preserveSymlinks); if (packageCache?.has(cacheKey)) { return packageCache.get(cacheKey); } try { const pkg = pnp.resolveToUnqualified(pkgName, basedir, { considerBuiltins: false }); if (!pkg) { return null; } const pkgData = loadPackageData(path3.join(pkg, "package.json")); packageCache?.set(cacheKey, pkgData); return pkgData; } catch { return null; } } const originalBasedir = basedir; while (basedir) { if (packageCache) { const cached = getRpdCache( packageCache, pkgName, basedir, originalBasedir, preserveSymlinks ); if (cached) { return cached; } } const pkg = path3.join(basedir, "node_modules", pkgName, "package.json"); try { if (fs2.existsSync(pkg)) { const pkgPath = preserveSymlinks ? pkg : safeRealpathSync(pkg); const pkgData = loadPackageData(pkgPath); if (packageCache) { setRpdCache( packageCache, pkgData, pkgName, basedir, originalBasedir, preserveSymlinks ); } return pkgData; } } catch { } const nextBasedir = path3.dirname(basedir); if (nextBasedir === basedir) { break; } basedir = nextBasedir; } return null; } function findNearestPackageData(basedir, packageCache) { const originalBasedir = basedir; while (basedir) { if (packageCache) { const cached = getFnpdCache(packageCache, basedir, originalBasedir); if (cached) { return cached; } } const pkgPath = path3.join(basedir, "package.json"); if (tryStatSync(pkgPath)?.isFile()) { try { const pkgData = loadPackageData(pkgPath); if (packageCache) { setFnpdCache(packageCache, pkgData, basedir, originalBasedir); } return pkgData; } catch { } } const nextBasedir = path3.dirname(basedir); if (nextBasedir === basedir) { break; } basedir = nextBasedir; } return null; } function findNearestMainPackageData(basedir, packageCache) { const nearestPackage = findNearestPackageData(basedir, packageCache); return nearestPackage && (nearestPackage.data.name ? nearestPackage : findNearestMainPackageData( path3.dirname(nearestPackage.dir), packageCache )); } function loadPackageData(pkgPath) { const data = JSON.parse(stripBomTag(fs2.readFileSync(pkgPath, "utf-8"))); const pkgDir = normalizePath(path3.dirname(pkgPath)); const { sideEffects } = data; let hasSideEffects; if (typeof sideEffects === "boolean") { hasSideEffects = () => sideEffects; } else if (Array.isArray(sideEffects)) { if (sideEffects.length <= 0) { hasSideEffects = () => false; } else { const finalPackageSideEffects = sideEffects.map((sideEffect) => { if (sideEffect.includes("/")) { return sideEffect; } return `**/${sideEffect}`; }); hasSideEffects = createFilter(finalPackageSideEffects, null, { resolve: pkgDir }); } } else { hasSideEffects = () => null; } const resolvedCache = {}; const pkg = { dir: pkgDir, data, hasSideEffects, setResolvedCache(key, entry, options) { resolvedCache[getResolveCacheKey(key, options)] = entry; }, getResolvedCache(key, options) { return resolvedCache[getResolveCacheKey(key, options)]; } }; return pkg; } function getResolveCacheKey(key, options) { return [ key, options.isRequire ? "1" : "0", options.conditions.join("_"), options.extensions.join("_"), options.mainFields.join("_") ].join("|"); } function findNearestNodeModules(basedir) { while (basedir) { const pkgPath = path3.join(basedir, "node_modules"); if (tryStatSync(pkgPath)?.isDirectory()) { return pkgPath; } const nextBasedir = path3.dirname(basedir); if (nextBasedir === basedir) { break; } basedir = nextBasedir; } return null; } function getRpdCache(packageCache, pkgName, basedir, originalBasedir, preserveSymlinks) { const cacheKey = getRpdCacheKey(pkgName, basedir, preserveSymlinks); const pkgData = packageCache.get(cacheKey); if (pkgData) { traverseBetweenDirs(originalBasedir, basedir, (dir) => { packageCache.set(getRpdCacheKey(pkgName, dir, preserveSymlinks), pkgData); }); return pkgData; } } function setRpdCache(packageCache, pkgData, pkgName, basedir, originalBasedir, preserveSymlinks) { packageCache.set(getRpdCacheKey(pkgName, basedir, preserveSymlinks), pkgData); traverseBetweenDirs(originalBasedir, basedir, (dir) => { packageCache.set(getRpdCacheKey(pkgName, dir, preserveSymlinks), pkgData); }); } function getRpdCacheKey(pkgName, basedir, preserveSymlinks) { return `rpd_${pkgName}_${basedir}_${preserveSymlinks}`; } function getFnpdCache(packageCache, basedir, originalBasedir) { const cacheKey = getFnpdCacheKey(basedir); const pkgData = packageCache.get(cacheKey); if (pkgData) { traverseBetweenDirs(originalBasedir, basedir, (dir) => { packageCache.set(getFnpdCacheKey(dir), pkgData); }); return pkgData; } } function setFnpdCache(packageCache, pkgData, basedir, originalBasedir) { packageCache.set(getFnpdCacheKey(basedir), pkgData); traverseBetweenDirs(originalBasedir, basedir, (dir) => { packageCache.set(getFnpdCacheKey(dir), pkgData); }); } function getFnpdCacheKey(basedir) { return `fnpd_${basedir}`; } function traverseBetweenDirs(longerDir, shorterDir, cb) { while (longerDir !== shorterDir) { cb(longerDir); longerDir = path3.dirname(longerDir); } } // src/plugins/resolve.ts var ERR_RESOLVE_PACKAGE_ENTRY_FAIL = "ERR_RESOLVE_PACKAGE_ENTRY_FAIL"; var browserExternalId = "__vite-browser-external"; var optionalPeerDepId = "__vite-optional-peer-dep"; function tryFsResolve(fsPath, options, tryIndex = true, skipPackageJson = false) { const hashIndex = fsPath.indexOf("#"); if (hashIndex >= 0 && isInNodeModules(fsPath)) { const queryIndex = fsPath.indexOf("?"); if (queryIndex < 0 || queryIndex > hashIndex) { const file2 = queryIndex > hashIndex ? fsPath.slice(0, queryIndex) : fsPath; const res2 = tryCleanFsResolve(file2, options, tryIndex, skipPackageJson); if (res2) { return res2 + fsPath.slice(file2.length); } } } const { file, postfix } = splitFileAndPostfix(fsPath); const res = tryCleanFsResolve(file, options, tryIndex, skipPackageJson); if (res) { return res + postfix; } } var knownTsOutputRE = /\.(?:js|mjs|cjs|jsx)$/; var isPossibleTsOutput = (url) => knownTsOutputRE.test(url); function tryCleanFsResolve(file, options, tryIndex = true, skipPackageJson = false) { const { tryPrefix, extensions, preserveSymlinks } = options; const fileResult = tryResolveRealFileOrType(file, options.preserveSymlinks); if (fileResult?.path) { return fileResult.path; } let res; const possibleJsToTs = isPossibleTsOutput(file); if (possibleJsToTs || options.extensions.length || tryPrefix) { const dirPath = path4.dirname(file); if (isDirectory(dirPath)) { if (possibleJsToTs) { const fileExt = path4.extname(file); const fileName = file.slice(0, -fileExt.length); if (res = tryResolveRealFile( fileName + fileExt.replace("js", "ts"), preserveSymlinks )) { return res; } if (fileExt === ".js" && (res = tryResolveRealFile(`${fileName}.tsx`, preserveSymlinks))) { return res; } } if (res = tryResolveRealFileWithExtensions( file, extensions, preserveSymlinks )) { return res; } if (tryPrefix) { const prefixed = `${dirPath}/${options.tryPrefix}${path4.basename(file)}`; if (res = tryResolveRealFile(prefixed, preserveSymlinks)) { return res; } if (res = tryResolveRealFileWithExtensions( prefixed, extensions, preserveSymlinks )) { return res; } } } } if (tryIndex && fileResult?.type === "directory") { const dirPath = file; if (!skipPackageJson) { let pkgPath = `${dirPath}/package.json`; try { if (fs3.existsSync(pkgPath)) { if (!options.preserveSymlinks) { pkgPath = safeRealpathSync(pkgPath); } const pkg = loadPackageData(pkgPath); return resolvePackageEntry(dirPath, pkg, options); } } catch (e) { if (e.code !== ERR_RESOLVE_PACKAGE_ENTRY_FAIL && e.code !== "ENOENT") { throw e; } } } if (res = tryResolveRealFileWithExtensions( `${dirPath}/index`, extensions, preserveSymlinks )) { return res; } if (tryPrefix) { if (res = tryResolveRealFileWithExtensions( `${dirPath}/${options.tryPrefix}index`, extensions, preserveSymlinks )) { return res; } } } } function tryNodeResolve(id, importer, options, depsOptimizer, externalize) { const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options; const deepMatch = deepImportRE.exec(id); const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : cleanUrl(id); let basedir; if (dedupe.includes(pkgId)) { basedir = root; } else if (importer && path4.isAbsolute(importer) && (importer.endsWith("*") || fs3.existsSync(cleanUrl(importer)))) { basedir = path4.dirname(importer); } else { basedir = root; } const isModuleBuiltin = (id2) => isBuiltin(options.builtins, id2); let selfPkg = null; if (!isModuleBuiltin(id) && !id.includes("\0") && bareImportRE.test(id)) { const selfPackageData = findNearestPackageData(basedir, packageCache); selfPkg = selfPackageData?.data.exports && selfPackageData.data.name === pkgId ? selfPackageData : null; } const pkg = selfPkg || resolvePackageData(pkgId, basedir, preserveSymlinks, packageCache); if (!pkg) { if (basedir !== root && !isModuleBuiltin(id) && !id.includes("\0") && bareImportRE.test(id)) { const mainPkg = findNearestMainPackageData(basedir, packageCache)?.data; if (mainPkg) { const pkgName = getNpmPackageName(id); if (pkgName != null && mainPkg.peerDependencies?.[pkgName] && mainPkg.peerDependenciesMeta?.[pkgName]?.optional) { return { id: `${optionalPeerDepId}:${id}:${mainPkg.name}` }; } } } return; } const resolveId = deepMatch ? resolveDeepImport : resolvePackageEntry; const unresolvedId = deepMatch ? `.${id.slice(pkgId.length)}` : id; let resolved = resolveId(unresolvedId, pkg, options); if (!resolved) { return; } const processResult = (resolved2) => { if (!externalize) { return resolved2; } if (!canExternalizeFile(resolved2.id)) { return resolved2; } let resolvedId = id; if (deepMatch && !pkg.data.exports && path4.extname(id) !== path4.extname(resolved2.id)) { const index = resolved2.id.indexOf(id); if (index > -1) { resolvedId = resolved2.id.slice(index); } } return { ...resolved2, id: resolvedId, external: true }; }; if (!options.idOnly && (!options.scan && isBuild || externalize)) { return processResult({ id: resolved, moduleSideEffects: pkg.hasSideEffects(resolved) }); } if (!isInNodeModules(resolved) || !depsOptimizer || options.scan) { return { id: resolved }; } const isJsType = isOptimizable(resolved, depsOptimizer.options); const exclude = depsOptimizer.options.exclude; const skipOptimization = depsOptimizer.options.noDiscovery || !isJsType || importer && isInNodeModules(importer) || exclude?.includes(pkgId) || exclude?.includes(id) || SPECIAL_QUERY_RE.test(resolved); if (skipOptimization) { const versionHash = depsOptimizer.metadata.browserHash; if (versionHash && isJsType) { resolved = injectQuery(resolved, `v=${versionHash}`); } } else { const optimizedInfo = depsOptimizer.registerMissingImport(id, resolved); resolved = depsOptimizer.getOptimizedDepId(optimizedInfo); } return { id: resolved }; } function resolvePackageEntry(id, { dir, data, setResolvedCache, getResolvedCache }, options) { const { postfix } = splitFileAndPostfix(id); const cached = getResolvedCache(".", options); if (cached) { return cached + postfix; } try { let entryPoint; if (data.exports) { entryPoint = resolveExportsOrImports(data, ".", options, "exports"); } if (!entryPoint) { for (const field of options.mainFields) { if (field === "browser") { entryPoint = tryResolveBrowserEntry(dir, data, options); if (entryPoint) { break; } } else if (typeof data[field] === "string") { entryPoint = data[field]; break; } } } entryPoint ||= data.main; const entryPoints = entryPoint ? [entryPoint] : ["index.js", "index.json", "index.node"]; for (let entry of entryPoints) { let skipPackageJson = false; if (options.mainFields[0] === "sass" && !options.extensions.includes(path4.extname(entry))) { entry = ""; skipPackageJson = true; } else { const { browser: browserField } = data; if (options.mainFields.includes("browser") && isObject(browserField)) { entry = mapWithBrowserField(entry, browserField) || entry; } } const entryPointPath = path4.join(dir, entry); const resolvedEntryPoint = tryFsResolve( entryPointPath, options, true, skipPackageJson ); if (resolvedEntryPoint) { setResolvedCache(".", resolvedEntryPoint, options); return resolvedEntryPoint + postfix; } } } catch (e) { packageEntryFailure( id, // @ts-ignore e.message ); } packageEntryFailure(id); } function packageEntryFailure(id, details) { const err = new Error( `Failed to resolve entry for package "${id}". The package may have incorrect main/module/exports specified in its package.json${details ? `: ${details}` : "."}` ); err.code = ERR_RESOLVE_PACKAGE_ENTRY_FAIL; throw err; } function getConditions(conditions, isProduction, isRequire) { const resolvedConditions = conditions.map((condition) => { if (condition === DEV_PROD_CONDITION) { return isProduction ? "production" : "development"; } return condition; }); if (isRequire) { resolvedConditions.push("require"); } else { resolvedConditions.push("import"); } return resolvedConditions; } function resolveExportsOrImports(pkg, key, options, type) { const conditions = getConditions( options.conditions, options.isProduction, options.isRequire ); const fn = type === "imports" ? imports : exports; const result = fn(pkg, key, { conditions, unsafe: true }); return result ? result[0] : void 0; } function resolveDeepImport(id, { setResolvedCache, getResolvedCache, dir, data }, options) { const cache = getResolvedCache(id, options); if (cache) { return cache; } let relativeId = id; const { exports: exportsField, browser: browserField } = data; if (exportsField) { if (isObject(exportsField) && !Array.isArray(exportsField)) { const { file, postfix } = splitFileAndPostfix(relativeId); const exportsId = resolveExportsOrImports(data, file, options, "exports"); if (exportsId !== void 0) { relativeId = exportsId + postfix; } else { relativeId = void 0; } } else { relativeId = void 0; } if (!relativeId) { throw new Error( `Package subpath '${relativeId}' is not defined by "exports" in ${path4.join(dir, "package.json")}.` ); } } else if (options.mainFields.includes("browser") && isObject(browserField)) { const { file, postfix } = splitFileAndPostfix(relativeId); const mapped = mapWithBrowserField(file, browserField); if (mapped) { relativeId = mapped + postfix; } else if (mapped === false) { setResolvedCache(id, browserExternalId, options); return browserExternalId; } } if (relativeId) { const resolved = tryFsResolve( path4.join(dir, relativeId), options, !exportsField // try index only if no exports field ); if (resolved) { setResolvedCache(id, resolved, options); return resolved; } } } function tryResolveBrowserEntry(dir, data, options) { const browserEntry = typeof data.browser === "string" ? data.browser : isObject(data.browser) && data.browser["."]; if (browserEntry) { if (!options.isRequire && options.mainFields.includes("module") && typeof data.module === "string" && data.module !== browserEntry) { const resolvedBrowserEntry = tryFsResolve( path4.join(dir, browserEntry), options ); if (resolvedBrowserEntry) { const content = fs3.readFileSync(resolvedBrowserEntry, "utf-8"); if (hasESMSyntax(content)) { return browserEntry; } else { return data.module; } } } else { return browserEntry; } } } function mapWithBrowserField(relativePathInPkgDir, map) { const normalizedPath = path4.posix.normalize(relativePathInPkgDir); for (const key in map) { const normalizedKey = path4.posix.normalize(key); if (normalizedPath === normalizedKey || equalWithoutSuffix(normalizedPath, normalizedKey, ".js") || equalWithoutSuffix(normalizedPath, normalizedKey, "/index.js")) { return map[key]; } } } function equalWithoutSuffix(path11, key, suffix) { return key.endsWith(suffix) && key.slice(0, -suffix.length) === path11; } function tryResolveRealFile(file, preserveSymlinks) { const stat = tryStatSync(file); if (stat?.isFile()) { return getRealPath(file, preserveSymlinks); } } function tryResolveRealFileWithExtensions(filePath, extensions, preserveSymlinks) { for (const ext of extensions) { const res = tryResolveRealFile(filePath + ext, preserveSymlinks); if (res) { return res; } } } function tryResolveRealFileOrType(file, preserveSymlinks) { const fileStat = tryStatSync(file); if (fileStat?.isFile()) { return { path: getRealPath(file, preserveSymlinks), type: "file" }; } if (fileStat?.isDirectory()) { return { type: "directory" }; } } function getRealPath(resolved, preserveSymlinks) { if (!preserveSymlinks) { resolved = safeRealpathSync(resolved); } return normalizePath(resolved); } function isDirectory(path11) { const stat = tryStatSync(path11); return stat?.isDirectory() ?? false; } // src/externalize.ts function createExternalizeDepsPlugin({ entryFile, isESM, moduleSyncEnabled }) { const entryDir = path5.dirname(entryFile); const packageCache = /* @__PURE__ */ new Map(); const resolveByViteResolver = (id, importer, isRequire) => { return tryNodeResolve(id, importer, { root: path5.dirname(entryFile), isBuild: true, isProduction: true, preferRelative: false, tryIndex: true, mainFields: [], conditions: [ "node", ...moduleSyncEnabled ? ["module-sync"] : [] ], externalConditions: [], external: [], noExternal: [], dedupe: [], extensions: configDefaults.resolve.extensions, preserveSymlinks: false, packageCache, isRequire, builtins: nodeLikeBuiltins })?.id; }; return { name: "externalize-deps", resolveId: { filter: { id: /^[^.#].*/ }, async handler(id, importer, { kind }) { if (!importer || path5.isAbsolute(id) || isNodeBuiltin(id)) { return; } if (isNodeLikeBuiltin(id)) { return { id, external: true }; } const isImport = isESM || kind === "dynamic-import"; let idFsPath; try { idFsPath = resolveByViteResolver(id, importer, !isImport); } catch (e) { if (!isImport) { let canResolveWithImport = false; try { canResolveWithImport = !!resolveByViteResolver( id, importer, false ); } catch { } if (canResolveWithImport) { throw new Error( `Failed to resolve ${JSON.stringify( id )}. This package is ESM only but it was tried to load by \`require\`. See https://vite.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.` ); } } throw e; } if (!idFsPath) { return; } if (idFsPath.endsWith(".json")) { return idFsPath; } const shouldExternalize = shouldExternalizeBareImport(id, importer, entryDir); if (idFsPath && isImport && shouldExternalize) { idFsPath = pathToFileURL(idFsPath).href; } return { id: idFsPath, external: shouldExternalize }; } } }; } function shouldExternalizeBareImport(specifier, importer, entryDir) { if (!specifier || specifier.startsWith(".") || path5.isAbsolute(specifier)) { return false; } if (isNodeLikeBuiltin(specifier)) { return true; } const importerPath = normalizeImporterPath(importer, entryDir); try { const containingNodeModules = findContainingNodeModules( createRequire3(importerPath).resolve(specifier) ); if (containingNodeModules) { const ownerDir = path5.dirname(containingNodeModules); const ownerInsideEntry = isPathWithinDirectory(entryDir, ownerDir); const entryInsideOwner = isPathWithinDirectory(ownerDir, entryDir); if (ownerInsideEntry && !entryInsideOwner) { return false; } } } catch { } if (!canResolveFromEntry(specifier, entryDir)) { return false; } return true; } function normalizeImporterPath(importer, fallback) { if (!importer || importer.startsWith("\0")) { return fallback; } const [withoutQuery] = importer.split("?"); return withoutQuery || fallback; } function findContainingNodeModules(filePath) { let current = path5.dirname(filePath); const { root } = path5.parse(current); while (true) { if (path5.basename(current) === "node_modules") { return current; } if (current === root) { break; } current = path5.dirname(current); } } function isPathWithinDirectory(parent, child) { const relative = path5.relative(parent, child); return relative === "" || !relative.startsWith("..") && !path5.isAbsolute(relative); } function getPackageName(specifier) { if (!specifier) { return void 0; } if (specifier.startsWith("@")) { const segments = specifier.split("/"); if (segments.length >= 2) { return `${segments[0]}/${segments[1]}`; } return void 0; } const [name] = specifier.split("/"); return name || void 0; } function canResolveFromEntry(specifier, entryDir) { const packageName = getPackageName(specifier); if (!packageName) { return false; } let currentDir = entryDir; while (true) { if (fs4.existsSync(path5.join(currentDir, "node_modules", packageName))) { return true; } const parentDir = path5.dirname(currentDir); if (parentDir === currentDir) { break; } currentDir = parentDir; } return false; } // src/module-sync.ts var cachedModuleSyncCondition; var moduleSyncConditionPromise; async function getModuleSyncConditionEnabled() { if (cachedModuleSyncCondition !== void 0) { return cachedModuleSyncCondition; } if (!moduleSyncConditionPromise) { moduleSyncConditionPromise = import( // @ts-ignore "#module-sync-enabled" ).then((mod) => Boolean(mod?.default)).catch(() => false).then((result) => { cachedModuleSyncCondition = result; return result; }).finally(() => { moduleSyncConditionPromise = void 0; }); } return moduleSyncConditionPromise; } // src/bundler.ts async function bundleFile(fileName, options) { const { isESM } = options; const moduleSyncEnabled = await getModuleSyncConditionEnabled(); const dirnameVarName = "__vite_injected_original_dirname"; const filenameVarName = "__vite_injected_original_filename"; const importMetaUrlVarName = "__vite_injected_original_import_meta_url"; const rolldownInputOptions = options?.rolldownOptions?.input || {}; const { transform: userTransform, resolve: userResolve, ...restRolldownInputOptions } = rolldownInputOptions; const transformDefine = { ...userTransform?.define ?? {}, "__dirname": dirnameVarName, "__filename": filenameVarName, "import.meta.url": importMetaUrlVarName, "import.meta.dirname": dirnameVarName, "import.meta.filename": filenameVarName }; const transformOptions = { ...userTransform ?? {}, define: transformDefine }; const resolveOptions = { ...userResolve ?? {}, mainFields: ["main"], tsconfigFilename: options.tsconfig }; const originalConsoleWarn = console.warn; console.warn = (...args) => { const message = typeof args[0] === "string" ? args[0] : ""; if (message.includes("resolve.tsconfigFilename") || message.includes("Invalid input options") || message.includes('top-level "define" option is deprecated')) { return; } originalConsoleWarn(...args); }; let bundle; try { bundle = await rolldown({ ...restRolldownInputOptions, input: fileName, platform: "node", resolve: resolveOptions, // @ts-ignore define: transformDefine, transform: transformOptions, // disable treeshake to include files that is not sideeffectful to `moduleIds` treeshake: false, plugins: [ createExternalizeDepsPlugin({ entryFile: fileName, isESM, moduleSyncEnabled }), createFileScopeVariablesPlugin({ dirnameVarName, filenameVarName, importMetaUrlVarName }) ], external: options.external }); } finally { console.warn = originalConsoleWarn; } if (!bundle) { throw new Error("Failed to initialize bundler"); } const rolldownOutputOptions = options?.rolldownOptions?.output || {}; const result = await bundle.generate({ ...rolldownOutputOptions, format: options.format, sourcemap: false, inlineDynamicImports: true }); await bundle.close(); const entryChunk = result.output.find( (chunk) => chunk.type === "chunk" && chunk.isEntry ); const bundleChunks = Object.fromEntries( result.output.flatMap((c) => c.type === "chunk" ? [[c.fileName, c]] : []) ); const allModules = /* @__PURE__ */ new Set(); collectReferencedModules(bundleChunks, entryChunk.fileName, allModules); allModules.delete(fileName); return { code: entryChunk.code, dependencies: [...allModules] }; } function createFileScopeVariablesPlugin({ dirnameVarName, filenameVarName, importMetaUrlVarName }) { return { name: "inject-file-scope-variables", transform: { filter: { id: /\.[cm]?[jt]s$/ }, async handler(code, id) { const injectValues = `const ${dirnameVarName} = ${JSON.stringify(path6.dirname(id))};const ${filenameVarName} = ${JSON.stringify(id)};const ${importMetaUrlVarName} = ${JSON.stringify( pathToFileURL2(id).href )};`; return { code: injectValues + code, map: null }; } } }; } // src/loader.ts import fs6 from "fs"; import { createRequire as createRequire5 } from "module"; import path9 from "path"; import { promisify } from "util"; // src/cache.ts import crypto from "crypto"; import fs5 from "fs"; import fsp from "fs/promises"; import { createRequire as createRequire4 } from "module"; import os from "os"; import path7 from "path"; import process4 from "process"; import { pathToFileURL as pathToFileURL3 } from "url"; var _require = createRequire4(import.meta.url); var memoryCache = /* @__PURE__ */ new Map(); function resolveCacheOptions(fileName, options) { const cacheOpt = options.cache; const enabled = cacheOpt === true || typeof cacheOpt === "object" && cacheOpt.enabled !== false; if (!enabled) { return { enabled: false, key: "", dir: "", reset: false, entryPath: fileName, memory: false, onEvent: void 0 }; } const dir = typeof cacheOpt === "object" && cacheOpt.dir ? cacheOpt.dir : resolveDefaultCacheDir(fileName); const reset = typeof cacheOpt === "object" && cacheOpt.reset === true; const onEvent = typeof cacheOpt === "object" ? cacheOpt.onEvent : void 0; const memory = !(typeof cacheOpt === "object" && cacheOpt.memory === false); const stat = tryStatSync(fileName); if (!stat) { onEvent?.({ type: "skip-invalid", key: "", reason: "missing-entry" }); return { enabled: false, key: "", dir, reset, entryPath: fileName, memory, onEvent }; } const hash = crypto.createHash("sha1"); hash.update( JSON.stringify({ entry: path7.resolve(fileName), mtimeMs: stat.mtimeMs, size: stat.size, format: options.format, isESM: options.isESM, tsconfig: options.tsconfig ?? "auto", node: process4.versions.node, rolldown: hashRolldownOptions(options.rolldownOptions) }) ); return { enabled: true, key: hash.digest("hex"), dir, reset, entryPath: path7.resolve(fileName), memory, onEvent }; } function resolveDefaultCacheDir(fileName) { if (typeof process4.versions.deno !== "string") { const nearest = findNearestNodeModules(path7.dirname(fileName)); if (nearest) { return path7.resolve(nearest, ".rolldown-require-cache"); } } return path7.join(os.tmpdir(), "rolldown-require-cache"); } async function maybeReadCache(cache, options) { const metaPath = path7.join(cache.dir, `${cache.key}.meta.json`); const mem = cache.memory ? memoryCache.get(cache.key) : void 0; if (mem?.meta) { const valid2 = validateMeta(mem.meta, options); if (valid2 === true) { cache.onEvent?.({ type: "hit", key: cache.key, reason: "memory" }); return mem; } memoryCache.delete(cache.key); cache.onEvent?.({ type: "skip-invalid", key: cache.key, reason: valid2 }); } const meta = await readCacheMeta(metaPath); if (!meta) { return; } const valid = validateMeta(meta, options); if (valid !== true) { cache.onEvent?.({ type: "skip-invalid", key: cache.key, reason: valid }); return; } if (mem?.mod !== void 0 && cache.memory) { const enriched = { mod: mem.mod, codePath: meta.codePath, meta }; memoryCache.set(cache.key, enriched); cache.onEvent?.({ type: "hit", key: cache.key, reason: "memory" }); return enriched; } return { codePath: meta.codePath, meta }; } async function importCachedCode(cached, options) { if (cached.mod !== void 0) { return cached.mod; } const target = options.format === "esm" ? pathToFileURL3(cached.codePath).href : cached.codePath; if (options.require) { return options.require(target, { format: options.format }); } if (options.format === "esm") { return import(target); } return _require(target); } async function storeCacheOutput(cache, code, options, dependencies) { await fsp.mkdir(cache.dir, { recursive: true }); const ext = options.format === "cjs" ? "cjs" : "mjs"; const codePath = path7.join(cache.dir, `${cache.key}.code.${ext}`); if (cache.reset) { await Promise.allSettled([ fsp.rm(codePath, { force: true }), fsp.rm(path7.join(cache.dir, `${cache.key}.meta.json`), { force: true }) ]); } await fsp.writeFile(codePath, code); const trackedFiles = collectFileStats([ cache.entryPath, ...dependencies ?? [] ]); return { outfile: options.format === "esm" ? pathToFileURL3(codePath).href : codePath, cleanup: async () => { }, cacheMeta: { format: options.format, codePath, files: trackedFiles } }; } async function writeCacheMeta(cache, meta) { await fsp.mkdir(cache.dir, { recursive: true }); await fsp.writeFile( path7.join(cache.dir, `${cache.key}.meta.json`), JSON.stringify(meta) ); if (cache.memory) { memoryCache.set(cache.key, { codePath: meta.codePath, meta }); } } function collectFileStats(files) { const seen = /* @__PURE__ */ new Set(); const stats = []; for (const file of files) { if (!file || seen.has(file)) { continue; } seen.add(file); const stat = tryStatSync(file); if (stat?.isFile()) { stats.push({ path: path7.resolve(file), mtimeMs: stat.mtimeMs, size: stat.size }); } } return stats; } function writeMemoryCache(cache, mod, meta) { if (!cache.memory) { return; } memoryCache.set(cache.key, { mod, codePath: meta.codePath, meta }); } async function readCacheMeta(metaPath) { try { const raw = await fsp.readFile(metaPath, "utf-8"); return JSON.parse(raw); } catch { } return void 0; } function validateMeta(meta, options) { if (meta.format !== options.format) { return "format-mismatch"; } if (!meta.codePath || !fs5.existsSync(meta.codePath)) { return "missing-code"; } for (const file of meta.files ?? []) { const stat = tryStatSync(file.path); if (!stat || stat.mtimeMs !== file.mtimeMs || stat.size !== file.size) { return "stale-deps"; } } return true; } function hashRolldownOptions(options) { if (!options) { return "none"; } return crypto.createHash("sha1").update( JSON.stringify(options, (_key, value) => { if (typeof value === "function" || typeof value === "symbol") { return void 0; } return value; }) ).digest("hex"); } // src/temp-output.ts import { Buffer as Buffer2 } from "buffer"; import fsp2 from "fs/promises"; import os2 from "os"; import path8 from "path"; import process5 from "process"; import { pathToFileURL as pathToFileURL4 } from "url"; function sanitizeFilename(name) { return name.replace(/[^\w.-]/g, "_"); } async function resolveTempOutputFile(sourceFile, code, options) { const getOutputFile = options.getOutputFile || defaultGetOutputFile; const filenameHint = sanitizeFilename(path8.basename(sourceFile)); const hash = `timestamp-${Date.now()}-${Math.random().toString(16).slice(2)}`; const extension = options.format === "cjs" ? "cjs" : "mjs"; const fileName = `${filenameHint}.${hash}.${extension}`; const candidates = []; if (typeof process5.versions.deno !== "string") { const nearest = findNearestNodeModules(path8.dirname(sourceFile)); if (nearest) { candidates.push(path8.resolve(nearest, ".rolldown-require")); } } candidates.push(path8.join(os2.tmpdir(), "rolldown-require")); for (const base of candidates) { const target = getOutputFile(path8.join(base, fileName), options.format); try { await fsp2.mkdir(path8.dirname(target), { recursive: true }); await fsp2.writeFile(target, code); const cleanup = async () => { if (options.preserveTemporaryFile) { return; } try { await fsp2.unlink(target); } catch { } }; return { outfile: options.format === "esm" ? pathToFileURL4(target).href : target, cleanup }; } catch { } } if (options.format === "esm") { const dataUrl = `data:text/javascript;base64,${Buffer2.from(code).toString("base64")}`; return { outfile: dataUrl, cleanup: async () => { } }; } throw new Error("Failed to create temporary output file for bundled code"); } // src/loader.ts var _require2 = createRequire5(import.meta.url); var promisifiedRealpath = promisify(fs6.realpath); async function loadFromBundledFile(fileName, bundledCode, options, dependencies) { const cacheConfig = resolveCacheOptions(fileName, options); if (cacheConfig.enabled) { const cached = await maybeReadCache(cacheConfig, options); if (cached) { if (!cached.mod) { cacheConfig.onEvent?.({ type: "hit", key: cacheConfig.key }); } return importCachedCode(cached, options); } cacheConfig.onEvent?.({ type: "miss", key: cacheConfig.key }); } const { isESM } = options; if (isESM) { const tempOutput = cacheConfig.enabled ? await storeCacheOutput(cacheConfig, bundledCode, options, dependencies) : await resolveTempOutputFile(fileName, bundledCode, options); const outfile = tempOutput?.outfile; const cleanup = tempOutput?.cleanup; let mod; const req = options.require || dynamicImport; try { mod = await req(outfile, { format: options.format }); if (cacheConfig.enabled && tempOutput?.cacheMeta) { await writeCacheMeta(cacheConfig, tempOutput.cacheMeta); cacheConfig.onEvent?.({ type: "store", key: cacheConfig.key }); writeMemoryCache(cacheConfig, mod, tempOutput.cacheMeta); } return mod; } finally { if (!cacheConfig.enabled) { await cleanup?.(); } } } else { const extension = path9.extname(fileName); const realFileName = await promisifiedRealpath(fileName); const loaderExt = extension in _require2.extensions ? extension : ".js"; const defaultLoader = _require2.extensions[loaderExt]; const compileLoader = (module, filename) => { if (filename === realFileName) { ; module._compile(bundledCode, filename); } else { defaultLoader(module, filename); } }; let raw; try { _require2.extensions[loaderExt] = compileLoader; delete _require2.cache[_require2.resolve(fileName)]; raw = _require2(fileName); return raw.__esModule ? raw.default : raw; } finally { _require2.extensions[loaderExt] = defaultLoader; if (cacheConfig.enabled && raw !== void 0) { const cachedPath = await storeCacheOutput( cacheConfig, bundledCode, options, dependencies ); await writeCacheMeta(cacheConfig, cachedPath.cacheMeta); cacheConfig.onEvent?.({ type: "store", key: cacheConfig.key }); writeMemoryCache( cacheConfig, raw.__esModule ? raw.default : raw, cachedPath.cacheMeta ); } } } } // src/options.ts import path10 from "path"; import process6 from "process"; import { getTsconfig } from "get-tsconfig"; function resolveEntryFilepath(options) { if (path10.isAbsolute(options.filepath)) { return options.filepath; } const cwd = options.cwd ? path10.resolve(options.cwd) : process6.cwd(); return path10.resolve(cwd, options.filepath); } function detectModuleType(resolvedPath) { return typeof process6.versions.deno === "string" || isFilePathESM(resolvedPath); } function createInternalOptions(userOptions, isESM) { const { filepath: _filepath, cwd: _cwd, ...rest } = userOptions; const tsconfig = resolveTsconfigPath(userOptions); const format = userOptions.format ?? (isESM ? "esm" : "cjs"); return { ...rest, isESM, format, tsconfig }; } function resolveTsconfigPath(options) { if (options.tsconfig === false) { return void 0; } if (typeof options.tsconfig === "string") { return options.tsconfig; } return getTsconfig(options.cwd, "tsconfig.json")?.path ?? void 0; } // src/index.ts async function bundleRequire(options) { const resolvedPath = resolveEntryFilepath(options); const isESM = detectModuleType(resolvedPath); const internalOptions = createInternalOptions(options, isESM); const bundled = await bundleFile( resolvedPath, internalOptions ); const mod = await loadFromBundledFile( resolvedPath, bundled.code, internalOptions, bundled.dependencies ); return { mod, dependencies: bundled.dependencies }; } export { bundleFile, bundleRequire, configDefaults, loadFromBundledFile };