Merge pull request #37 from codex/turbo-package-exports

refactor(turbo): consume workspace package exports
This commit is contained in:
vince 2026-06-20 07:27:51 +02:00
commit 243d05cef7
8 changed files with 96 additions and 21 deletions

View file

@ -114,6 +114,62 @@ describe("workspace boundaries", () => {
); );
}); });
test("consumes workspace packages through package exports instead of source aliases", () => {
const webTsconfig = JSON.parse(
readFileSync(join(root, "apps/web/tsconfig.json"), "utf8"),
) as { compilerOptions?: { paths?: Record<string, string[]> } };
const modelPackage = JSON.parse(
readFileSync(join(root, "packages/dashboard-model/package.json"), "utf8"),
) as { exports?: Record<string, WorkspacePackageExport> };
const uiPackage = JSON.parse(
readFileSync(join(root, "packages/ui/package.json"), "utf8"),
) as { exports?: Record<string, WorkspacePackageExport> };
const viteConfig = readFileSync(join(root, "apps/web/vite.config.ts"), "utf8");
const turboConfig = JSON.parse(
readFileSync(join(root, "turbo.json"), "utf8"),
) as { tasks?: Record<string, { dependsOn?: string[] }> };
expect(webTsconfig.compilerOptions?.paths).not.toHaveProperty(
"@dimensionlab/dashboard-model",
);
expect(webTsconfig.compilerOptions?.paths).not.toHaveProperty(
"@dimensionlab/dashboard-model/fixtures",
);
expect(webTsconfig.compilerOptions?.paths).not.toHaveProperty("@dimensionlab/ui");
expect(webTsconfig.compilerOptions?.paths).not.toHaveProperty(
"@dimensionlab/ui/styles.css",
);
expect(webTsconfig.compilerOptions?.paths).toEqual({
"$lib/*": ["src/lib/*"],
});
expect(viteConfig).not.toContain("../../packages/dashboard-model/src");
expect(viteConfig).not.toContain("../../packages/ui/src");
expect(turboConfig.tasks?.dev?.dependsOn).toEqual(["^build"]);
expectPackageExport(modelPackage.exports?.["."], {
types: "./dist/index.d.ts",
development: "./src/index.ts",
default: "./dist/index.js",
});
expectPackageExport(modelPackage.exports?.["./fixtures"], {
types: "./dist/fixtures/index.d.ts",
development: "./src/fixtures/index.ts",
default: "./dist/fixtures/index.js",
});
expectPackageExport(uiPackage.exports?.["."], {
types: "./dist/index.d.ts",
development: "./src/index.ts",
default: "./dist/index.js",
});
expectPackageExport(uiPackage.exports?.["./styles.css"], {
development: "./src/styles.css",
default: "./dist/styles.css",
});
expectPackageExport(uiPackage.exports?.["./tokens.css"], {
development: "./src/tokens.css",
default: "./dist/tokens.css",
});
});
test("builds the internal container from a turbo-pruned web workspace", () => { test("builds the internal container from a turbo-pruned web workspace", () => {
const containerfile = readFileSync( const containerfile = readFileSync(
join(root, "apps/web/Containerfile"), join(root, "apps/web/Containerfile"),
@ -183,3 +239,18 @@ describe("workspace boundaries", () => {
); );
}); });
}); });
type WorkspacePackageExport =
| string
| {
types?: string;
development?: string;
default?: string;
};
function expectPackageExport(
actual: WorkspacePackageExport | undefined,
expected: Exclude<WorkspacePackageExport, string>,
): void {
expect(actual).toMatchObject(expected);
}

View file

@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
import { describe, expect, test } from "vitest"; import { describe, expect, test } from "vitest";
import { createDevServerConfig } from "../../vite.config"; import { createDevServerConfig } from "../../vite.config";
import { apiServerArgs } from "./dev";
describe("local development runtime", () => { describe("local development runtime", () => {
test("starts the Bun API server together with the Vite dev server", () => { test("starts the Bun API server together with the Vite dev server", () => {
@ -22,4 +23,11 @@ describe("local development runtime", () => {
changeOrigin: true, changeOrigin: true,
}); });
}); });
test("uses development package export conditions for the Bun API server", () => {
expect(apiServerArgs).toEqual([
"--conditions=development",
"src/server/index.ts",
]);
});
}); });

View file

