From 688d076cbb496a5658e9e4cb55e3fac07662d294 Mon Sep 17 00:00:00 2001 From: Jay Tavares Date: Fri, 29 Apr 2022 15:47:44 -0400 Subject: [PATCH 1/2] feat(node): add deleteOutputPath option to @nrwl/node:webpack executor ISSUES CLOSED: #9167 --- docs/generated/packages/node.json | 5 +++ e2e/node/src/node.test.ts | 37 +++++++++++++++++++ .../node/src/executors/webpack/schema.json | 5 +++ .../src/executors/webpack/webpack.impl.ts | 6 +++ packages/node/src/utils/fs.ts | 14 +++++++ packages/node/src/utils/types.ts | 1 + 6 files changed, 68 insertions(+) create mode 100644 packages/node/src/utils/fs.ts diff --git a/docs/generated/packages/node.json b/docs/generated/packages/node.json index a8b6de20a022f..aba8267776732 100644 --- a/docs/generated/packages/node.json +++ b/docs/generated/packages/node.json @@ -291,6 +291,11 @@ "type": "string", "description": "The output path of the generated files." }, + "deleteOutputPath": { + "type": "boolean", + "description": "Delete the output path before building.", + "default": true + }, "watch": { "type": "boolean", "description": "Run build when files change.", diff --git a/e2e/node/src/node.test.ts b/e2e/node/src/node.test.ts index e5e30904d38c4..45982880ddc33 100644 --- a/e2e/node/src/node.test.ts +++ b/e2e/node/src/node.test.ts @@ -1,5 +1,6 @@ import { stripIndents } from '@angular-devkit/core/src/utils/literals'; import { + createFile, checkFilesDoNotExist, checkFilesExist, expectJestTestsToPass, @@ -309,6 +310,42 @@ ${jslib}(); expect(nodeAppPackageJson['dependencies']['tslib']).toBeTruthy(); }, 300000); + it('should remove previous output before building with the --deleteOutputPath option set', async () => { + const appName = uniq('app'); + const libName = uniq('lib'); + + runCLI( + `generate @nrwl/node:app ${appName} --no-interactive --compiler swc` + ); + runCLI( + `generate @nrwl/node:lib ${libName} --buildable --no-interactive --compiler swc` + ); + + createFile(`dist/apps/${appName}/_should_remove.txt`); + createFile(`dist/libs/${libName}/_should_remove.txt`); + createFile(`dist/apps/_should_not_remove.txt`); + checkFilesExist( + `dist/apps/${appName}/_should_remove.txt`, + `dist/apps/_should_not_remove.txt` + ); + runCLI(`build ${appName} --outputHashing none`); + runCLI(`build ${libName}`); + checkFilesDoNotExist( + `dist/apps/${appName}/_should_remove.txt`, + `dist/libs/${libName}/_should_remove.txt` + ); + checkFilesExist(`dist/apps/_should_not_remove.txt`); + + // `delete-output-path` + createFile(`dist/apps/${appName}/_should_keep.txt`); + runCLI(`build ${appName} --delete-output-path=false --outputHashing none`); + checkFilesExist(`dist/apps/${appName}/_should_keep.txt`); + + createFile(`dist/libs/${libName}/_should_keep.txt`); + runCLI(`build ${libName} --delete-output-path=false --outputHashing none`); + checkFilesExist(`dist/libs/${libName}/_should_keep.txt`); + }, 120000); + describe('NestJS', () => { it('should have plugin output if specified in `tsPlugins`', async () => { newProject(); diff --git a/packages/node/src/executors/webpack/schema.json b/packages/node/src/executors/webpack/schema.json index d5ad246ed3ba9..923723cec9a77 100644 --- a/packages/node/src/executors/webpack/schema.json +++ b/packages/node/src/executors/webpack/schema.json @@ -16,6 +16,11 @@ "type": "string", "description": "The output path of the generated files." }, + "deleteOutputPath": { + "type": "boolean", + "description": "Delete the output path before building.", + "default": true + }, "watch": { "type": "boolean", "description": "Run build when files change.", diff --git a/packages/node/src/executors/webpack/webpack.impl.ts b/packages/node/src/executors/webpack/webpack.impl.ts index bdc71d4392d5c..76e6307c917a6 100644 --- a/packages/node/src/executors/webpack/webpack.impl.ts +++ b/packages/node/src/executors/webpack/webpack.impl.ts @@ -17,6 +17,7 @@ import { register } from 'ts-node'; import { getNodeWebpackConfig } from '../../utils/node.config'; import { BuildNodeBuilderOptions } from '../../utils/types'; import { normalizeBuildOptions } from '../../utils/normalize'; +import { deleteOutputDir } from '../../utils/fs'; import { runWebpack } from '../../utils/run-webpack'; export type NodeBuildEvent = { @@ -77,6 +78,11 @@ export async function* webpackExecutor( } } + // Delete output path before bundling + if (options.deleteOutputPath) { + deleteOutputDir(context.root, options.outputPath); + } + const config = await options.webpackConfig.reduce( async (currentConfig, plugin) => { return require(plugin)(await currentConfig, { diff --git a/packages/node/src/utils/fs.ts b/packages/node/src/utils/fs.ts new file mode 100644 index 0000000000000..76948da59bd61 --- /dev/null +++ b/packages/node/src/utils/fs.ts @@ -0,0 +1,14 @@ +import * as path from 'path'; +import { removeSync } from 'fs-extra'; + +/** + * Delete an output directory, but error out if it's the root of the project. + */ +export function deleteOutputDir(root: string, outputPath: string) { + const resolvedOutputPath = path.resolve(root, outputPath); + if (resolvedOutputPath === root) { + throw new Error('Output path MUST not be project root directory!'); + } + + removeSync(resolvedOutputPath); +} diff --git a/packages/node/src/utils/types.ts b/packages/node/src/utils/types.ts index a56934941bf37..cd51238ca7e27 100644 --- a/packages/node/src/utils/types.ts +++ b/packages/node/src/utils/types.ts @@ -96,6 +96,7 @@ export interface BuildNodeBuilderOptions extends BuildBuilderOptions { externalDependencies: 'all' | 'none' | string[]; buildLibsFromSource?: boolean; generatePackageJson?: boolean; + deleteOutputPath?: boolean; } export interface NormalizedBuildNodeBuilderOptions From 845a2f5e7e2b103dcbecd28f631d2772113da8f9 Mon Sep 17 00:00:00 2001 From: Jay Tavares Date: Wed, 8 Jun 2022 15:01:03 -0400 Subject: [PATCH 2/2] fix(node): fix deleteOutputPath implementation Ensure that generated package.json is retained Remove lib from e2e test since it uses @nrwl/js:tsc executor Add deleteOutputPath to schema normalization --- e2e/node/src/node.test.ts | 93 ++++++++++++++-------------- packages/node/src/utils/normalize.ts | 1 + 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/e2e/node/src/node.test.ts b/e2e/node/src/node.test.ts index 45982880ddc33..db9b82804307f 100644 --- a/e2e/node/src/node.test.ts +++ b/e2e/node/src/node.test.ts @@ -312,38 +312,37 @@ ${jslib}(); it('should remove previous output before building with the --deleteOutputPath option set', async () => { const appName = uniq('app'); - const libName = uniq('lib'); - runCLI( - `generate @nrwl/node:app ${appName} --no-interactive --compiler swc` - ); - runCLI( - `generate @nrwl/node:lib ${libName} --buildable --no-interactive --compiler swc` - ); + runCLI(`generate @nrwl/node:app ${appName} --no-interactive`); + // deleteOutputPath should default to true createFile(`dist/apps/${appName}/_should_remove.txt`); - createFile(`dist/libs/${libName}/_should_remove.txt`); createFile(`dist/apps/_should_not_remove.txt`); checkFilesExist( `dist/apps/${appName}/_should_remove.txt`, `dist/apps/_should_not_remove.txt` ); - runCLI(`build ${appName} --outputHashing none`); - runCLI(`build ${libName}`); - checkFilesDoNotExist( + runCLI(`build ${appName} --outputHashing none`); // no explicit deleteOutputPath option set + checkFilesDoNotExist(`dist/apps/${appName}/_should_remove.txt`); + checkFilesExist(`dist/apps/_should_not_remove.txt`); + + // Explicitly set `deleteOutputPath` to true + createFile(`dist/apps/${appName}/_should_remove.txt`); + createFile(`dist/apps/_should_not_remove.txt`); + checkFilesExist( `dist/apps/${appName}/_should_remove.txt`, - `dist/libs/${libName}/_should_remove.txt` + `dist/apps/_should_not_remove.txt` ); + runCLI(`build ${appName} --outputHashing none --deleteOutputPath`); + checkFilesDoNotExist(`dist/apps/${appName}/_should_remove.txt`); checkFilesExist(`dist/apps/_should_not_remove.txt`); - // `delete-output-path` + // Explicitly set `deleteOutputPath` to false createFile(`dist/apps/${appName}/_should_keep.txt`); - runCLI(`build ${appName} --delete-output-path=false --outputHashing none`); + createFile(`dist/apps/_should_keep.txt`); + runCLI(`build ${appName} --deleteOutputPath=false --outputHashing none`); checkFilesExist(`dist/apps/${appName}/_should_keep.txt`); - - createFile(`dist/libs/${libName}/_should_keep.txt`); - runCLI(`build ${libName} --delete-output-path=false --outputHashing none`); - checkFilesExist(`dist/libs/${libName}/_should_keep.txt`); + checkFilesExist(`dist/apps/_should_keep.txt`); }, 120000); describe('NestJS', () => { @@ -362,35 +361,35 @@ ${jslib}(); updateFile( `apps/${nestapp}/src/app/foo.dto.ts`, ` -export class FooDto { - foo: string; - bar: number; -}` + export class FooDto { + foo: string; + bar: number; + }` ); updateFile( `apps/${nestapp}/src/app/app.controller.ts`, ` -import { Controller, Get } from '@nestjs/common'; -import { FooDto } from './foo.dto'; -import { AppService } from './app.service'; + import { Controller, Get } from '@nestjs/common'; + import { FooDto } from './foo.dto'; + import { AppService } from './app.service'; -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} + @Controller() + export class AppController { + constructor(private readonly appService: AppService) {} - @Get() - getData() { - return this.appService.getData(); - } + @Get() + getData() { + return this.appService.getData(); + } - @Get('foo') - getFoo(): Promise { - return Promise.resolve({ - foo: 'foo', - bar: 123 - }) - } -}` + @Get('foo') + getFoo(): Promise { + return Promise.resolve({ + foo: 'foo', + bar: 123 + }) + } + }` ); await runCLIAsync(`build ${nestapp}`); @@ -398,13 +397,13 @@ export class AppController { const mainJs = readFile(`dist/apps/${nestapp}/main.js`); expect(stripIndents`${mainJs}`).toContain( stripIndents` -class FooDto { - static _OPENAPI_METADATA_FACTORY() { - return { foo: { required: true, type: () => String }, bar: { required: true, type: () => Number } }; - } -} -exports.FooDto = FooDto; - ` + class FooDto { + static _OPENAPI_METADATA_FACTORY() { + return { foo: { required: true, type: () => String }, bar: { required: true, type: () => Number } }; + } + } + exports.FooDto = FooDto; + ` ); }, 300000); }); diff --git a/packages/node/src/utils/normalize.ts b/packages/node/src/utils/normalize.ts index 8dbd7281e5db1..413cb7349ab2c 100644 --- a/packages/node/src/utils/normalize.ts +++ b/packages/node/src/utils/normalize.ts @@ -37,6 +37,7 @@ export function normalizeBuildOptions( options.additionalEntryPoints ?? [] ), outputFileName: options.outputFileName ?? 'main.js', + deleteOutputPath: options.deleteOutputPath ?? true, }; }