Skip to content

Commit e162d01

Browse files
fix(nx-infra-plugin): support spaces in workspace path (DevExpress#33514)
Co-authored-by: Aliullov Vlad <91639107+GoodDayForSurf@users.noreply.github.com>
1 parent 7e7dfbd commit e162d01

1 file changed

Lines changed: 38 additions & 63 deletions

File tree

  • packages/nx-infra-plugin/scripts

packages/nx-infra-plugin/scripts/build.ts

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { execSync } from 'child_process';
21
import * as fs from 'fs';
32
import * as path from 'path';
3+
import * as ts from 'typescript';
44

55
const DIST_DIR_NAME = 'dist';
66
const SRC_DIR_NAME = 'src';
7-
const TEMP_TSCONFIG_NAME = 'tsconfig.bootstrap.json';
87
const TSCONFIG_LIB_NAME = 'tsconfig.lib.json';
98
const EXECUTORS_JSON_NAME = 'executors.json';
109
const JSON_EXTENSION = '.json';
@@ -17,13 +16,6 @@ interface PathConfig {
1716
tsconfig: string;
1817
}
1918

20-
interface TsConfig {
21-
extends?: string;
22-
compilerOptions?: Record<string, unknown>;
23-
include?: string[];
24-
exclude?: string[];
25-
}
26-
2719
interface CompilationResult {
2820
success: boolean;
2921
error?: string;
@@ -49,38 +41,39 @@ const checkDistExists = (distPath: string): boolean => {
4941
return files.length > 0;
5042
};
5143

52-
const readTsConfig = (configPath: string): TsConfig => {
53-
const content = fs.readFileSync(configPath, 'utf8');
54-
return JSON.parse(content);
44+
const formatDiagnostics = (diagnostics: readonly ts.Diagnostic[]): string => {
45+
const host: ts.FormatDiagnosticsHost = {
46+
getCanonicalFileName: (f) => f,
47+
getCurrentDirectory: ts.sys.getCurrentDirectory,
48+
getNewLine: () => ts.sys.newLine,
49+
};
50+
return ts.formatDiagnosticsWithColorAndContext(diagnostics, host);
5551
};
5652

57-
const createBootstrapConfig = (original: TsConfig): TsConfig => ({
58-
...original,
59-
compilerOptions: {
60-
...original.compilerOptions,
61-
rootDir: undefined,
62-
outDir: `./${DIST_DIR_NAME}`,
63-
},
64-
});
65-
66-
const writeTsConfig = (configPath: string, config: TsConfig): void => {
67-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
68-
};
53+
const compileTypeScript = (configPath: string): CompilationResult => {
54+
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
55+
if (configFile.error) {
56+
return { success: false, error: formatDiagnostics([configFile.error]) };
57+
}
6958

70-
const compileTypeScript = (pluginDir: string, configPath: string): CompilationResult => {
71-
try {
72-
execSync(`pnpm exec tsc -p ${configPath}`, {
73-
cwd: pluginDir,
74-
stdio: 'inherit',
75-
env: { ...process.env, NODE_ENV: 'production' },
76-
});
77-
return { success: true };
78-
} catch (error) {
79-
return {
80-
success: false,
81-
error: (error as Error).message,
82-
};
59+
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
60+
if (parsed.errors.length > 0) {
61+
return { success: false, error: formatDiagnostics(parsed.errors) };
62+
}
63+
64+
const program = ts.createProgram({
65+
rootNames: parsed.fileNames,
66+
options: parsed.options,
67+
projectReferences: parsed.projectReferences,
68+
});
69+
70+
const emitResult = program.emit();
71+
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
72+
73+
if (emitResult.emitSkipped || diagnostics.length > 0) {
74+
return { success: false, error: formatDiagnostics(diagnostics) };
8375
}
76+
return { success: true };
8477
};
8578

8679
const isJsonAsset = (filename: string): boolean =>
@@ -144,12 +137,6 @@ const copyExecutorsJson = (pluginDir: string, distDir: string): boolean => {
144137
return true;
145138
};
146139

147-
const cleanupTempConfig = (configPath: string): void => {
148-
if (fs.existsSync(configPath)) {
149-
fs.unlinkSync(configPath);
150-
}
151-
};
152-
153140
const shouldSkipBuild = (distPath: string, forceRebuild: boolean): boolean => {
154141
if (forceRebuild) return false;
155142
return checkDistExists(distPath);
@@ -162,28 +149,16 @@ const buildPlugin = (paths: PathConfig, forceRebuild = false): void => {
162149
}
163150

164151
console.log(' Compiling TypeScript...');
152+
const result = compileTypeScript(paths.tsconfig);
153+
if (!result.success) {
154+
throw new Error(result.error);
155+
}
165156

166-
const tempConfigPath = path.join(paths.pluginDir, TEMP_TSCONFIG_NAME);
167-
const originalConfig = readTsConfig(paths.tsconfig);
168-
const bootstrapConfig = createBootstrapConfig(originalConfig);
169-
170-
writeTsConfig(tempConfigPath, bootstrapConfig);
171-
172-
try {
173-
const result = compileTypeScript(paths.pluginDir, tempConfigPath);
174-
if (!result.success) {
175-
throw new Error(result.error);
176-
}
177-
178-
console.log(' Copying assets...');
179-
copyJsonAssets(paths.srcDir, paths.distDir);
180-
181-
copyExecutorsJson(paths.pluginDir, paths.distDir);
157+
console.log(' Copying assets...');
158+
copyJsonAssets(paths.srcDir, paths.distDir);
159+
copyExecutorsJson(paths.pluginDir, paths.distDir);
182160

183-
console.log('✓ Plugin built successfully!');
184-
} finally {
185-
cleanupTempConfig(tempConfigPath);
186-
}
161+
console.log('✓ Plugin built successfully!');
187162
};
188163

189164
const parseArgs = (): { forceRebuild: boolean } => {

0 commit comments

Comments
 (0)