From 3fd6ec6466dad035037028b68f7297e0ea523b19 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Thu, 15 Jun 2023 20:25:02 +0300 Subject: [PATCH] fix(js): node executor should always log error --- e2e/js/src/js-node.test.ts | 49 +++++++++++++++++++ packages/js/src/executors/node/node.impl.ts | 21 +++++--- packages/js/src/utils/buildable-libs-utils.ts | 9 ++++ 3 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 e2e/js/src/js-node.test.ts diff --git a/e2e/js/src/js-node.test.ts b/e2e/js/src/js-node.test.ts new file mode 100644 index 00000000000000..577ac7a601aa74 --- /dev/null +++ b/e2e/js/src/js-node.test.ts @@ -0,0 +1,49 @@ +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`); + + expect(output).toContain('Hello from my library!'); + expect(output).toContain('This is an error'); + }, 240_000); +}); diff --git a/packages/js/src/executors/node/node.impl.ts b/packages/js/src/executors/node/node.impl.ts index a186f149174a46..3775a2465f5236 100644 --- a/packages/js/src/executors/node/node.impl.ts +++ b/packages/js/src/executors/node/node.impl.ts @@ -13,7 +13,10 @@ import { join } from 'path'; import { InspectType, NodeExecutorOptions } from './schema'; import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable'; -import { calculateProjectDependencies } from '../../utils/buildable-libs-utils'; +import { + calculateProjectDependencies, + getOutputFileName, +} from '../../utils/buildable-libs-utils'; import { killTree } from './lib/kill-tree'; interface ActiveTask { @@ -71,11 +74,14 @@ 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' - ); + + let outputFileName = buildOptions.outputFileName; + + if (!outputFileName) { + outputFileName = getOutputFileName(buildOptions.main); + } + + let fileToRun = join(context.root, buildOptions.outputPath, outputFileName); const tasks: ActiveTask[] = []; let currentTask: ActiveTask = null; @@ -168,7 +174,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()); } }); diff --git a/packages/js/src/utils/buildable-libs-utils.ts b/packages/js/src/utils/buildable-libs-utils.ts index 0801a959fd2fb6..174ea2bd968918 100644 --- a/packages/js/src/utils/buildable-libs-utils.ts +++ b/packages/js/src/utils/buildable-libs-utils.ts @@ -424,3 +424,12 @@ function hasDependency(outputJson, depConfigName: string, packageName: string) { return false; } } + +export function getOutputFileName(path: string): string { + const filename: string = path.split('/').pop() || ''; + const filenameWithoutExtension: string = filename + .split('.') + .slice(0, -1) + .join('.'); + return `${filenameWithoutExtension}.js`; +}