load-config-pmbgQdFU.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { t as rolldown } from "./rolldown-BLMDGLfI.mjs";
  2. import fs from "node:fs";
  3. import path from "node:path";
  4. import { readdir } from "node:fs/promises";
  5. import { cwd } from "node:process";
  6. import { pathToFileURL } from "node:url";
  7. //#region src/utils/load-config.ts
  8. async function bundleTsConfig(configFile, isEsm) {
  9. const dirnameVarName = "injected_original_dirname";
  10. const filenameVarName = "injected_original_filename";
  11. const importMetaUrlVarName = "injected_original_import_meta_url";
  12. const bundle = await rolldown({
  13. input: configFile,
  14. platform: "node",
  15. resolve: { mainFields: ["main"] },
  16. transform: { define: {
  17. __dirname: dirnameVarName,
  18. __filename: filenameVarName,
  19. "import.meta.url": importMetaUrlVarName,
  20. "import.meta.dirname": dirnameVarName,
  21. "import.meta.filename": filenameVarName
  22. } },
  23. treeshake: false,
  24. external: [/^[\w@][^:]/],
  25. plugins: [{
  26. name: "inject-file-scope-variables",
  27. transform: {
  28. filter: { id: /\.[cm]?[jt]s$/ },
  29. async handler(code, id) {
  30. return {
  31. code: `const ${dirnameVarName} = ${JSON.stringify(path.dirname(id))};const ${filenameVarName} = ${JSON.stringify(id)};const ${importMetaUrlVarName} = ${JSON.stringify(pathToFileURL(id).href)};` + code,
  32. map: null
  33. };
  34. }
  35. }
  36. }]
  37. });
  38. const outputDir = path.dirname(configFile);
  39. const fileName = (await bundle.write({
  40. dir: outputDir,
  41. format: isEsm ? "esm" : "cjs",
  42. sourcemap: "inline",
  43. entryFileNames: `rolldown.config.[hash]${path.extname(configFile).replace("ts", "js")}`
  44. })).output.find((chunk) => chunk.type === "chunk" && chunk.isEntry).fileName;
  45. return path.join(outputDir, fileName);
  46. }
  47. const SUPPORTED_JS_CONFIG_FORMATS = [
  48. ".js",
  49. ".mjs",
  50. ".cjs"
  51. ];
  52. const SUPPORTED_TS_CONFIG_FORMATS = [
  53. ".ts",
  54. ".mts",
  55. ".cts"
  56. ];
  57. const SUPPORTED_CONFIG_FORMATS = [...SUPPORTED_JS_CONFIG_FORMATS, ...SUPPORTED_TS_CONFIG_FORMATS];
  58. const DEFAULT_CONFIG_BASE = "rolldown.config";
  59. async function findConfigFileNameInCwd() {
  60. const filesInWorkingDirectory = new Set(await readdir(cwd()));
  61. for (const extension of SUPPORTED_CONFIG_FORMATS) {
  62. const fileName = `${DEFAULT_CONFIG_BASE}${extension}`;
  63. if (filesInWorkingDirectory.has(fileName)) return fileName;
  64. }
  65. throw new Error("No `rolldown.config` configuration file found.");
  66. }
  67. async function loadTsConfig(configFile) {
  68. const file = await bundleTsConfig(configFile, isFilePathESM(configFile));
  69. try {
  70. return (await import(pathToFileURL(file).href)).default;
  71. } finally {
  72. fs.unlink(file, () => {});
  73. }
  74. }
  75. function isFilePathESM(filePath) {
  76. if (/\.m[jt]s$/.test(filePath)) return true;
  77. else if (/\.c[jt]s$/.test(filePath)) return false;
  78. else {
  79. const pkg = findNearestPackageData(path.dirname(filePath));
  80. if (pkg) return pkg.type === "module";
  81. return false;
  82. }
  83. }
  84. function findNearestPackageData(basedir) {
  85. while (basedir) {
  86. const pkgPath = path.join(basedir, "package.json");
  87. if (tryStatSync(pkgPath)?.isFile()) try {
  88. return JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
  89. } catch {}
  90. const nextBasedir = path.dirname(basedir);
  91. if (nextBasedir === basedir) break;
  92. basedir = nextBasedir;
  93. }
  94. return null;
  95. }
  96. function tryStatSync(file) {
  97. try {
  98. return fs.statSync(file, { throwIfNoEntry: false });
  99. } catch {}
  100. }
  101. /**
  102. * Load config from a file in a way that Rolldown does.
  103. *
  104. * @param configPath The path to the config file. If empty, it will look for `rolldown.config` with supported extensions in the current working directory.
  105. * @returns The loaded config export
  106. *
  107. * @category Config
  108. */
  109. async function loadConfig(configPath) {
  110. const ext = path.extname(configPath = configPath || await findConfigFileNameInCwd());
  111. try {
  112. if (SUPPORTED_JS_CONFIG_FORMATS.includes(ext) || process.env.NODE_OPTIONS?.includes("--import=tsx") && SUPPORTED_TS_CONFIG_FORMATS.includes(ext)) return (await import(pathToFileURL(configPath).href)).default;
  113. else if (SUPPORTED_TS_CONFIG_FORMATS.includes(ext)) return await loadTsConfig(path.resolve(configPath));
  114. else throw new Error(`Unsupported config format. Expected: \`${SUPPORTED_CONFIG_FORMATS.join(",")}\` but got \`${ext}\``);
  115. } catch (err) {
  116. throw new Error("Error happened while loading config.", { cause: err });
  117. }
  118. }
  119. //#endregion
  120. export { loadConfig as t };