fix(js): node executor should always log error (#17622)

This commit is contained in:
Katerina Skroumpelou 2023-06-16 19:45:05 +03:00 committed by GitHub
parent bfe8e47d23
commit 36838d6211
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 23 deletions

View File

@ -0,0 +1,50 @@
import {
cleanupProject,
newProject,
runCLI,
uniq,
updateFile,
updateProjectConfig,
} from '@nx/e2e/utils';
describe('js:node error handling', () => {
let scope: string;
beforeEach(() => {
scope = newProject();
});
afterEach(() => cleanupProject());
it('should log out the error', () => {
const esbuildLib = uniq('esbuildlib');
runCLI(
`generate @nx/js:lib ${esbuildLib} --bundler=esbuild --no-interactive`
);
updateFile(`libs/${esbuildLib}/src/index.ts`, () => {
return `
console.log('Hello from my library!');
throw new Error('This is an error');
`;
});
updateProjectConfig(esbuildLib, (config) => {
config.targets['run-node'] = {
executor: '@nx/js:node',
options: {
buildTarget: `${esbuildLib}:build`,
watch: false,
},
};
return config;
});
const output = runCLI(`run ${esbuildLib}:run-node`, {
redirectStderr: true,
});
expect(output).toContain('Hello from my library!');
expect(output).toContain('This is an error');
}, 240_000);
});

View File

@ -23,6 +23,7 @@ export interface RunCmdOpts {
cwd?: string;
silent?: boolean;
verbose?: boolean;
redirectStderr?: boolean;
}
/**
@ -325,26 +326,25 @@ export function runCLI(
silenceError: false,
env: undefined,
verbose: undefined,
redirectStderr: undefined,
}
): string {
try {
const pm = getPackageManagerCommand();
const logs = execSync(
`${pm.runNxSilent} ${command} ${
opts.verbose ?? isVerboseE2ERun() ? ' --verbose' : ''
}`,
{
cwd: opts.cwd || tmpProjPath(),
env: {
CI: 'true',
...getStrippedEnvironmentVariables(),
...opts.env,
},
encoding: 'utf-8',
stdio: 'pipe',
maxBuffer: 50 * 1024 * 1024,
}
);
const commandToRun = `${pm.runNxSilent} ${command} ${
opts.verbose ?? isVerboseE2ERun() ? ' --verbose' : ''
}${opts.redirectStderr ? ' 2>&1' : ''}`;
const logs = execSync(commandToRun, {
cwd: opts.cwd || tmpProjPath(),
env: {
CI: 'true',
...getStrippedEnvironmentVariables(),
...opts.env,
},
encoding: 'utf-8',
stdio: 'pipe',
maxBuffer: 50 * 1024 * 1024,
});
if (opts.verbose ?? isVerboseE2ERun()) {
output.log({

View File

@ -10,11 +10,13 @@ import {
import { daemonClient } from 'nx/src/daemon/client/client';
import { randomUUID } from 'crypto';
import { join } from 'path';
import * as path from 'path';
import { InspectType, NodeExecutorOptions } from './schema';
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';
import { calculateProjectDependencies } from '../../utils/buildable-libs-utils';
import { killTree } from './lib/kill-tree';
import { fileExists } from 'nx/src/utils/fileutils';
interface ActiveTask {
id: string;
@ -71,12 +73,11 @@ export async function* nodeExecutor(
// Re-map buildable workspace projects to their output directory.
const mappings = calculateResolveMappings(context, options);
const fileToRun = join(
context.root,
buildOptions.outputPath,
buildOptions.outputFileName ?? 'main.js'
);
const outputFileName =
buildOptions.outputFileName ?? `${path.parse(buildOptions.main).name}.js`;
const fileToRun = join(context.root, buildOptions.outputPath, outputFileName);
const tasks: ActiveTask[] = [];
let currentTask: ActiveTask = null;
@ -159,7 +160,7 @@ export async function* nodeExecutor(
stdio: [0, 1, 'pipe', 'ipc'],
env: {
...process.env,
NX_FILE_TO_RUN: fileToRun,
NX_FILE_TO_RUN: fileToRunCorrectPath(fileToRun),
NX_MAPPINGS: JSON.stringify(mappings),
},
}
@ -168,7 +169,8 @@ export async function* nodeExecutor(
task.childProcess.stderr.on('data', (data) => {
// Don't log out error if task is killed and new one has started.
// This could happen if a new build is triggered while new process is starting, since the operation is not atomic.
if (options.watch && !task.killed) {
// Log the error in normal mode
if (!options.watch || !task.killed) {
logger.error(data.toString());
}
});
@ -304,4 +306,23 @@ function runWaitUntilTargets(
);
}
function fileToRunCorrectPath(fileToRun: string): string {
if (!fileExists(fileToRun)) {
const cjsFile = fileToRun.replace(/\.js$/, '.cjs');
if (fileExists(cjsFile)) {
fileToRun = cjsFile;
} else {
const mjsFile = fileToRun.replace(/\.js$/, '.mjs');
if (fileExists(mjsFile)) {
fileToRun = mjsFile;
} else {
throw new Error(
`Could not find ${fileToRun}. Make sure your build succeeded.`
);
}
}
}
return fileToRun;
}
export default nodeExecutor;