mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build: copy stylesheets to release output (#7204)
* 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)
This commit is contained in:
committed by
Jeremy Elbourn
parent
1ac3fd25c9
commit
afa92a8d60
@@ -0,0 +1,3 @@
|
||||
@import './a11y';
|
||||
|
||||
@include cdk-a11y();
|
||||
@@ -1,8 +1,8 @@
|
||||
// TODO(jelbourn): Measure perf benefits for translate3d and will-change.
|
||||
// TODO(jelbourn): Figure out if anchor hover underline actually happens in any browser.
|
||||
@import 'button-base';
|
||||
@import '../../cdk/a11y/a11y';
|
||||
@import '../core/style/layout-common';
|
||||
@import '../../cdk/a11y/a11y';
|
||||
|
||||
.mat-button, .mat-icon-button {
|
||||
@extend %mat-button-base;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@import '../../cdk/a11y/a11y';
|
||||
@import '../core/style/elevation';
|
||||
@import '../../cdk/a11y/a11y';
|
||||
|
||||
$mat-chip-vertical-padding: 7px;
|
||||
$mat-chip-horizontal-padding: 12px;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import '../style/menu-common';
|
||||
@import '../style/vendor-prefixes';
|
||||
@import '../../../cdk/a11y/a11y';
|
||||
@import '../style/layout-common';
|
||||
@import '../../../cdk/a11y/a11y';
|
||||
|
||||
/**
|
||||
* This mixin contains shared option styles between the select and
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// TODO(kara): update vars for desktop when MD team responds
|
||||
|
||||
@import '../core/style/button-common';
|
||||
@import '../core/style/layout-common';
|
||||
@import '../core/style/menu-common';
|
||||
@import '../../cdk/a11y/a11y';
|
||||
@import '../core/style/layout-common';
|
||||
@import '../../cdk/a11y/a11y';
|
||||
|
||||
$mat-menu-vertical-padding: 8px !default;
|
||||
$mat-menu-border-radius: 2px !default;
|
||||
|
||||
@@ -12,3 +12,8 @@ materialPackage.exportsSecondaryEntryPointsAtRoot = true;
|
||||
|
||||
// To avoid refactoring of the project the material package will map to the source path `lib/`.
|
||||
materialPackage.sourceDir = join(buildConfig.packagesDir, 'lib');
|
||||
|
||||
// Some CDK secondary entry-points include SCSS files that should be exposed individually at the
|
||||
// release output root. This is different in the Material package because here a full SCSS bundle
|
||||
// will be generated.
|
||||
cdkPackage.copySecondaryEntryPointStylesToRoot = true;
|
||||
|
||||
@@ -22,8 +22,8 @@ const themingEntryPointPath = join(sourceDir, 'core', 'theming', '_all-theme.scs
|
||||
const themingBundlePath = join(releasePath, '_theming.scss');
|
||||
// Matches all pre-built theme css files
|
||||
const prebuiltThemeGlob = join(outputDir, '**/theming/prebuilt/*.css?(.map)');
|
||||
// Matches all SCSS files in the library.
|
||||
const allScssGlob = join(sourceDir, '**/*.scss');
|
||||
// Matches all SCSS files in the different packages.
|
||||
const allScssGlob = join(buildConfig.packagesDir, '**/*.scss');
|
||||
|
||||
/**
|
||||
* Overwrite the release task for the material package. The material release will include special
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import {red} from 'chalk';
|
||||
import {spawn} from 'child_process';
|
||||
import {readFileSync, writeFileSync} from 'fs';
|
||||
import {sync as glob} from 'glob';
|
||||
import {join, resolve as resolvePath} from 'path';
|
||||
import {join} from 'path';
|
||||
import {main as ngc} from '@angular/tsc-wrapped';
|
||||
import {PackageBundler} from './build-bundles';
|
||||
import {buildConfig} from './build-config';
|
||||
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
|
||||
|
||||
import {compileEntryPoint, renamePrivateReExportsToBeUnique} from './compile-entry-point';
|
||||
|
||||
const {packagesDir, outputDir} = buildConfig;
|
||||
|
||||
@@ -17,9 +13,6 @@ const buildTsconfigName = 'tsconfig-build.json';
|
||||
/** Name of the tsconfig file that is responsible for building the tests. */
|
||||
const testsTsconfigName = 'tsconfig-tests.json';
|
||||
|
||||
/** Incrementing ID counter. */
|
||||
let nextId = 0;
|
||||
|
||||
export class BuildPackage {
|
||||
/** Path to the package sources. */
|
||||
sourceDir: string;
|
||||
@@ -30,6 +23,9 @@ export class BuildPackage {
|
||||
/** Whether this package will re-export its secondary-entry points at the root module. */
|
||||
exportsSecondaryEntryPointsAtRoot = false;
|
||||
|
||||
/** Whether the secondary entry-point styles should be copied to the release output. */
|
||||
copySecondaryEntryPointStylesToRoot = false;
|
||||
|
||||
/** Path to the entry file of the package in the output directory. */
|
||||
readonly entryFilePath: string;
|
||||
|
||||
@@ -39,22 +35,22 @@ export class BuildPackage {
|
||||
/** Path to the tsconfig file, which will be used to build the tests. */
|
||||
private readonly tsconfigTests: string;
|
||||
|
||||
private _secondaryEntryPoints: string[];
|
||||
private _secondaryEntryPointsByDepth: string[][];
|
||||
/** Package bundler instance. */
|
||||
private bundler = new PackageBundler(this);
|
||||
|
||||
/** Secondary entry-points partitioned by their build depth. */
|
||||
private get secondaryEntryPointsByDepth(): string[][] {
|
||||
this.cacheSecondaryEntryPoints();
|
||||
return this._secondaryEntryPointsByDepth;
|
||||
}
|
||||
|
||||
private readonly bundler = new PackageBundler(this);
|
||||
private _secondaryEntryPointsByDepth: string[][];
|
||||
|
||||
/** Secondary entry points for the package. */
|
||||
get secondaryEntryPoints(): string[] {
|
||||
this.cacheSecondaryEntryPoints();
|
||||
return this._secondaryEntryPoints;
|
||||
}
|
||||
private _secondaryEntryPoints: string[];
|
||||
|
||||
constructor(public readonly name: string, public readonly dependencies: BuildPackage[] = []) {
|
||||
this.sourceDir = join(packagesDir, name);
|
||||
@@ -74,11 +70,11 @@ export class BuildPackage {
|
||||
// Depth 1: a11y, scrolling
|
||||
// Depth 2: overlay
|
||||
for (const entryPointGroup of this.secondaryEntryPointsByDepth) {
|
||||
await Promise.all(entryPointGroup.map(p => this._compileEntryPoint(buildTsconfigName, p)));
|
||||
await Promise.all(entryPointGroup.map(p => compileEntryPoint(this, buildTsconfigName, p)));
|
||||
}
|
||||
|
||||
// Compile the primary entry-point.
|
||||
await this._compileEntryPoint(buildTsconfigName);
|
||||
await compileEntryPoint(this, buildTsconfigName);
|
||||
}
|
||||
|
||||
/** Compiles the TypeScript test source files for the package. */
|
||||
@@ -91,50 +87,13 @@ export class BuildPackage {
|
||||
await this.bundler.createBundles();
|
||||
}
|
||||
|
||||
/** Compiles the TypeScript sources of a primary or secondary entry point. */
|
||||
private async _compileEntryPoint(tsconfigName: string, secondaryEntryPoint = '') {
|
||||
const entryPointPath = join(this.sourceDir, secondaryEntryPoint);
|
||||
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const ngcPath = resolvePath('./node_modules/.bin/ngc');
|
||||
const childProcess = spawn(ngcPath, ['-p', entryPointTsconfigPath], {shell: true});
|
||||
|
||||
// Pipe stdout and stderr from the child process.
|
||||
childProcess.stdout.on('data', (data: any) => console.log(`${data}`));
|
||||
childProcess.stderr.on('data', (data: any) => console.error(red(`${data}`)));
|
||||
|
||||
childProcess.on('exit', (exitCode: number) => exitCode === 0 ? resolve() : reject());
|
||||
})
|
||||
.catch(() => console.error(red(`Failed to compile ${secondaryEntryPoint}`)))
|
||||
.then(() => this.renamePrivateReExportsToBeUnique(secondaryEntryPoint));
|
||||
}
|
||||
|
||||
/** Compiles the TypeScript sources of a primary or secondary entry point. */
|
||||
private async _compileTestEntryPoint(tsconfigName: string, secondaryEntryPoint = '') {
|
||||
const entryPointPath = join(this.sourceDir, secondaryEntryPoint);
|
||||
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
|
||||
|
||||
await ngc(entryPointTsconfigPath, {basePath: entryPointPath});
|
||||
this.renamePrivateReExportsToBeUnique(secondaryEntryPoint);
|
||||
}
|
||||
|
||||
/** Renames `ɵa`-style re-exports generated by Angular to be unique across compilation units. */
|
||||
private renamePrivateReExportsToBeUnique(secondaryEntryPoint = '') {
|
||||
// When we compiled the typescript sources with ngc, we do entry-point individually.
|
||||
// If the root-level module re-exports multiple of these entry-points, the private-export
|
||||
// identifiers (e.g., `ɵa`) generated by ngc will collide. We work around this by suffixing
|
||||
// each of these identifiers with an ID specific to this entry point. We make this
|
||||
// replacement in the js, d.ts, and metadata output.
|
||||
if (this.exportsSecondaryEntryPointsAtRoot && secondaryEntryPoint) {
|
||||
const entryPointId = nextId++;
|
||||
const outputPath = join(this.outputDir, secondaryEntryPoint);
|
||||
glob(join(outputPath, '**/*.+(js|d.ts|metadata.json)')).forEach(filePath => {
|
||||
let fileContent = readFileSync(filePath, 'utf-8');
|
||||
fileContent = fileContent.replace(/(ɵ[a-z]+)/g, `$1${entryPointId}`);
|
||||
writeFileSync(filePath, fileContent, 'utf-8');
|
||||
});
|
||||
}
|
||||
renamePrivateReExportsToBeUnique(this, secondaryEntryPoint);
|
||||
}
|
||||
|
||||
/** Stores the secondary entry-points for this package if they haven't been computed already. */
|
||||
|
||||
@@ -54,6 +54,10 @@ export function composeRelease(buildPackage: BuildPackage) {
|
||||
createFilesForSecondaryEntryPoint(buildPackage, releasePath);
|
||||
}
|
||||
|
||||
if (buildPackage.copySecondaryEntryPointStylesToRoot) {
|
||||
copySecondaryEntryPointStylesheets(buildPackage, releasePath);
|
||||
}
|
||||
|
||||
if (buildPackage.exportsSecondaryEntryPointsAtRoot) {
|
||||
// Add re-exports to the root d.ts file to prevent errors of the form
|
||||
// "@angular/material/material has no exported member 'MATERIAL_SANITY_CHECKS."
|
||||
@@ -102,3 +106,13 @@ function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePa
|
||||
createMetadataReexportFile(releasePath, `./${entryPointName}/index`, entryPointName);
|
||||
});
|
||||
}
|
||||
|
||||
/** Copies the stylesheets for secondary entry-points that generate one to the release output. */
|
||||
function copySecondaryEntryPointStylesheets(buildPackage: BuildPackage, releasePath: string) {
|
||||
buildPackage.secondaryEntryPoints.forEach(entryPointName => {
|
||||
const entryPointDir = join(buildPackage.outputDir, entryPointName);
|
||||
|
||||
copyFiles(entryPointDir, `_${entryPointName}.scss`, releasePath);
|
||||
copyFiles(entryPointDir, `${entryPointName}-prebuilt.css`, releasePath);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import {join, resolve as resolvePath} from 'path';
|
||||
import {spawn} from 'child_process';
|
||||
import {writeFileSync, readFileSync} from 'fs';
|
||||
import {sync as glob} from 'glob';
|
||||
import {red} from 'chalk';
|
||||
import {BuildPackage} from './build-package';
|
||||
|
||||
/** Incrementing ID counter. */
|
||||
let nextId = 0;
|
||||
|
||||
/** Compiles the TypeScript sources of a primary or secondary entry point. */
|
||||
export async function compileEntryPoint(buildPackage: BuildPackage, tsconfigName: string,
|
||||
secondaryEntryPoint = '') {
|
||||
const entryPointPath = join(buildPackage.sourceDir, secondaryEntryPoint);
|
||||
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const ngcPath = resolvePath('./node_modules/.bin/ngc');
|
||||
const childProcess = spawn(ngcPath, ['-p', entryPointTsconfigPath], {shell: true});
|
||||
|
||||
// Pipe stdout and stderr from the child process.
|
||||
childProcess.stdout.on('data', (data: any) => console.log(`${data}`));
|
||||
childProcess.stderr.on('data', (data: any) => console.error(red(`${data}`)));
|
||||
|
||||
childProcess.on('exit', (exitCode: number) => exitCode === 0 ? resolve() : reject());
|
||||
})
|
||||
.catch(() => console.error(red(`Failed to compile ${secondaryEntryPoint}`)))
|
||||
.then(() => renamePrivateReExportsToBeUnique(buildPackage, secondaryEntryPoint));
|
||||
}
|
||||
|
||||
/** Renames `ɵa`-style re-exports generated by Angular to be unique across compilation units. */
|
||||
export function renamePrivateReExportsToBeUnique(buildPackage: BuildPackage,
|
||||
secondaryEntryPoint = '') {
|
||||
// When we compiled the typescript sources with ngc, we do entry-point individually.
|
||||
// If the root-level module re-exports multiple of these entry-points, the private-export
|
||||
// identifiers (e.g., `ɵa`) generated by ngc will collide. We work around this by suffixing
|
||||
// each of these identifiers with an ID specific to this entry point. We make this
|
||||
// replacement in the js, d.ts, and metadata output.
|
||||
if (buildPackage.exportsSecondaryEntryPointsAtRoot && secondaryEntryPoint) {
|
||||
const entryPointId = nextId++;
|
||||
const outputPath = join(buildPackage.outputDir, secondaryEntryPoint);
|
||||
glob(join(outputPath, '**/*.+(js|d.ts|metadata.json)')).forEach(filePath => {
|
||||
let fileContent = readFileSync(filePath, 'utf-8');
|
||||
fileContent = fileContent.replace(/(ɵ[a-z]+)/g, `$1${entryPointId}`);
|
||||
writeFileSync(filePath, fileContent, 'utf-8');
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user