fix(angular): change tsconfig path handling for angular ng-packagr executors to let ng-packagr use default options (#7702)

This commit is contained in:
Leosvel Pérez Espinosa 2021-11-11 16:09:11 +00:00 committed by GitHub
parent d1f276af52
commit 23415a5060
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 66 deletions

View File

@ -1,4 +1,3 @@
jest.mock('ng-packagr/lib/utils/ng-compiler-cli');
jest.mock('@nrwl/workspace/src/core/project-graph'); jest.mock('@nrwl/workspace/src/core/project-graph');
jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils'); jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils');
jest.mock('ng-packagr'); jest.mock('ng-packagr');
@ -13,7 +12,6 @@ import {
NX_PACKAGE_PROVIDERS, NX_PACKAGE_PROVIDERS,
NX_PACKAGE_TRANSFORM, NX_PACKAGE_TRANSFORM,
} from './ng-packagr-adjustments/package.di'; } from './ng-packagr-adjustments/package.di';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import ngPackagrLiteExecutor from './ng-packagr-lite.impl'; import ngPackagrLiteExecutor from './ng-packagr-lite.impl';
describe('NgPackagrLite executor', () => { describe('NgPackagrLite executor', () => {
@ -24,14 +22,8 @@ describe('NgPackagrLite executor', () => {
let ngPackagrWithBuildTransformMock: jest.Mock; let ngPackagrWithBuildTransformMock: jest.Mock;
let ngPackagrWithTsConfigMock: jest.Mock; let ngPackagrWithTsConfigMock: jest.Mock;
let options: BuildAngularLibraryExecutorOptions; let options: BuildAngularLibraryExecutorOptions;
let tsConfig: { options: { paths: { [key: string]: string[] } } };
beforeEach(async () => { beforeEach(async () => {
tsConfig = {
options: {
paths: { '@myorg/my-package': ['/root/my-package/src/index.ts'] },
},
};
( (
buildableLibsUtils.calculateProjectDependencies as jest.Mock buildableLibsUtils.calculateProjectDependencies as jest.Mock
).mockImplementation(() => ({ ).mockImplementation(() => ({
@ -57,7 +49,8 @@ describe('NgPackagrLite executor', () => {
projectName: 'my-lib', projectName: 'my-lib',
targetName: 'build', targetName: 'build',
configurationName: 'production', configurationName: 'production',
} as ExecutorContext; workspace: { projects: { 'my-lib': { root: '/libs/my-lib' } } },
} as any;
options = { project: 'my-lib' }; options = { project: 'my-lib' };
}); });
@ -104,31 +97,39 @@ describe('NgPackagrLite executor', () => {
expect(result.done).toBe(true); expect(result.done).toBe(true);
}); });
it('should not set up incremental builds when tsConfig option is not set', async () => {
(
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true);
const result = await ngPackagrLiteExecutor(options, context).next();
expect(buildableLibsUtils.createTmpTsConfig).not.toHaveBeenCalled();
expect(ngPackagrWithTsConfigMock).not.toHaveBeenCalled();
expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true);
});
it('should process tsConfig for incremental builds when tsConfig options is set', async () => { it('should process tsConfig for incremental builds when tsConfig options is set', async () => {
// ARRANGE // ARRANGE
( (
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true); ).mockReturnValue(true);
const generatedTsConfig = '/root/tmp/my-lib/tsconfig.app.generated.json';
(ngCompilerCli as jest.Mock).mockImplementation(() => (buildableLibsUtils.createTmpTsConfig as jest.Mock).mockImplementation(
Promise.resolve({ () => generatedTsConfig
readConfiguration: (...args) => tsConfig,
})
); );
const tsConfigPath = '/root/my-lib/tsconfig.app.json';
// ACT // ACT
const result = await ngPackagrLiteExecutor( const result = await ngPackagrLiteExecutor(
{ ...options, tsConfig: tsConfigPath }, { ...options, tsConfig: '/root/my-lib/tsconfig.app.json' },
context context
).next(); ).next();
// ASSERT // ASSERT
expect(buildableLibsUtils.updatePaths).toHaveBeenCalledWith( expect(buildableLibsUtils.createTmpTsConfig).toHaveBeenCalled();
expect.any(Array), expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(generatedTsConfig);
tsConfig.options.paths
);
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(tsConfig);
expect(ngPackagrBuildMock).toHaveBeenCalled(); expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true }); expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true); expect(result.done).toBe(true);

View File

@ -1,8 +1,9 @@
import type { ExecutorContext } from '@nrwl/devkit'; import type { ExecutorContext } from '@nrwl/devkit';
import type { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/buildable-libs-utils'; import {
import { updatePaths } from '@nrwl/workspace/src/utilities/buildable-libs-utils'; createTmpTsConfig,
DependentBuildableProjectNode,
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import { NgPackagr } from 'ng-packagr'; import { NgPackagr } from 'ng-packagr';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { resolve } from 'path'; import { resolve } from 'path';
import { createLibraryExecutor } from '../package/package.impl'; import { createLibraryExecutor } from '../package/package.impl';
import type { BuildAngularLibraryExecutorOptions } from '../package/schema'; import type { BuildAngularLibraryExecutorOptions } from '../package/schema';
@ -26,13 +27,13 @@ async function initializeNgPackgrLite(
packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide); packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide);
if (options.tsConfig) { if (options.tsConfig) {
// read the tsconfig and modify its path in memory to const tsConfigPath = createTmpTsConfig(
// pass it on to ngpackagr options.tsConfig,
const parsedTSConfig = (await ngCompilerCli()).readConfiguration( context.root,
options.tsConfig context.workspace.projects[context.projectName].root,
projectDependencies
); );
updatePaths(projectDependencies, parsedTSConfig.options.paths); packager.withTsConfig(tsConfigPath);
packager.withTsConfig(parsedTSConfig);
} }
return packager; return packager;

View File

@ -1,4 +1,3 @@
jest.mock('ng-packagr/lib/utils/ng-compiler-cli');
jest.mock('@nrwl/workspace/src/core/project-graph'); jest.mock('@nrwl/workspace/src/core/project-graph');
jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils'); jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils');
jest.mock('ng-packagr'); jest.mock('ng-packagr');
@ -6,8 +5,12 @@ jest.mock('ng-packagr');
import type { ExecutorContext } from '@nrwl/devkit'; import type { ExecutorContext } from '@nrwl/devkit';
import * as buildableLibsUtils from '@nrwl/workspace/src/utilities/buildable-libs-utils'; import * as buildableLibsUtils from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import * as ngPackagr from 'ng-packagr'; import * as ngPackagr from 'ng-packagr';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import {
NX_PACKAGE_PROVIDERS,
NX_PACKAGE_TRANSFORM,
} from './ng-packagr-adjustments/ng-package/package.di';
import packageExecutor from './package.impl'; import packageExecutor from './package.impl';
import type { BuildAngularLibraryExecutorOptions } from './schema'; import type { BuildAngularLibraryExecutorOptions } from './schema';
@ -45,7 +48,8 @@ describe('Package executor', () => {
projectName: 'my-lib', projectName: 'my-lib',
targetName: 'build', targetName: 'build',
configurationName: 'production', configurationName: 'production',
} as ExecutorContext; workspace: { projects: { 'my-lib': { root: '/libs/my-lib' } } },
} as any;
options = { project: 'my-lib' }; options = { project: 'my-lib' };
}); });
@ -74,49 +78,54 @@ describe('Package executor', () => {
expect(result.done).toBe(true); expect(result.done).toBe(true);
}); });
it('should instantiate NgPackager with the right providers and set to use the right build transformation provider', async () => {
(
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true);
const result = await packageExecutor(options, context).next();
expect(ngPackagr.NgPackagr).toHaveBeenCalledWith([
...NX_PACKAGE_PROVIDERS,
...NX_ENTRY_POINT_PROVIDERS,
]);
expect(ngPackagrWithBuildTransformMock).toHaveBeenCalledWith(
NX_PACKAGE_TRANSFORM.provide
);
expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true);
});
it('should not set up incremental builds when tsConfig option is not set', async () => { it('should not set up incremental builds when tsConfig option is not set', async () => {
( (
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true); ).mockReturnValue(true);
(ngCompilerCli as jest.Mock).mockImplementation(() =>
Promise.resolve({ readConfiguration: jest.fn() })
);
const result = await packageExecutor(options, context).next(); const result = await packageExecutor(options, context).next();
expect((await ngCompilerCli()).readConfiguration).not.toHaveBeenCalled(); expect(buildableLibsUtils.createTmpTsConfig).not.toHaveBeenCalled();
expect(buildableLibsUtils.updatePaths).not.toHaveBeenCalled();
expect(ngPackagrWithTsConfigMock).not.toHaveBeenCalled(); expect(ngPackagrWithTsConfigMock).not.toHaveBeenCalled();
expect(ngPackagrBuildMock).toHaveBeenCalled(); expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true }); expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true); expect(result.done).toBe(true);
}); });
it('should process tsConfig for incremental builds when tsConfig option is set and enableIvy is true', async () => { it('should process tsConfig for incremental builds when tsConfig option is set', async () => {
( (
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true); ).mockReturnValue(true);
const tsConfig = { const generatedTsConfig = '/root/tmp/my-lib/tsconfig.app.generated.json';
options: { (buildableLibsUtils.createTmpTsConfig as jest.Mock).mockImplementation(
paths: { '@myorg/my-package': ['/root/my-package/src/index.ts'] }, () => generatedTsConfig
enableIvy: true,
},
};
(ngCompilerCli as jest.Mock).mockImplementation(() =>
Promise.resolve({ readConfiguration: () => tsConfig })
); );
const tsConfigPath = '/root/my-lib/tsconfig.app.json';
const result = await packageExecutor( const result = await packageExecutor(
{ ...options, tsConfig: tsConfigPath }, { ...options, tsConfig: '/root/my-lib/tsconfig.app.json' },
context context
).next(); ).next();
expect(buildableLibsUtils.updatePaths).toHaveBeenCalledWith( expect(buildableLibsUtils.createTmpTsConfig).toHaveBeenCalled();
expect.any(Array), expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(generatedTsConfig);
tsConfig.options.paths
);
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(tsConfig);
expect(ngPackagrBuildMock).toHaveBeenCalled(); expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true }); expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true); expect(result.done).toBe(true);

View File

@ -1,19 +1,19 @@
import type { ExecutorContext } from '@nrwl/devkit'; import type { ExecutorContext } from '@nrwl/devkit';
import { readCachedProjectGraph } from '@nrwl/workspace/src/core/project-graph'; import { readCachedProjectGraph } from '@nrwl/workspace/src/core/project-graph';
import type { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/buildable-libs-utils'; import {
createTmpTsConfig,
DependentBuildableProjectNode,
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import { import {
calculateProjectDependencies, calculateProjectDependencies,
checkDependentProjectsHaveBeenBuilt, checkDependentProjectsHaveBeenBuilt,
updateBuildableProjectPackageJsonDependencies, updateBuildableProjectPackageJsonDependencies,
updatePaths,
} from '@nrwl/workspace/src/utilities/buildable-libs-utils'; } from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import type { NgPackagr } from 'ng-packagr'; import type { NgPackagr } from 'ng-packagr';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { resolve } from 'path'; import { resolve } from 'path';
import { from } from 'rxjs'; import { from } from 'rxjs';
import { eachValueFrom } from 'rxjs-for-await'; import { eachValueFrom } from 'rxjs-for-await';
import { mapTo, switchMap, tap } from 'rxjs/operators'; import { mapTo, switchMap, tap } from 'rxjs/operators';
import * as ts from 'typescript';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di'; import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import { import {
NX_PACKAGE_PROVIDERS, NX_PACKAGE_PROVIDERS,
@ -34,16 +34,14 @@ async function initializeNgPackagr(
packager.forProject(resolve(context.root, options.project)); packager.forProject(resolve(context.root, options.project));
packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide); packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide);
// read the tsconfig and modify its path in memory to
// pass it on to ngpackagr if specified
if (options.tsConfig) { if (options.tsConfig) {
// read the tsconfig and modify its path in memory to const tsConfigPath = createTmpTsConfig(
// pass it on to ngpackagr options.tsConfig,
const parsedTSConfig = (await ngCompilerCli()).readConfiguration( context.root,
options.tsConfig context.workspace.projects[context.projectName].root,
projectDependencies
); );
updatePaths(projectDependencies, parsedTSConfig.options.paths); packager.withTsConfig(tsConfigPath);
packager.withTsConfig(parsedTSConfig);
} }
return packager; return packager;