Skip to content

Commit c32a690

Browse files
authored
fix(@schematics/angular): migrate secondary entry point style options in use-library-builder
migration read only `lib.entryFile` from secondary `ng-package.json` and then deleted it, so its `styleIncludePaths` and `sass` options were lost and next build failed with `Can't find stylesheet to import` library builder has single global `stylePreprocessorOptions`, so secondary optoins are now merged into it next to primary ones
1 parent 8c14983 commit c32a690

2 files changed

Lines changed: 107 additions & 4 deletions

File tree

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

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ interface SecondaryEntryPoint {
6060
subpath: string;
6161
entryPoint: string;
6262
configFile: string;
63+
config: NgPackageConfig | undefined;
6364
}
6465

6566
/**
@@ -176,6 +177,7 @@ function findSecondaryEntryPoints(
176177
subpath,
177178
entryPoint: join(currentPath, entryFile),
178179
configFile: ngPackageJsonPath,
180+
config,
179181
});
180182
} else if (
181183
current.subfiles.some((f) => f === 'package.json') &&
@@ -189,6 +191,7 @@ function findSecondaryEntryPoints(
189191
subpath,
190192
entryPoint: join(currentPath, entryFile),
191193
configFile: packageJsonPath,
194+
config,
192195
});
193196
}
194197
}
@@ -296,12 +299,19 @@ function migrateTargetOptions(
296299
join(projectDir, p),
297300
);
298301
existingPreprocessorOptions['includePaths'] = [
299-
...existingIncludePaths,
300-
...migratedIncludePaths,
302+
...new Set([...existingIncludePaths, ...migratedIncludePaths]),
301303
];
302304
}
303305
if (ngPackageConfig.lib.sass) {
304-
existingPreprocessorOptions['sass'] = ngPackageConfig.lib.sass;
306+
const existingSass = existingPreprocessorOptions['sass'];
307+
const sass: JsonObject = isJsonObject(existingSass) ? { ...existingSass } : {};
308+
for (const [key, value] of Object.entries(ngPackageConfig.lib.sass)) {
309+
if (Array.isArray(value)) {
310+
const existing = Array.isArray(sass[key]) ? (sass[key] as string[]) : [];
311+
sass[key] = [...new Set([...existing, ...value])];
312+
}
313+
}
314+
existingPreprocessorOptions['sass'] = sass;
305315
}
306316

307317
buildTarget.options['stylePreprocessorOptions'] = existingPreprocessorOptions;
@@ -400,7 +410,7 @@ function updateLibraryTarget(
400410
return false;
401411
}
402412

403-
const ngPackageConfig = primaryProjectFile
413+
let ngPackageConfig = primaryProjectFile
404414
? parseNgPackageFile(tree, primaryProjectFile)
405415
: undefined;
406416

@@ -430,6 +440,31 @@ function updateLibraryTarget(
430440
? secondary.subpath
431441
: `./${secondary.subpath}`;
432442
entryPointExports[exportKey] = toRelativeExportPath(secondary.entryPoint);
443+
444+
if (secondary.config?.lib) {
445+
ngPackageConfig ??= {};
446+
ngPackageConfig.lib ??= {};
447+
448+
if (secondary.config.lib.styleIncludePaths?.length) {
449+
const secondaryDir = dirname(secondary.configFile);
450+
ngPackageConfig.lib.styleIncludePaths ??= [];
451+
for (const includePath of secondary.config.lib.styleIncludePaths) {
452+
ngPackageConfig.lib.styleIncludePaths.push(
453+
relative(projectDir, join(secondaryDir, includePath)),
454+
);
455+
}
456+
}
457+
458+
if (secondary.config.lib.sass) {
459+
const sass: Record<string, unknown> = (ngPackageConfig.lib.sass ??= {});
460+
for (const [key, value] of Object.entries(secondary.config.lib.sass)) {
461+
if (Array.isArray(value)) {
462+
const existing = Array.isArray(sass[key]) ? (sass[key] as string[]) : [];
463+
sass[key] = [...new Set([...existing, ...value])];
464+
}
465+
}
466+
}
467+
}
433468
}
434469

435470
migrateTargetOptions(normalizedProjectRoot, projectDir, buildTarget, ngPackageConfig, tree);

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,74 @@ describe('Migration to use the library builder', () => {
399399
});
400400
});
401401

402+
it('should merge existing stylePreprocessorOptions.sass when migrating sass options', async () => {
403+
const angularJson = JSON.parse(tree.readContent('/angular.json'));
404+
angularJson.projects['my-lib'].architect.build.options.stylePreprocessorOptions = {
405+
sass: { silenceDeprecations: ['mixed-decls'] },
406+
};
407+
tree.overwrite('/angular.json', JSON.stringify(angularJson, undefined, 2));
408+
409+
tree.overwrite(
410+
'/projects/my-lib/ng-package.json',
411+
JSON.stringify(
412+
{
413+
lib: {
414+
entryFile: 'src/public-api.ts',
415+
sass: { silenceDeprecations: ['import'] },
416+
},
417+
},
418+
undefined,
419+
2,
420+
),
421+
);
422+
423+
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
424+
const {
425+
projects: { 'my-lib': lib },
426+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
427+
} = newTree.readJson('/angular.json') as any;
428+
429+
expect(lib.architect['build'].options.stylePreprocessorOptions).toEqual({
430+
sass: { silenceDeprecations: ['mixed-decls', 'import'] },
431+
});
432+
});
433+
434+
it('should migrate styleIncludePaths and sass options from secondary entry points', async () => {
435+
tree.overwrite(
436+
'/projects/my-lib/ng-package.json',
437+
JSON.stringify({
438+
lib: {
439+
entryFile: 'src/public-api.ts',
440+
styleIncludePaths: ['styles'],
441+
sass: { silenceDeprecations: ['import'] },
442+
},
443+
}),
444+
);
445+
tree.create(
446+
'/projects/my-lib/testing/ng-package.json',
447+
JSON.stringify({
448+
lib: {
449+
entryFile: 'src/public-api.ts',
450+
styleIncludePaths: ['../styles', 'styles'],
451+
sass: { silenceDeprecations: ['import', 'global-builtin'] },
452+
},
453+
}),
454+
);
455+
456+
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
457+
const {
458+
projects: { 'my-lib': lib },
459+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
460+
} = newTree.readJson('/angular.json') as any;
461+
462+
expect(lib.architect['build'].options.stylePreprocessorOptions).toEqual({
463+
includePaths: ['projects/my-lib/styles', 'projects/my-lib/testing/styles'],
464+
sass: {
465+
silenceDeprecations: ['import', 'global-builtin'],
466+
},
467+
});
468+
});
469+
402470
it('should throw an error when entry file is not configured and no default candidate exists', async () => {
403471
tree.overwrite('/projects/my-lib/ng-package.json', JSON.stringify({}, undefined, 2));
404472

0 commit comments

Comments
 (0)