Skip to content

Commit 4371ca7

Browse files
committed
fix(@schematics/angular): skip other projects when finding secondary entry points in use-library-builder
The migration discovers secondary entry points by walking the library's root directory. For a library at the workspace root, this includes the directories of the other projects, so their ng-packagr configurations are added to the root library's `exports` and deleted before those libraries are migrated. Skip the root directories of other workspace projects while discovering secondary entry points. A new spec fails without this change.
1 parent bf1602a commit 4371ca7

2 files changed

Lines changed: 41 additions & 2 deletions

File tree

‎packages/schematics/angular/migrations/use-library-builder/migration.ts‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,14 @@ function resolveEntryFile(tree: Tree, dir: string, configuredEntry?: string): st
146146
* @param tree The virtual file system tree.
147147
* @param projectRoot The root directory of the library project.
148148
* @param primaryProjectFile The workspace-relative path to the primary `ng-packagr` configuration file.
149+
* @param projectRoots The normalized root directories of all workspace projects.
149150
* @returns An array of discovered secondary entry points.
150151
*/
151152
function findSecondaryEntryPoints(
152153
tree: Tree,
153154
projectRoot: string,
154155
primaryProjectFile: string,
156+
projectRoots: ReadonlySet<string>,
155157
): SecondaryEntryPoint[] {
156158
const secondaryEntryPoints: SecondaryEntryPoint[] = [];
157159
const normalizedRoot = normalizeRelativePath(projectRoot);
@@ -202,7 +204,9 @@ function findSecondaryEntryPoints(
202204
subdir === 'node_modules' ||
203205
subdir === 'dist' ||
204206
subdir === 'out-tsc' ||
205-
subdir.startsWith('.')
207+
subdir.startsWith('.') ||
208+
// Other projects nested in the directory, such as libraries of a workspace root library.
209+
projectRoots.has(join(currentPath, subdir))
206210
) {
207211
continue;
208212
}
@@ -370,13 +374,15 @@ function migrateTargetOptions(
370374
* @param buildTarget The library's `build` target definition in `angular.json`.
371375
* @param tree The virtual file system tree.
372376
* @param context The schematic execution context.
377+
* @param projectRoots The normalized root directories of all workspace projects.
373378
* @returns `true` if the library target was migrated, or `false` if it was skipped.
374379
*/
375380
function updateLibraryTarget(
376381
projectRoot: string,
377382
buildTarget: TargetDefinition,
378383
tree: Tree,
379384
context: SchematicContext,
385+
projectRoots: ReadonlySet<string>,
380386
): boolean {
381387
const normalizedProjectRoot = normalizeRelativePath(projectRoot);
382388
let primaryProjectFile =
@@ -423,6 +429,7 @@ function updateLibraryTarget(
423429
tree,
424430
normalizedProjectRoot,
425431
primaryProjectFile,
432+
projectRoots,
426433
);
427434

428435
const toRelativeExportPath = (filePath: string): string => {
@@ -588,6 +595,9 @@ export default function (): Rule {
588595
return (tree, context) =>
589596
updateWorkspace((workspace) => {
590597
let hasMigratedLibrary = false;
598+
const projectRoots = new Set(
599+
Array.from(workspace.projects.values(), (project) => normalizeRelativePath(project.root)),
600+
);
591601

592602
for (const [, project] of workspace.projects) {
593603
if (project.extensions.projectType !== ProjectType.Library) {
@@ -604,7 +614,7 @@ export default function (): Rule {
604614
continue;
605615
}
606616

607-
if (updateLibraryTarget(project.root, buildTarget, tree, context)) {
617+
if (updateLibraryTarget(project.root, buildTarget, tree, context, projectRoots)) {
608618
hasMigratedLibrary = true;
609619
}
610620
}

‎packages/schematics/angular/migrations/use-library-builder/migration_spec.ts‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,35 @@ describe('Migration to use the library builder', () => {
280280
});
281281
});
282282

283+
it('should not treat other libraries as secondary entry points of a workspace root library', async () => {
284+
const angularJson = JSON.parse(tree.readContent('/angular.json'));
285+
angularJson.projects = {
286+
'root-lib': {
287+
root: '',
288+
sourceRoot: 'src',
289+
projectType: ProjectType.Library,
290+
architect: {
291+
build: {
292+
builder: Builders.NgPackagr,
293+
options: { project: 'ng-package.json' },
294+
},
295+
},
296+
},
297+
...angularJson.projects,
298+
};
299+
tree.overwrite('/angular.json', JSON.stringify(angularJson));
300+
tree.create('/ng-package.json', JSON.stringify({ lib: { entryFile: 'src/public-api.ts' } }));
301+
tree.create('/projects/my-lib/src/public-api.ts', '');
302+
303+
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
304+
305+
const rootPkg = newTree.readJson('/package.json') as { exports: unknown };
306+
expect(rootPkg.exports).toEqual({ '.': './src/public-api.ts' });
307+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
308+
const { projects } = newTree.readJson('/angular.json') as any;
309+
expect(projects['my-lib'].architect['build'].options.outputPath).toBe('dist/my-lib');
310+
});
311+
283312
it('should migrate assets, styleIncludePaths, and sass options from ng-package.json', async () => {
284313
tree.create('/projects/my-lib/CHANGELOG.md', '# Changelog');
285314
tree.overwrite(

0 commit comments

Comments
 (0)