Skip to content

Commit 2b4d4b1

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 dcf3b27 commit 2b4d4b1

File tree

21 files changed

+97
-70
lines changed

21 files changed

+97
-70
lines changed
File renamed without changes.

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-toggle/button-toggle.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
@import '../core/a11y/a11y';
21
@import '../core/style/elevation';
32
@import '../core/style/vendor-prefixes';
43
@import '../core/style/layout-common';

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 '../core/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/card/card.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import '../core/style/variables';
22
@import '../core/style/elevation';
3-
@import '../core/a11y/a11y';
3+
@import '../../cdk/a11y/a11y';
44

55

66
$mat-card-default-padding: 24px !default;

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 '../core/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/_core.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// We can use relative imports for imports from the cdk because we bundle everything
22
// up into a single flat scss file for material.
33
@import '../../cdk/overlay/overlay';
4+
@import '../../cdk/a11y/a11y';
45

56
// Core styles that can be used to apply material design treatments to any element.
6-
@import 'a11y/a11y';
77
@import 'style/elevation';
88
@import 'ripple/ripple';
99
@import 'option/option';

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 '../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/core/ripple/_ripple.scss

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

44
$mat-ripple-color-opacity: 0.1;
55

src/lib/dialog/dialog.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import '../core/style/elevation';
22
@import '../core/style/vendor-prefixes';
3-
@import '../core/a11y/a11y';
3+
@import '../../cdk/a11y/a11y';
44

55

66
$mat-dialog-padding: 24px !default;

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 '../core/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;

src/lib/select/select.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
@import '../core/style/list-common';
33
@import '../core/style/variables';
44
@import '../core/style/vendor-prefixes';
5-
@import '../core/a11y/a11y';
5+
@import '../../cdk/a11y/a11y';
66

77
$mat-select-trigger-height: 30px !default;
88
$mat-select-trigger-min-width: 112px !default;

src/lib/sidenav/drawer.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import '../core/style/variables';
22
@import '../core/style/elevation';
33
@import '../core/style/layout-common';
4-
@import '../core/a11y/a11y';
4+
@import '../../cdk/a11y/a11y';
55

66
// stylelint-disable max-line-length
77
// Mixin that creates a new stacking context.

src/lib/slide-toggle/slide-toggle.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
@import '../core/ripple/ripple';
33
@import '../core/style/elevation';
44
@import '../core/style/vendor-prefixes';
5-
@import '../core/a11y/a11y';
5+
@import '../../cdk/a11y/a11y';
66

77
$mat-slide-toggle-thumb-size: 20px !default;
88
$mat-slide-toggle-bar-border-radius: 8px !default;

src/lib/snack-bar/snack-bar-container.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import '../core/a11y/a11y';
1+
@import '../../cdk/a11y/a11y';
22

33
$mat-snack-bar-padding: 14px 24px !default;
44
$mat-snack-bar-min-width: 288px !default;

src/lib/tooltip/tooltip.scss

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

44
$mat-tooltip-horizontal-padding: 8px;
55
$mat-tooltip-max-width: 250px;

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)