@ -3,6 +3,10 @@ const webPort = process.env.PORT || "5173";
const apiHost = process.env.DASHBOARD_DEV_API_HOST || "127.0.0.1"; const apiHost = process.env.DASHBOARD_DEV_API_HOST || "127.0.0.1";
const apiPort = process.env.DASHBOARD_DEV_API_PORT || "5174"; const apiPort = process.env.DASHBOARD_DEV_API_PORT || "5174";
const apiTarget = `http://${apiHost}:${apiPort}`; const apiTarget = `http://${apiHost}:${apiPort}`;
export const apiServerArgs = [
"--conditions=development",
"src/server/index.ts",
] as const;
if (import.meta.main) { if (import.meta.main) {
runDevServers(); runDevServers();
@ -51,7 +55,7 @@ export function runDevServers(): void {
process.on("SIGINT", () => shutdown(0)); process.on("SIGINT", () => shutdown(0));
process.on("SIGTERM", () => shutdown(0)); process.on("SIGTERM", () => shutdown(0));
spawn("api server", [process.execPath, "src/server/index.ts"], { spawn("api server", [process.execPath, ...apiServerArgs], {
HOST: apiHost, HOST: apiHost,
PORT: apiPort, PORT: apiPort,
}); });

View file

@ -3,12 +3,6 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@dimensionlab/dashboard-model": ["../../packages/dashboard-model/src/index.ts"],
"@dimensionlab/dashboard-model/fixtures": [
"../../packages/dashboard-model/src/fixtures/index.ts"
],
"@dimensionlab/ui": ["../../packages/ui/src/index.ts"],
"@dimensionlab/ui/styles.css": ["../../packages/ui/src/styles.css"],
"$lib/*": ["src/lib/*"] "$lib/*": ["src/lib/*"]
}, },
"types": ["node", "bun-types", "react", "react-dom", "vite/client"] "types": ["node", "bun-types", "react", "react-dom", "vite/client"]

View file

@ -24,18 +24,6 @@ export default defineConfig({
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss()],
resolve: { resolve: {
alias: { alias: {
"@dimensionlab/ui/styles.css": fileURLToPath(
new URL("../../packages/ui/src/styles.css", import.meta.url),
),
"@dimensionlab/ui": fileURLToPath(
new URL("../../packages/ui/src/index.ts", import.meta.url),
),
"@dimensionlab/dashboard-model/fixtures": fileURLToPath(
new URL("../../packages/dashboard-model/src/fixtures/index.ts", import.meta.url),
),
"@dimensionlab/dashboard-model": fileURLToPath(
new URL("../../packages/dashboard-model/src/index.ts", import.meta.url),
),
$lib: fileURLToPath(new URL("./src/lib", import.meta.url)), $lib: fileURLToPath(new URL("./src/lib", import.meta.url)),
}, },
}, },

View file

@ -6,10 +6,12 @@
"exports": { "exports": {
".": { ".": {
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"development": "./src/index.ts",
"default": "./dist/index.js" "default": "./dist/index.js"
}, },
"./fixtures": { "./fixtures": {
"types": "./dist/fixtures/index.d.ts", "types": "./dist/fixtures/index.d.ts",
"development": "./src/fixtures/index.ts",
"default": "./dist/fixtures/index.js" "default": "./dist/fixtures/index.js"
} }
}, },

View file

@ -7,10 +7,17 @@
"exports": { "exports": {
".": { ".": {
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"development": "./src/index.ts",
"default": "./dist/index.js" "default": "./dist/index.js"
}, },
"./styles.css": "./dist/styles.css", "./styles.css": {
"./tokens.css": "./dist/tokens.css" "development": "./src/styles.css",
"default": "./dist/styles.css"
},
"./tokens.css": {
"development": "./src/tokens.css",
"default": "./dist/tokens.css"
}
}, },
"scripts": { "scripts": {
"build": "rm -rf dist && tsc -p tsconfig.build.json && mkdir -p dist/components && cp src/styles.css dist/styles.css && cp src/tokens.css dist/tokens.css && cp src/components/styles.css dist/components/styles.css", "build": "rm -rf dist && tsc -p tsconfig.build.json && mkdir -p dist/components && cp src/styles.css dist/styles.css && cp src/tokens.css dist/tokens.css && cp src/components/styles.css dist/components/styles.css",

View file

@ -60,6 +60,7 @@
"env": ["DATABASE_URL"] "env": ["DATABASE_URL"]
}, },
"dev": { "dev": {
"dependsOn": ["^build"],
"cache": false, "cache": false,
"persistent": true, "persistent": true,
"env": [ "env": [