Skip to content

Commit

Permalink
feat(config): import mud config with tsx (#3290)
Browse files Browse the repository at this point in the history
  • Loading branch information
holic authored Jan 17, 2025
1 parent ef67355 commit 9580d29
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 261 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-dodos-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/config": patch
---

Replaced esbuild with tsx to load MUD config in an effort to resolve issues with loading multiple MUD configs in parallel.
4 changes: 2 additions & 2 deletions packages/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"@ark/util": "0.2.2",
"@latticexyz/common": "workspace:*",
"@latticexyz/schema-type": "workspace:*",
"esbuild": "^0.17.15",
"find-up": "^6.3.0"
"find-up": "^6.3.0",
"tsx": "^4.19.1"
},
"devDependencies": {
"tsup": "^6.7.0",
Expand Down
40 changes: 15 additions & 25 deletions packages/config/src/deprecated/node/loadConfig.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
import { findUp } from "find-up";
import path from "path";
import esbuild from "esbuild";
import { rmSync } from "fs";
import { pathToFileURL } from "url";
import os from "os";

// TODO: explore using https://www.npmjs.com/package/ts-import instead
import fs from "fs/promises";
import { tsImport } from "tsx/esm/api";
import { require as tsRequire } from "tsx/cjs/api";

// In order of preference files are checked
/** @deprecated */
const configFiles = ["mud.config.js", "mud.config.mjs", "mud.config.ts", "mud.config.mts"];
/** @deprecated */
const TEMP_CONFIG = "mud.config.temp.mjs";

/** @deprecated */
export async function loadConfig(configPath?: string): Promise<unknown> {
configPath = await resolveConfigPath(configPath);
try {
await esbuild.build({
entryPoints: [configPath],
format: "esm",
outfile: TEMP_CONFIG,
// https://esbuild.github.io/getting-started/#bundling-for-node
platform: "node",
// bundle local imports (otherwise it may error, js can't import ts)
bundle: true,
// avoid bundling external imports (it's unnecessary and esbuild can't handle all node features)
packages: "external",
});
configPath = await resolveConfigPath(TEMP_CONFIG, true);
// Node.js caches dynamic imports, so without appending a cache breaking
// param like `?update={Date.now()}` this import always returns the same config
// if called multiple times in a single process, like the `dev-contracts` cli
return (await import(configPath + `?update=${Date.now()}`)).default;
} finally {
rmSync(TEMP_CONFIG, { force: true });
// load nearest package.json to figure out if we need to import with ESM or CJS
const packageJsonPath = await findUp("package.json", { cwd: path.dirname(configPath) });
if (!packageJsonPath) throw new Error(`Could not find package.json for config at "${configPath}".`);
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8"));
// use require if cjs
if (!packageJson.type || packageJson.type === "commonjs") {
// tsRequire has an internal cache, so we need to append data to reload the config
// this helps with things like the mud dev runner that reevalutes the config on changes
return tsRequire(`${configPath}?update=${Date.now()}`, import.meta.url).default;
}
// otherwise default to esm
// this is not cached, so we don't need to append anything to the config path
return (await tsImport(configPath, import.meta.url)).default;
}

/** @deprecated */
Expand Down
Loading

0 comments on commit 9580d29

Please sign in to comment.