Skip to content

Commit

Permalink
fix(angular): ensure paths are resolved correctly in ng-packagr execu…
Browse files Browse the repository at this point in the history
…tors (#13059)
  • Loading branch information
leosvelperez committed Nov 9, 2022
1 parent 0432279 commit 6bc3720
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
jest.mock('@nrwl/devkit');
jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils');
jest.mock('ng-packagr');
jest.mock('ng-packagr/lib/utils/ng-compiler-cli');
jest.mock('./ng-packagr-adjustments/ng-package/options.di');

import type { ExecutorContext } from '@nrwl/devkit';
import * as buildableLibsUtils from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import * as ngPackagr from 'ng-packagr';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { BehaviorSubject } from 'rxjs';
import type { BuildAngularLibraryExecutorOptions } from '../package/schema';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
Expand All @@ -23,6 +25,7 @@ describe('NgPackagrLite executor', () => {
let ngPackagrWatchMock: jest.Mock;
let ngPackagrWithBuildTransformMock: jest.Mock;
let ngPackagrWithTsConfigMock: jest.Mock;
let ngCliReadConfigurationMock: jest.Mock;
let options: BuildAngularLibraryExecutorOptions;

beforeEach(async () => {
Expand All @@ -46,6 +49,10 @@ describe('NgPackagrLite executor', () => {
withBuildTransform: ngPackagrWithBuildTransformMock,
withTsConfig: ngPackagrWithTsConfigMock,
}));
ngCliReadConfigurationMock = jest.fn();
(ngCompilerCli as jest.Mock).mockImplementation(() => ({
readConfiguration: ngCliReadConfigurationMock,
}));

context = {
root: '/root',
Expand Down Expand Up @@ -131,20 +138,27 @@ describe('NgPackagrLite executor', () => {
(
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true);
const generatedTsConfig = '/root/tmp/my-lib/tsconfig.app.generated.json';
const tsConfig = 'libs/my-lib/tsconfig.lib.json';
const generatedTsConfig =
'/root/tmp/libs/my-lib/tsconfig.lib.generated.json';
(buildableLibsUtils.createTmpTsConfig as jest.Mock).mockImplementation(
() => generatedTsConfig
);
ngCliReadConfigurationMock.mockReturnValue({
options: { configFilePath: generatedTsConfig },
});

// ACT
const result = await ngPackagrLiteExecutor(
{ ...options, tsConfig: '/root/my-lib/tsconfig.app.json' },
{ ...options, tsConfig },
context
).next();

// ASSERT
expect(buildableLibsUtils.createTmpTsConfig).toHaveBeenCalled();
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(generatedTsConfig);
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith({
options: { configFilePath: `/root/${tsConfig}` },
});
expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { NgPackagr } from 'ng-packagr';
import { resolve } from 'path';
import { createLibraryExecutor } from '../package/package.impl';
import type { BuildAngularLibraryExecutorOptions } from '../package/schema';
import { parseRemappedTsConfigAndMergeDefaults } from '../utilities/typescript';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import { nxProvideOptions } from './ng-packagr-adjustments/ng-package/options.di';
import {
Expand All @@ -32,13 +33,18 @@ async function initializeNgPackgrLite(
packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide);

if (options.tsConfig) {
const tsConfigPath = createTmpTsConfig(
const remappedTsConfigFilePath = createTmpTsConfig(
options.tsConfig,
context.root,
context.workspace.projects[context.projectName].root,
projectDependencies
);
packager.withTsConfig(tsConfigPath);
const tsConfig = await parseRemappedTsConfigAndMergeDefaults(
context.root,
options.tsConfig,
remappedTsConfigFilePath
);
packager.withTsConfig(tsConfig);
}

return packager;
Expand Down
20 changes: 17 additions & 3 deletions packages/angular/src/executors/package/package.impl.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
jest.mock('@nrwl/devkit');
jest.mock('@nrwl/workspace/src/utilities/buildable-libs-utils');
jest.mock('ng-packagr');
jest.mock('ng-packagr/lib/utils/ng-compiler-cli');
jest.mock('./ng-packagr-adjustments/ng-package/options.di');

import type { ExecutorContext } from '@nrwl/devkit';
import * as buildableLibsUtils from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import * as ngPackagr from 'ng-packagr';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { BehaviorSubject } from 'rxjs';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import { nxProvideOptions } from './ng-packagr-adjustments/ng-package/options.di';
Expand All @@ -23,6 +25,7 @@ describe('Package executor', () => {
let ngPackagrWatchMock: jest.Mock;
let ngPackagrWithBuildTransformMock: jest.Mock;
let ngPackagrWithTsConfigMock: jest.Mock;
let ngCliReadConfigurationMock: jest.Mock;
let options: BuildAngularLibraryExecutorOptions;

beforeEach(async () => {
Expand All @@ -45,6 +48,10 @@ describe('Package executor', () => {
withBuildTransform: ngPackagrWithBuildTransformMock,
withTsConfig: ngPackagrWithTsConfigMock,
}));
ngCliReadConfigurationMock = jest.fn();
(ngCompilerCli as jest.Mock).mockImplementation(() => ({
readConfiguration: ngCliReadConfigurationMock,
}));

context = {
root: '/root',
Expand Down Expand Up @@ -129,18 +136,25 @@ describe('Package executor', () => {
(
buildableLibsUtils.checkDependentProjectsHaveBeenBuilt as jest.Mock
).mockReturnValue(true);
const generatedTsConfig = '/root/tmp/my-lib/tsconfig.app.generated.json';
const tsConfig = 'libs/my-lib/tsconfig.lib.json';
const generatedTsConfig =
'/root/tmp/libs/my-lib/tsconfig.lib.generated.json';
(buildableLibsUtils.createTmpTsConfig as jest.Mock).mockImplementation(
() => generatedTsConfig
);
ngCliReadConfigurationMock.mockReturnValue({
options: { configFilePath: generatedTsConfig },
});

const result = await packageExecutor(
{ ...options, tsConfig: '/root/my-lib/tsconfig.app.json' },
{ ...options, tsConfig },
context
).next();

expect(buildableLibsUtils.createTmpTsConfig).toHaveBeenCalled();
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith(generatedTsConfig);
expect(ngPackagrWithTsConfigMock).toHaveBeenCalledWith({
options: { configFilePath: `/root/${tsConfig}` },
});
expect(ngPackagrBuildMock).toHaveBeenCalled();
expect(result.value).toEqual({ success: true });
expect(result.done).toBe(true);
Expand Down
10 changes: 8 additions & 2 deletions packages/angular/src/executors/package/package.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { NgPackagr } from 'ng-packagr';
import { resolve } from 'path';
import { from } from 'rxjs';
import { mapTo, switchMap, tap } from 'rxjs/operators';
import { parseRemappedTsConfigAndMergeDefaults } from '../utilities/typescript';
import { NX_ENTRY_POINT_PROVIDERS } from './ng-packagr-adjustments/ng-package/entry-point/entry-point.di';
import { nxProvideOptions } from './ng-packagr-adjustments/ng-package/options.di';
import {
Expand All @@ -37,13 +38,18 @@ async function initializeNgPackagr(
packager.withBuildTransform(NX_PACKAGE_TRANSFORM.provide);

if (options.tsConfig) {
const tsConfigPath = createTmpTsConfig(
const remappedTsConfigFilePath = createTmpTsConfig(
options.tsConfig,
context.root,
context.workspace.projects[context.projectName].root,
projectDependencies
);
packager.withTsConfig(tsConfigPath);
const tsConfig = await parseRemappedTsConfigAndMergeDefaults(
context.root,
options.tsConfig,
remappedTsConfigFilePath
);
packager.withTsConfig(tsConfig);
}

return packager;
Expand Down
62 changes: 62 additions & 0 deletions packages/angular/src/executors/utilities/typescript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Adapted from a private function at ng-packagr
* https://github.com/ng-packagr/ng-packagr/blob/main/src/lib/ts/tsconfig.ts#L12:
*
* Changes made:
* - Added an extra function that updates the configFilePath in the returned parsed options
* to be the original tsconfig file.
*/

import type {
CompilerOptions,
ParsedConfiguration,
} from '@angular/compiler-cli';
import { ngCompilerCli } from 'ng-packagr/lib/utils/ng-compiler-cli';
import { resolve } from 'path';
import * as ts from 'typescript';

async function readDefaultTsConfig(
fileName: string
): Promise<ParsedConfiguration> {
// these options are mandatory
const extraOptions: CompilerOptions = {
target: ts.ScriptTarget.ES2020,
experimentalDecorators: true,

// sourcemaps
sourceMap: false,
inlineSources: true,
inlineSourceMap: true,

outDir: '',
declaration: true,

// ng compiler to options
enableResourceInlining: true,

// these are required to set the appropriate EmitFlags
flatModuleId: 'AUTOGENERATED',
flatModuleOutFile: 'AUTOGENERATED',
};

const { readConfiguration } = await ngCompilerCli();

return readConfiguration(fileName, extraOptions);
}

/**
* Proxy function that ensures the configFilePath option points to the original file path.
*/
export async function parseRemappedTsConfigAndMergeDefaults(
workspaceRoot: string,
originalFilePath: string,
remappedFilePath: string
): Promise<ParsedConfiguration> {
const parsedConfiguration = await readDefaultTsConfig(remappedFilePath);
parsedConfiguration.options.configFilePath = resolve(
workspaceRoot,
originalFilePath
);

return parsedConfiguration;
}

0 comments on commit 6bc3720

Please sign in to comment.