rolldown-require
Version:
bundle and require a file using rolldown!
1,563 lines (1,541 loc) • 48.1 kB
JavaScript
// 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
};