mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
chore: don't hard-code cdk build order (#6207)
* chore: don't hard-code cdk build order * Use BuildPackage * packagename grep * fix rollup globals conflict
This commit is contained in:
committed by
tinayuangao
parent
c6c7908c29
commit
f913cc992a
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig-build",
|
||||
"files": [
|
||||
"public_api.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"strictMetadataEmit": true,
|
||||
"flatModuleOutFile": "index.js",
|
||||
"flatModuleId": "@angular/cdk/testing",
|
||||
"skipTemplateCodegen": true
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"noUnusedParameters": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"lib": ["es2015", "dom", "es2016.array.include"],
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../dist/tools/gulp",
|
||||
|
||||
@@ -2,10 +2,8 @@ import {join} from 'path';
|
||||
import {main as tsc} from '@angular/tsc-wrapped';
|
||||
import {buildConfig} from './build-config';
|
||||
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
|
||||
import {
|
||||
buildPrimaryEntryPointBundles,
|
||||
buildSecondaryEntryPointBundles
|
||||
} from 'material2-build-tools';
|
||||
import {buildPrimaryEntryPointBundles, buildSecondaryEntryPointBundles} from './build-bundles';
|
||||
|
||||
|
||||
const {packagesDir, outputDir} = buildConfig;
|
||||
|
||||
@@ -23,9 +21,6 @@ export class BuildPackage {
|
||||
/** Path to the package output. */
|
||||
packageOut: string;
|
||||
|
||||
/** Secondary entry points for the package. */
|
||||
secondaryEntryPoints: string[];
|
||||
|
||||
/** Path to the entry file of the package in the output directory. */
|
||||
private entryFilePath: string;
|
||||
|
||||
@@ -35,6 +30,17 @@ export class BuildPackage {
|
||||
/** Path to the tsconfig file, which will be used to build the tests. */
|
||||
private tsconfigTests: string;
|
||||
|
||||
/** Secondary entry points for the package. */
|
||||
get secondaryEntryPoints(): string[] {
|
||||
if (!this._secondaryEntryPoints) {
|
||||
this._secondaryEntryPoints = getSecondaryEntryPointsForPackage(this);
|
||||
}
|
||||
|
||||
return this._secondaryEntryPoints;
|
||||
}
|
||||
|
||||
private _secondaryEntryPoints: string[];
|
||||
|
||||
constructor(public packageName: string, public dependencies: BuildPackage[] = []) {
|
||||
this.packageRoot = join(packagesDir, packageName);
|
||||
this.packageOut = join(outputDir, 'packages', packageName);
|
||||
@@ -43,8 +49,6 @@ export class BuildPackage {
|
||||
this.tsconfigTests = join(this.packageRoot, testsTsconfigName);
|
||||
|
||||
this.entryFilePath = join(this.packageOut, 'index.js');
|
||||
|
||||
this.secondaryEntryPoints = getSecondaryEntryPointsForPackage(packageName);
|
||||
}
|
||||
|
||||
/** Compiles the package sources with all secondary entry points. */
|
||||
|
||||
@@ -47,7 +47,7 @@ export function composeRelease(buildPackage: BuildPackage) {
|
||||
function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePath: string) {
|
||||
const {packageName, packageOut} = buildPackage;
|
||||
|
||||
getSecondaryEntryPointsForPackage(packageName).forEach(entryPointName => {
|
||||
getSecondaryEntryPointsForPackage(buildPackage).forEach(entryPointName => {
|
||||
// Create a directory in the root of the package for this entry point that contains
|
||||
// * A package.json that lists the different bundle locations
|
||||
// * An index.d.ts file that re-exports the index.d.ts from the typings/ directory
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
|
||||
import {join} from 'path';
|
||||
import {getSubdirectoryNames} from './secondary-entry-points';
|
||||
import {buildConfig} from './build-config';
|
||||
|
||||
/** Method that converts dash-case strings to a camel-based string. */
|
||||
const dashCaseToCamelCase = (str: string) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
||||
|
||||
/** List of available secondary entry-points for the CDK package. */
|
||||
const cdkSecondaryEntryPoints = getSecondaryEntryPointsForPackage('cdk');
|
||||
/** List of potential secondary entry-points for the CDK package. */
|
||||
const cdkSecondaryEntryPoints = getSubdirectoryNames(join(buildConfig.packagesDir, 'cdk'));
|
||||
|
||||
/** Object with all CDK entry points in the format of Rollup globals. */
|
||||
const rollupCdkEntryPoints = cdkSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => {
|
||||
|
||||
@@ -1,35 +1,87 @@
|
||||
/**
|
||||
* List of cdk entry-points in the order that they must be built. This is necessary because
|
||||
* some of the entry-points depend on each other. This is temporary until we switch to bazel.
|
||||
*/
|
||||
const CDK_ENTRY_POINTS = [
|
||||
'coercion',
|
||||
'rxjs',
|
||||
'keyboard',
|
||||
'platform',
|
||||
'bidi',
|
||||
'table',
|
||||
'portal',
|
||||
'observe-content',
|
||||
'a11y',
|
||||
];
|
||||
import {join} from 'path';
|
||||
import {readdirSync, lstatSync, existsSync} from 'fs';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {BuildPackage} from './build-package';
|
||||
|
||||
|
||||
/**
|
||||
* Gets secondary entry-points for a given package.
|
||||
* Gets secondary entry-points for a given package in the order they should be built.
|
||||
*
|
||||
* This currently assumes that every directory under a package should be an entry-point. This may
|
||||
* not always be desired, in which case we can add an extra build configuration for specifying the
|
||||
* entry-points.
|
||||
* This currently assumes that every directory under a package should be an entry-point except for
|
||||
* specifically black-listed directories.
|
||||
*
|
||||
* @param packageName The package name for which to get entry points, e.g., 'cdk'.
|
||||
* @param pkg The package for which to get entry points, e.g., 'cdk'.
|
||||
* @returns An array of secondary entry-points names, e.g., ['a11y', 'bidi', ...]
|
||||
*/
|
||||
export function getSecondaryEntryPointsForPackage(packageName: string) {
|
||||
// For now, we hard-code the fact that only the CDK has secondary entry-points until we switch
|
||||
// to bazel.
|
||||
if (packageName === 'cdk') {
|
||||
return CDK_ENTRY_POINTS;
|
||||
export function getSecondaryEntryPointsForPackage(pkg: BuildPackage) {
|
||||
const packageName = pkg.packageName;
|
||||
const packageDir = pkg.packageRoot;
|
||||
|
||||
// Get the list of all entry-points as the list of directories in the package that have a
|
||||
// tsconfig-build.json
|
||||
const entryPoints = getSubdirectoryNames(packageDir)
|
||||
.filter(d => existsSync(join(packageDir, d, 'tsconfig-build.json')));
|
||||
|
||||
// Create nodes that comprise the build graph.
|
||||
const buildNodes: BuildNode[] = entryPoints.map(p => ({name: p, deps: []}));
|
||||
|
||||
// Create a lookup for name -> build graph node.
|
||||
const nodeLookup = buildNodes.reduce((lookup, node) => {
|
||||
return lookup.set(node.name, node);
|
||||
}, new Map<string, BuildNode>());
|
||||
|
||||
// Regex used to extract entry-point name from an import statement referencing that entry-point.
|
||||
// E.g., extract "portal" from "from '@angular/cdk/portal';".
|
||||
const importRegex = new RegExp(`${packageName}/(.+)';`);
|
||||
|
||||
// Update the deps for each node to point to the appropriate BuildNodes.
|
||||
buildNodes.forEach(node => {
|
||||
// Look for any imports that reference this same umbrella package and get the corresponding
|
||||
// BuildNode for each by looking at the import statements with grep.
|
||||
node.deps = spawnSync('egrep', [
|
||||
'-roh',
|
||||
'--include', '*.ts',
|
||||
`from.'@angular/${packageName}/.+';`,
|
||||
`${packageDir}/${node.name}/`
|
||||
])
|
||||
.stdout
|
||||
.toString()
|
||||
.split('\n')
|
||||
.filter(String)
|
||||
.map(importStatement => importStatement.match(importRegex)![1])
|
||||
.map(depName => nodeLookup.get(depName)!) || [];
|
||||
});
|
||||
|
||||
// Concatenate the build order for each node into one global build order.
|
||||
// Duplicates are automatically omitted by getBuildOrder.
|
||||
return buildNodes.reduce((order: string[], node) => {
|
||||
return [...order, ...getBuildOrder(node)];
|
||||
}, []);
|
||||
}
|
||||
|
||||
/** Gets the build order for a given node with DFS. */
|
||||
function getBuildOrder(node: BuildNode): string[] {
|
||||
if (node.visited) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
let buildOrder: string[] = [];
|
||||
for (const dep of node.deps) {
|
||||
buildOrder = [...buildOrder, ...getBuildOrder(dep)];
|
||||
}
|
||||
|
||||
node.visited = true;
|
||||
return [...buildOrder, node.name];
|
||||
}
|
||||
|
||||
/** Gets the names of all subdirectories for a given path. */
|
||||
export function getSubdirectoryNames(dir: string): string[] {
|
||||
return readdirSync(dir).filter(f => lstatSync(join(dir, f)).isDirectory());
|
||||
}
|
||||
|
||||
/** A node in the build graph of a package's entry-points. */
|
||||
interface BuildNode {
|
||||
name: string;
|
||||
deps: BuildNode[];
|
||||
visited?: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user