Skip to content

Commit 53b3ddf

Browse files
committed
build: copy stylesheets to release output
* Copies stylesheets of secondary entry-points to the root of the release output * Better deduping for the `_theming.scss` file (currently includes multiple `cdk-a11y` mixins) * Removes unused `cdk-a11y` import in the `button-toggle` component. * Moves some logic out of the `BuildPackage` class (in favor of readability)
1 parent 3571f68 commit 53b3ddf

File tree

10 files changed

+88
-60
lines changed

10 files changed

+88
-60
lines changed

src/cdk/a11y/a11y-prebuilt.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@import './a11y';
2+
3+
@include cdk-a11y();

src/lib/button/button.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// TODO(jelbourn): Measure perf benefits for translate3d and will-change.
22
// TODO(jelbourn): Figure out if anchor hover underline actually happens in any browser.
33
@import 'button-base';
4-
@import '../../cdk/a11y/a11y';
54
@import '../core/style/layout-common';
5+
@import '../../cdk/a11y/a11y';
66

77
.mat-button, .mat-icon-button {
88
@extend %mat-button-base;

src/lib/chips/chips.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@import '../../cdk/a11y/a11y';
21
@import '../core/style/elevation';
2+
@import '../../cdk/a11y/a11y';
33

44
$mat-chip-vertical-padding: 7px;
55
$mat-chip-horizontal-padding: 12px;

src/lib/core/option/_option.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import '../style/menu-common';
22
@import '../style/vendor-prefixes';
3-
@import '../../../cdk/a11y/a11y';
43
@import '../style/layout-common';
4+
@import '../../../cdk/a11y/a11y';
55

66
/**
77
* This mixin contains shared option styles between the select and

src/lib/menu/menu.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// TODO(kara): update vars for desktop when MD team responds
2-
32
@import '../core/style/button-common';
43
@import '../core/style/layout-common';
54
@import '../core/style/menu-common';
6-
@import '../../cdk/a11y/a11y';
75
@import '../core/style/layout-common';
6+
@import '../../cdk/a11y/a11y';
87

98
$mat-menu-vertical-padding: 8px !default;
109
$mat-menu-border-radius: 2px !default;

tools/gulp/packages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ materialPackage.exportsSecondaryEntryPointsAtRoot = true;
1313

1414
// To avoid refactoring of the project the material package will map to the source path `lib/`.
1515
materialPackage.sourceDir = join(buildConfig.packagesDir, 'lib');
16+
17+
// Some CDK secondary entry-points include SCSS files that should be exposed individually at the
18+
// release output root. This is different in the Material package because here a full SCSS bundle
19+
// will be generated.
20+
cdkPackage.copySecondaryEntryPointStylesToRoot = true;

tools/gulp/tasks/material-release.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const themingEntryPointPath = join(sourceDir, 'core', 'theming', '_all-theme.scs
2222
const themingBundlePath = join(releasePath, '_theming.scss');
2323
// Matches all pre-built theme css files
2424
const prebuiltThemeGlob = join(outputDir, '**/theming/prebuilt/*.css?(.map)');
25-
// Matches all SCSS files in the library.
26-
const allScssGlob = join(sourceDir, '**/*.scss');
25+
// Matches all SCSS files in the different packages.
26+
const allScssGlob = join(buildConfig.packagesDir, '**/*.scss');
2727

2828
/**
2929
* Overwrite the release task for the material package. The material release will include special

tools/package-tools/build-package.ts

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
import {red} from 'chalk';
2-
import {spawn} from 'child_process';
3-
import {readFileSync, writeFileSync} from 'fs';
4-
import {sync as glob} from 'glob';
5-
import {join, resolve as resolvePath} from 'path';
1+
import {join} from 'path';
62
import {main as ngc} from '@angular/tsc-wrapped';
73
import {PackageBundler} from './build-bundles';
84
import {buildConfig} from './build-config';
95
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
10-
6+
import {compileEntryPoint, renamePrivateReExportsToBeUnique} from './compile-entry-point';
117

128
const {packagesDir, outputDir} = buildConfig;
139

@@ -17,9 +13,6 @@ const buildTsconfigName = 'tsconfig-build.json';
1713
/** Name of the tsconfig file that is responsible for building the tests. */
1814
const testsTsconfigName = 'tsconfig-tests.json';
1915

20-
/** Incrementing ID counter. */
21-
let nextId = 0;
22-
2316
export class BuildPackage {
2417
/** Path to the package sources. */
2518
sourceDir: string;
@@ -30,6 +23,9 @@ export class BuildPackage {
3023
/** Whether this package will re-export its secondary-entry points at the root module. */
3124
exportsSecondaryEntryPointsAtRoot = false;
3225

26+
/** Whether the secondary entry-point styles should be copied to the release output. */
27+
copySecondaryEntryPointStylesToRoot = false;
28+
3329
/** Path to the entry file of the package in the output directory. */
3430
readonly entryFilePath: string;
3531

@@ -39,22 +35,22 @@ export class BuildPackage {
3935
/** Path to the tsconfig file, which will be used to build the tests. */
4036
private readonly tsconfigTests: string;
4137

42-
private _secondaryEntryPoints: string[];
43-
private _secondaryEntryPointsByDepth: string[][];
38+
/** Package bundler instance. */
39+
private bundler = new PackageBundler(this);
4440

4541
/** Secondary entry-points partitioned by their build depth. */
4642
private get secondaryEntryPointsByDepth(): string[][] {
4743
this.cacheSecondaryEntryPoints();
4844
return this._secondaryEntryPointsByDepth;
4945
}
50-
51-
private readonly bundler = new PackageBundler(this);
46+
private _secondaryEntryPointsByDepth: string[][];
5247

5348
/** Secondary entry points for the package. */
5449
get secondaryEntryPoints(): string[] {
5550
this.cacheSecondaryEntryPoints();
5651
return this._secondaryEntryPoints;
5752
}
53+
private _secondaryEntryPoints: string[];
5854

5955
constructor(public readonly name: string, public readonly dependencies: BuildPackage[] = []) {
6056
this.sourceDir = join(packagesDir, name);
@@ -74,11 +70,11 @@ export class BuildPackage {
7470
// Depth 1: a11y, scrolling
7571
// Depth 2: overlay
7672
for (const entryPointGroup of this.secondaryEntryPointsByDepth) {
77-
await Promise.all(entryPointGroup.map(p => this._compileEntryPoint(buildTsconfigName, p)));
73+
await Promise.all(entryPointGroup.map(p => compileEntryPoint(this, buildTsconfigName, p)));
7874
}
7975

8076
// Compile the primary entry-point.
81-
await this._compileEntryPoint(buildTsconfigName);
77+
await compileEntryPoint(this, buildTsconfigName);
8278
}
8379

8480
/** Compiles the TypeScript test source files for the package. */
@@ -91,50 +87,13 @@ export class BuildPackage {
9187
await this.bundler.createBundles();
9288
}
9389

94-
/** Compiles the TypeScript sources of a primary or secondary entry point. */
95-
private async _compileEntryPoint(tsconfigName: string, secondaryEntryPoint = '') {
96-
const entryPointPath = join(this.sourceDir, secondaryEntryPoint);
97-
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
98-
99-
return new Promise((resolve, reject) => {
100-
const ngcPath = resolvePath('./node_modules/.bin/ngc');
101-
const childProcess = spawn(ngcPath, ['-p', entryPointTsconfigPath], {shell: true});
102-
103-
// Pipe stdout and stderr from the child process.
104-
childProcess.stdout.on('data', (data: any) => console.log(`${data}`));
105-
childProcess.stderr.on('data', (data: any) => console.error(red(`${data}`)));
106-
107-
childProcess.on('exit', (exitCode: number) => exitCode === 0 ? resolve() : reject());
108-
})
109-
.catch(() => console.error(red(`Failed to compile ${secondaryEntryPoint}`)))
110-
.then(() => this.renamePrivateReExportsToBeUnique(secondaryEntryPoint));
111-
}
112-
11390
/** Compiles the TypeScript sources of a primary or secondary entry point. */
11491
private async _compileTestEntryPoint(tsconfigName: string, secondaryEntryPoint = '') {
11592
const entryPointPath = join(this.sourceDir, secondaryEntryPoint);
11693
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
11794

11895
await ngc(entryPointTsconfigPath, {basePath: entryPointPath});
119-
this.renamePrivateReExportsToBeUnique(secondaryEntryPoint);
120-
}
121-
122-
/** Renames `ɵa`-style re-exports generated by Angular to be unique across compilation units. */
123-
private renamePrivateReExportsToBeUnique(secondaryEntryPoint = '') {
124-
// When we compiled the typescript sources with ngc, we do entry-point individually.
125-
// If the root-level module re-exports multiple of these entry-points, the private-export
126-
// identifiers (e.g., `ɵa`) generated by ngc will collide. We work around this by suffixing
127-
// each of these identifiers with an ID specific to this entry point. We make this
128-
// replacement in the js, d.ts, and metadata output.
129-
if (this.exportsSecondaryEntryPointsAtRoot && secondaryEntryPoint) {
130-
const entryPointId = nextId++;
131-
const outputPath = join(this.outputDir, secondaryEntryPoint);
132-
glob(join(outputPath, '**/*.+(js|d.ts|metadata.json)')).forEach(filePath => {
133-
let fileContent = readFileSync(filePath, 'utf-8');
134-
fileContent = fileContent.replace(/(ɵ[a-z]+)/g, `$1${entryPointId}`);
135-
writeFileSync(filePath, fileContent, 'utf-8');
136-
});
137-
}
96+
renamePrivateReExportsToBeUnique(this, secondaryEntryPoint);
13897
}
13998

14099
/** Stores the secondary entry-points for this package if they haven't been computed already. */

tools/package-tools/build-release.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ export function composeRelease(buildPackage: BuildPackage) {
5454
createFilesForSecondaryEntryPoint(buildPackage, releasePath);
5555
}
5656

57+
if (buildPackage.copySecondaryEntryPointStylesToRoot) {
58+
copySecondaryEntryPointStylesheets(buildPackage, releasePath);
59+
}
60+
5761
if (buildPackage.exportsSecondaryEntryPointsAtRoot) {
5862
// Add re-exports to the root d.ts file to prevent errors of the form
5963
// "@angular/material/material has no exported member 'MATERIAL_SANITY_CHECKS."
@@ -102,3 +106,13 @@ function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePa
102106
createMetadataReexportFile(releasePath, `./${entryPointName}/index`, entryPointName);
103107
});
104108
}
109+
110+
/** Copies the stylesheets for secondary entry-points that generate one to the release output. */
111+
function copySecondaryEntryPointStylesheets(buildPackage: BuildPackage, releasePath: string) {
112+
buildPackage.secondaryEntryPoints.forEach(entryPointName => {
113+
const entryPointDir = join(buildPackage.outputDir, entryPointName);
114+
115+
copyFiles(entryPointDir, `_${entryPointName}.scss`, releasePath);
116+
copyFiles(entryPointDir, `${entryPointName}-prebuilt.css`, releasePath);
117+
});
118+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import {join, resolve as resolvePath} from 'path';
2+
import {spawn} from 'child_process';
3+
import {writeFileSync, readFileSync} from 'fs';
4+
import {sync as glob} from 'glob';
5+
import {red} from 'chalk';
6+
import {BuildPackage} from './build-package';
7+
8+
/** Incrementing ID counter. */
9+
let nextId = 0;
10+
11+
/** Compiles the TypeScript sources of a primary or secondary entry point. */
12+
export async function compileEntryPoint(buildPackage: BuildPackage, tsconfigName: string,
13+
secondaryEntryPoint = '') {
14+
const entryPointPath = join(buildPackage.sourceDir, secondaryEntryPoint);
15+
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
16+
17+
return new Promise((resolve, reject) => {
18+
const ngcPath = resolvePath('./node_modules/.bin/ngc');
19+
const childProcess = spawn(ngcPath, ['-p', entryPointTsconfigPath], {shell: true});
20+
21+
// Pipe stdout and stderr from the child process.
22+
childProcess.stdout.on('data', (data: any) => console.log(`${data}`));
23+
childProcess.stderr.on('data', (data: any) => console.error(red(`${data}`)));
24+
25+
childProcess.on('exit', (exitCode: number) => exitCode === 0 ? resolve() : reject());
26+
})
27+
.catch(() => console.error(red(`Failed to compile ${secondaryEntryPoint}`)))
28+
.then(() => renamePrivateReExportsToBeUnique(buildPackage, secondaryEntryPoint));
29+
}
30+
31+
/** Renames `ɵa`-style re-exports generated by Angular to be unique across compilation units. */
32+
export function renamePrivateReExportsToBeUnique(buildPackage: BuildPackage,
33+
secondaryEntryPoint = '') {
34+
// When we compiled the typescript sources with ngc, we do entry-point individually.
35+
// If the root-level module re-exports multiple of these entry-points, the private-export
36+
// identifiers (e.g., `ɵa`) generated by ngc will collide. We work around this by suffixing
37+
// each of these identifiers with an ID specific to this entry point. We make this
38+
// replacement in the js, d.ts, and metadata output.
39+
if (buildPackage.exportsSecondaryEntryPointsAtRoot && secondaryEntryPoint) {
40+
const entryPointId = nextId++;
41+
const outputPath = join(buildPackage.outputDir, secondaryEntryPoint);
42+
glob(join(outputPath, '**/*.+(js|d.ts|metadata.json)')).forEach(filePath => {
43+
let fileContent = readFileSync(filePath, 'utf-8');
44+
fileContent = fileContent.replace(/(ɵ[a-z]+)/g, `$1${entryPointId}`);
45+
writeFileSync(filePath, fileContent, 'utf-8');
46+
});
47+
}
48+
}

0 commit comments

Comments
 (0)