diff --git a/packages/rspack/src/executors/rspack/rspack.impl.ts b/packages/rspack/src/executors/rspack/rspack.impl.ts index dd5737a9f..a30c7e401 100644 --- a/packages/rspack/src/executors/rspack/rspack.impl.ts +++ b/packages/rspack/src/executors/rspack/rspack.impl.ts @@ -1,14 +1,12 @@ -import { ExecutorContext, logger, output } from '@nx/devkit'; +import { ExecutorContext, logger } from '@nx/devkit'; import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable'; import { Stats } from '@rspack/core'; -import { existsSync, rmSync } from 'fs'; +import { rmSync } from 'fs'; import * as path from 'path'; import { createCompiler } from '../../utils/create-compiler'; import { isMode } from '../../utils/mode-utils'; import { RspackExecutorSchema } from './schema'; -import { spawn } from 'child_process'; -import { resolve } from 'path'; -import chalk = require('chalk'); +import { printDiagnostics, runTypeCheck } from '@nx/js'; export default async function* runExecutor( options: RspackExecutorSchema, @@ -19,16 +17,17 @@ export default async function* runExecutor( if (isMode(process.env.NODE_ENV)) { options.mode = process.env.NODE_ENV; } + + if (options.typeCheck) { + await executeTypeCheck(options, context); + } + // Mimic --clean from webpack. rmSync(path.join(context.root, options.outputPath), { force: true, recursive: true, }); - - if (options.typeCheck) { - await runTypeCheck(options, context); - } - + const compiler = await createCompiler(options, context); const iterable = createAsyncIterable<{ @@ -119,63 +118,22 @@ function registerCleanupCallback(callback: () => void) { process.on('exit', wrapped); } -async function runTypeCheck( + +async function executeTypeCheck( options: RspackExecutorSchema, context: ExecutorContext ) { - let tsFilePath = options.tsConfig && resolve(options.tsConfig); - - if (!tsFilePath) { - const projectConfiguration = - context.projectsConfigurations!.projects[context.projectName!]; - const tsFileName = - projectConfiguration.projectType === 'application' - ? 'tsconfig.app.json' - : 'tsconfig.lib.json'; - tsFilePath = resolve(projectConfiguration.root, tsFileName); - } - if (!existsSync(tsFilePath)) { - const customTsConfigMessage = options.tsConfig - ? '' - : ` If project's tsconfig file name is not standard, provide the path to it as "tsConfig" executor option.`; - throw new Error( - `Could not find tsconfig at "${tsFilePath}".` + customTsConfigMessage - ); - } - - const typeCheckCommand = `npx tsc --incremental --noEmit --pretty -p ${tsFilePath}`; - output.log({ - title: `Running type check for the "${context.projectName}"..`, - bodyLines: [chalk.dim(typeCheckCommand)], + const projectConfiguration = + context.projectsConfigurations!.projects[context.projectName!]; + const result = await runTypeCheck({ + workspaceRoot: path.resolve(projectConfiguration.root), + tsConfigPath: options.tsConfig, + mode: 'noEmit', }); - const exitCode = await spawnChecker(typeCheckCommand); - if (exitCode !== 0) { - process.exit(exitCode); - } -} - -function spawnChecker(typeCheckCommand: string) { - return new Promise((r) => { - const proc = spawn(typeCheckCommand, { - cwd: process.cwd(), - stdio: 'inherit', - env: process.env, - // shell is necessary on windows to get the process to even start. - // Command line args constructed by checkers therefore need to escape double quotes - // to have them not striped out by cmd.exe. Using shell on all platforms lets us avoid - // having to perform platform-specific logic around escaping quotes since all platform - // shells will strip out unescaped double quotes. E.g. shell=false on linux only would - // result in escaped quotes not being unescaped. - shell: true, - }); + await printDiagnostics(result.errors, result.warnings); - proc.on('exit', (code) => { - if (code !== null && code !== 0) { - r(code); - } else { - r(0); - } - }); - }); + if (result.errors.length > 0) { + throw new Error('Found type errors. See above.'); + } } \ No newline at end of file