diff --git a/cli/build/register.ts b/cli/build/register.ts index b3fa4178..5e16398b 100644 --- a/cli/build/register.ts +++ b/cli/build/register.ts @@ -14,6 +14,7 @@ import { generateKicadProject } from "./generate-kicad-project" import type { GeneratedKicadProject } from "./generate-kicad-project" import { generateKicadFootprintLibrary } from "./generate-kicad-footprint-library" import { transpileFile } from "./transpile" +import { validateMainInDist } from "../utils/validate-main-in-dist" // @ts-ignore import runFrameStandaloneBundleContent from "@tscircuit/runframe/standalone" with { @@ -184,6 +185,8 @@ export const registerBuild = (program: Command) => { } if (options?.transpile) { + validateMainInDist(projectDir, distDir) + console.log("Transpiling entry file...") const entryFile = mainEntrypoint || circuitFiles[0] if (!entryFile) { diff --git a/cli/transpile/register.ts b/cli/transpile/register.ts index eecf569e..3ef63964 100644 --- a/cli/transpile/register.ts +++ b/cli/transpile/register.ts @@ -1,8 +1,8 @@ import type { Command } from "commander" -import fs from "node:fs" import path from "node:path" import { transpileFile } from "../build/transpile/index" import { getBuildEntrypoints } from "../build/get-build-entrypoints" +import { validateMainInDist } from "../utils/validate-main-in-dist" export const registerTranspile = (program: Command) => { program @@ -20,25 +20,7 @@ export const registerTranspile = (program: Command) => { const distDir = path.join(projectDir, "dist") - const packageJsonPath = path.join(projectDir, "package.json") - if (fs.existsSync(packageJsonPath)) { - const packageJson = JSON.parse( - fs.readFileSync(packageJsonPath, "utf-8"), - ) - - if (typeof packageJson.main === "string") { - const resolvedMainPath = path.resolve(projectDir, packageJson.main) - const isMainInDist = - resolvedMainPath === distDir || - resolvedMainPath.startsWith(`${distDir}${path.sep}`) - - if (!isMainInDist) { - throw new Error( - 'When using transpilation, your package\'s "main" field should point inside the `dist/*` directory, usually to "dist/index.js"', - ) - } - } - } + validateMainInDist(projectDir, distDir) console.log("Transpiling entry file...") const entryFile = mainEntrypoint || circuitFiles[0] diff --git a/cli/utils/validate-main-in-dist.ts b/cli/utils/validate-main-in-dist.ts new file mode 100644 index 00000000..7e4b6fb6 --- /dev/null +++ b/cli/utils/validate-main-in-dist.ts @@ -0,0 +1,22 @@ +import fs from "node:fs" +import path from "node:path" + +export const validateMainInDist = (projectDir: string, distDir: string) => { + const packageJsonPath = path.join(projectDir, "package.json") + if (!fs.existsSync(packageJsonPath)) return + + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) + + if (typeof packageJson.main !== "string") return + + const resolvedMainPath = path.resolve(projectDir, packageJson.main) + const isMainInDist = + resolvedMainPath === distDir || + resolvedMainPath.startsWith(`${distDir}${path.sep}`) + + if (!isMainInDist) { + throw new Error( + 'When using transpilation, your package\'s "main" field should point inside the `dist/*` directory, usually to "dist/index.js"', + ) + } +} diff --git a/tests/cli/build/build-transpile.test.ts b/tests/cli/build/build-transpile.test.ts index 997f90f0..0033672a 100644 --- a/tests/cli/build/build-transpile.test.ts +++ b/tests/cli/build/build-transpile.test.ts @@ -60,7 +60,7 @@ test("build with --transpile uses mainEntrypoint when available", async () => { await writeFile(otherPath, circuitCode) await writeFile( path.join(tmpDir, "package.json"), - JSON.stringify({ main: "index.tsx" }), + JSON.stringify({ main: "dist/index.js" }), ) await runCommand(`tsci build --transpile --ignore-errors`) @@ -79,6 +79,23 @@ test("build with --transpile uses mainEntrypoint when available", async () => { expect(dtsStat.isFile()).toBe(true) }, 30_000) +test("build with --transpile errors when main is outside dist", async () => { + const { tmpDir, runCommand } = await getCliTestFixture() + const mainPath = path.join(tmpDir, "index.tsx") + + await writeFile(mainPath, circuitCode) + await writeFile( + path.join(tmpDir, "package.json"), + JSON.stringify({ main: "index.tsx" }), + ) + + const { stderr } = await runCommand(`tsci build --transpile`) + + expect(stderr).toContain( + 'When using transpilation, your package\'s "main" field should point inside the `dist/*` directory, usually to "dist/index.js"', + ) +}, 30_000) + test("build with --transpile transforms JSX correctly", async () => { const { tmpDir, runCommand } = await getCliTestFixture() const circuitPath = path.join(tmpDir, "jsx-test.tsx")