diff --git a/package.json b/package.json index 82c9e2b38..6a01b272e 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "clean:ts": "tsc --build tsconfig.build.json --clean", "format": "prettier -w .", "format:check": "prettier -c .", + "postinstall": "pnpm scripts postinstall", "lint": "eslint --ignore-path .gitignore .", "prepare": "husky install", "release": "changeset publish", diff --git a/scripts/actions/patchWsModulesLinks.ts b/scripts/actions/patchWsModulesLinks.ts new file mode 100644 index 000000000..4473f8a78 --- /dev/null +++ b/scripts/actions/patchWsModulesLinks.ts @@ -0,0 +1,40 @@ +import { readdir, symlink, unlink } from "fs/promises"; +import { join } from "path"; +import { safeReadLink, safeStat } from "~/util/fs"; +import { parsePackageFile } from "~/util/package"; +import { getPackageNames, packagesPath } from "~/util/workspace"; + +async function patch(packagePath: string) { + const wsPath = `${packagePath}/node_modules/@suid`; + if (!(await safeStat(wsPath))) return; + const dependencyNames = await readdir(wsPath); + for (const dependencyName of dependencyNames) { + const dependencyPath = join(wsPath, dependencyName); + const link = await safeReadLink(dependencyPath); + if (!link) continue; + const pkg = await parsePackageFile(join(dependencyPath, "package.json")); + if (pkg.publishConfig?.directory) { + await unlink(dependencyPath); + await symlink( + join(link, pkg.publishConfig.directory), + dependencyPath, + "junction" + ); + } + } +} + +/** + * @link https://github.com/pnpm/pnpm/issues/3901 + */ +async function patchWsModulesLinks() { + const { name } = patchWsModulesLinks; + const packageNames = await getPackageNames(); + for (const packageName of packageNames) { + console.log(`[${name}] ${packageName}`); + const packagePath = `${packagesPath}/${packageName}`; + await patch(packagePath); + } +} + +export default patchWsModulesLinks; diff --git a/scripts/actions/postinstall.ts b/scripts/actions/postinstall.ts new file mode 100644 index 000000000..c43dd348f --- /dev/null +++ b/scripts/actions/postinstall.ts @@ -0,0 +1,7 @@ +import patchWsModulesLinks from "~/actions/patchWsModulesLinks"; + +async function postinstall() { + await patchWsModulesLinks(); +} + +export default postinstall; diff --git a/scripts/index.ts b/scripts/index.ts index 3651bbe94..cdde2c2cf 100644 --- a/scripts/index.ts +++ b/scripts/index.ts @@ -9,7 +9,9 @@ import genRes from "~/actions/genRes"; import genRoadmap from "~/actions/genRoadmap"; import patchLibModulesLinks from "~/actions/patchLibModulesLinks"; import patchTsConfigs from "~/actions/patchTsConfigs"; +import patchWsModulesLinks from "~/actions/patchWsModulesLinks"; import postbuild from "~/actions/postbuild"; +import postinstall from "~/actions/postinstall"; import prebuild from "~/actions/prebuild"; import syncIconsMaterial from "~/actions/syncIconsMaterial"; @@ -56,8 +58,12 @@ program program.command(snakeCase(patchTsConfigs.name)).action(() => patchTsConfigs()); -program.command(snakeCase(postbuild.name)).action(() => postbuild()); +program + .command(snakeCase(patchWsModulesLinks.name)) + .action(() => patchWsModulesLinks()); +program.command(snakeCase(postbuild.name)).action(() => postbuild()); +program.command(snakeCase(postinstall.name)).action(() => postinstall()); program.command(snakeCase(prebuild.name)).action(() => prebuild()); program diff --git a/scripts/util/fs.ts b/scripts/util/fs.ts index 57ebf5ec9..a0ed2fd7e 100644 --- a/scripts/util/fs.ts +++ b/scripts/util/fs.ts @@ -1,4 +1,4 @@ -import { readFile, stat } from "fs/promises"; +import { readFile, readlink, stat } from "fs/promises"; import { parse } from "json5"; export async function parseJSONFile(path: string) { @@ -13,3 +13,11 @@ export async function safeStat(path: string) { return; } } + +export async function safeReadLink(path: string) { + try { + return await readlink(path); + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; + } +}