diff --git a/.changeset/wicked-tigers-move.md b/.changeset/wicked-tigers-move.md new file mode 100644 index 00000000..698f1f09 --- /dev/null +++ b/.changeset/wicked-tigers-move.md @@ -0,0 +1,5 @@ +--- +"pluv": patch +--- + +Updated the pluv cli's `build` command so that only the pluv entry file and all necessary dependencies are type-checked, instead of all TypeScript files in the project workspace. diff --git a/packages/cli/package.json b/packages/cli/package.json index ee060007..c3bbd0ee 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -48,12 +48,13 @@ "react": "^18.2.0", "rollup": "^4.14.2", "rollup-plugin-node-polyfills": "^0.2.1", + "tslib": "^2.6.2", + "typescript": "^5.4.5", "zod": "^3.22.4" }, "devDependencies": { "@pluv/tsconfig": "workspace:^", "eslint": "^8.57.0", - "eslint-config-pluv": "workspace:^", - "typescript": "^5.4.5" + "eslint-config-pluv": "workspace:^" } } diff --git a/packages/cli/src/hooks/useBuildApp.ts b/packages/cli/src/hooks/useBuildApp.ts index a3e80610..8d565fd2 100644 --- a/packages/cli/src/hooks/useBuildApp.ts +++ b/packages/cli/src/hooks/useBuildApp.ts @@ -1,6 +1,7 @@ import { useApp } from "ink"; import { useState } from "react"; -import { BuildAppOptions, buildApp } from "../utils/buildApp.js"; +import type { BuildAppOptions } from "../utils/index.js"; +import { buildApp } from "../utils/index.js"; import { useMountEffect } from "./useMountEffect.js"; export const useBuildApp = (options: BuildAppOptions) => { diff --git a/packages/cli/src/hooks/useConfig.ts b/packages/cli/src/hooks/useConfig.ts index 0f3ac78e..031a7cf7 100644 --- a/packages/cli/src/hooks/useConfig.ts +++ b/packages/cli/src/hooks/useConfig.ts @@ -1,5 +1,5 @@ import { useState } from "react"; -import { getConfig } from "../utils/config.js"; +import { getConfig } from "../utils/index.js"; export const useConfig = () => { const [config] = useState(() => getConfig()); diff --git a/packages/cli/src/schemas/ZodPluvConfig.ts b/packages/cli/src/schemas/ZodPluvConfig.ts index 11e730ec..ea5af22b 100644 --- a/packages/cli/src/schemas/ZodPluvConfig.ts +++ b/packages/cli/src/schemas/ZodPluvConfig.ts @@ -1,9 +1,7 @@ import { z } from "zod"; export const ZodPluvConfig = z.object({ - env: z - .intersection(z.record(z.string(), z.string()), z.string()) - .optional(), + env: z.record(z.string(), z.string()).optional(), input: z.string().default("./pluv.ts"), outDir: z.string().default("./.pluv"), }); diff --git a/packages/cli/src/utils/buildApp.ts b/packages/cli/src/utils/buildApp/buildApp.ts similarity index 88% rename from packages/cli/src/utils/buildApp.ts rename to packages/cli/src/utils/buildApp/buildApp.ts index 00368765..bd8df1b1 100644 --- a/packages/cli/src/utils/buildApp.ts +++ b/packages/cli/src/utils/buildApp/buildApp.ts @@ -7,9 +7,10 @@ import terser from "@rollup/plugin-terser"; import typescript from "@rollup/plugin-typescript"; import dotenv from "dotenv"; import fs from "fs-extra"; -import path from "path"; +import path from "node:path"; import { OutputAsset, OutputChunk, Plugin, rollup } from "rollup"; import nodePolyfills from "rollup-plugin-node-polyfills"; +import { resolveDependenciesTransformer } from "./resolveDependenciesTransformer.js"; const isOutputValid = (chunks: (OutputChunk | OutputAsset)[]): boolean => { return chunks.some((chunk) => { @@ -52,6 +53,9 @@ export interface BuildAppOptions { export const buildApp = async (options: BuildAppOptions) => { const { env, input, outDir: _outDir } = options; + const outDir = path.resolve(process.cwd(), options.outDir); + const outFile = path.resolve(outDir, "./index.js"); + const replaceEnv = Object.entries(getEnv(env)).reduce< Record >( @@ -64,13 +68,16 @@ export const buildApp = async (options: BuildAppOptions) => { const bundle = await rollup({ input, - output: { format: "esm" }, + output: { format: "esm", file: outFile }, onLog: (level, log) => { const { frame, loc, message } = log; if (loc) { console.warn( - `${loc.file} (${loc.line}:${loc.column}) ${message}`, + `${message}` + .replace(/\s*\[plugin\s+\w+\]\s*/gi, "") + .replace(/\s*@rollup\/plugin\S+\s*/gi, "") + .replace(/\s*rollup\S+\s*/gi, ""), ); if (frame) console.warn(frame); } else { @@ -103,6 +110,8 @@ export const buildApp = async (options: BuildAppOptions) => { skipLibCheck: true, strict: true, target: "es2021", + transformers: { before: [resolveDependenciesTransformer] }, + include: input, }), // Converts CommonJS modules to ES6. (commonjs as unknown as typeof commonjs.default)({ @@ -128,10 +137,8 @@ export const buildApp = async (options: BuildAppOptions) => { ], }); - const outDir = path.resolve(process.cwd(), options.outDir); - const { output } = await bundle.generate({ - file: path.resolve(outDir, "./index.js"), + file: outFile, format: "esm", }); diff --git a/packages/cli/src/utils/buildApp/index.ts b/packages/cli/src/utils/buildApp/index.ts new file mode 100644 index 00000000..35846571 --- /dev/null +++ b/packages/cli/src/utils/buildApp/index.ts @@ -0,0 +1,2 @@ +export { buildApp } from "./buildApp.js"; +export type { BuildAppOptions } from "./buildApp.js"; diff --git a/packages/cli/src/utils/buildApp/resolveDependenciesTransformer.ts b/packages/cli/src/utils/buildApp/resolveDependenciesTransformer.ts new file mode 100644 index 00000000..d0377454 --- /dev/null +++ b/packages/cli/src/utils/buildApp/resolveDependenciesTransformer.ts @@ -0,0 +1,68 @@ +import { ProgramTransformerFactory } from "@rollup/plugin-typescript"; +import path from "node:path"; +import type { SourceFile, TransformerFactory } from "typescript"; +import ts from "typescript"; + +const resolveDependencies = (entryFilePath: string): string[] => { + const dependencies = new Set(); + const visited = new Set(); + + const visit = (filePath: string) => { + if (visited.has(filePath)) return; + + visited.add(filePath); + + const sourceText = ts.sys.readFile(filePath); + + if (!sourceText) return; + + let sourceFile: SourceFile = ts.createSourceFile( + filePath, + sourceText, + ts.ScriptTarget.ESNext, + true, + ); + + if (!sourceFile) return; + + ts.forEachChild(sourceFile, (node) => { + if (!ts.isImportDeclaration(node)) return; + + const importPath = node.moduleSpecifier.getText(); + const absolutePath = path.resolve( + path.dirname(filePath), + importPath, + ); + + dependencies.add(importPath); + + visit(absolutePath); + }); + }; + + visit(entryFilePath); + + return Array.from(dependencies.values()); +}; + +export const resolveDependenciesTransformer: ProgramTransformerFactory<"before"> = + { + type: "program", + factory: (program): TransformerFactory => { + return (context) => { + return (node) => { + const dependencies = resolveDependencies(node.fileName); + + dependencies.forEach((dependency) => { + const sourceFile = program.getSourceFile(dependency); + + try { + program.emit(sourceFile); + } catch {} + }); + + return node; + }; + }; + }, + }; diff --git a/packages/cli/src/utils/config.ts b/packages/cli/src/utils/getConfig.ts similarity index 100% rename from packages/cli/src/utils/config.ts rename to packages/cli/src/utils/getConfig.ts diff --git a/packages/cli/src/utils/index.ts b/packages/cli/src/utils/index.ts index d1bc97e8..6cab3b33 100644 --- a/packages/cli/src/utils/index.ts +++ b/packages/cli/src/utils/index.ts @@ -1 +1,4 @@ -export * from "./config.js"; +export { buildApp } from "./buildApp/index.js"; +export type { BuildAppOptions } from "./buildApp/index.js"; +export { getConfig } from "./getConfig.js"; +export type { ParsedPluvConfig, PluvConfig } from "./getConfig.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1062e77a..838f996d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,7 +65,7 @@ importers: version: 0.4.4(rollup@4.14.2) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.14.2)(typescript@5.4.5) + version: 11.1.6(rollup@4.14.2)(tslib@2.6.2)(typescript@5.4.5) eslint-config-pluv: specifier: workspace:^ version: link:../../packages/eslint-config-pluv @@ -1000,7 +1000,7 @@ importers: version: 0.4.4(rollup@4.14.2) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.14.2)(typescript@5.4.5) + version: 11.1.6(rollup@4.14.2)(tslib@2.6.2)(typescript@5.4.5) '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 @@ -1037,6 +1037,12 @@ importers: rollup-plugin-node-polyfills: specifier: ^0.2.1 version: 0.2.1 + tslib: + specifier: ^2.6.2 + version: 2.6.2 + typescript: + specifier: ^5.4.5 + version: 5.4.5 zod: specifier: ^3.22.4 version: 3.22.4 @@ -1050,9 +1056,6 @@ importers: eslint-config-pluv: specifier: workspace:^ version: link:../eslint-config-pluv - typescript: - specifier: ^5.4.5 - version: 5.4.5 packages/client: dependencies: @@ -5496,7 +5499,7 @@ packages: smob: 1.4.1 terser: 5.21.0 - /@rollup/plugin-typescript@11.1.6(rollup@4.14.2)(typescript@5.4.5): + /@rollup/plugin-typescript@11.1.6(rollup@4.14.2)(tslib@2.6.2)(typescript@5.4.5): resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5512,6 +5515,7 @@ packages: '@rollup/pluginutils': 5.1.0(rollup@4.14.2) resolve: 1.22.8 rollup: 4.14.2 + tslib: 2.6.2 typescript: 5.4.5 /@rollup/pluginutils@5.0.5(rollup@4.14.2):