Skip to content

Commit 056d3b2

Browse files
devversiontinayuangao
authored andcommitted
build: make packaging more flexible (#6143)
* Makes the packaging more flexible by no longer including checks that are specific to the Angular Material project (e.g `material` => `lib` mapping) * Updates the code to be more readable by making the packaging more object orientated (TS compilation helpers shouldn't be part of the gulp task generation)
1 parent 235f664 commit 056d3b2

File tree

9 files changed

+159
-128
lines changed

9 files changed

+159
-128
lines changed

tools/gulp/gulpfile.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {createPackageBuildTasks} from 'material2-build-tools';
2+
import {cdkPackage, examplesPackage, materialPackage} from './packages';
23

3-
// Create gulp tasks to build the different packages in the project.
4-
createPackageBuildTasks('cdk', [], {useSecondaryEntryPoints: true});
5-
createPackageBuildTasks('material', ['cdk']);
6-
createPackageBuildTasks('material-examples', ['material', 'cdk']);
4+
createPackageBuildTasks(cdkPackage);
5+
createPackageBuildTasks(materialPackage);
6+
createPackageBuildTasks(examplesPackage);
77

88
import './tasks/ci';
99
import './tasks/clean';

tools/gulp/packages.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {BuildPackage, buildConfig} from 'material2-build-tools';
2+
import {join} from 'path';
3+
4+
export const cdkPackage = new BuildPackage('cdk');
5+
export const materialPackage = new BuildPackage('material', [cdkPackage]);
6+
export const examplesPackage = new BuildPackage('material-examples', [materialPackage, cdkPackage]);
7+
8+
// To avoid refactoring of the project the material package will map to the source path `lib/`.
9+
materialPackage.packageRoot = join(buildConfig.packagesDir, 'lib');

tools/gulp/tasks/material-release.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,33 @@ import {join} from 'path';
33
import {writeFileSync, mkdirpSync} from 'fs-extra';
44
import {Bundler} from 'scss-bundle';
55
import {composeRelease, buildConfig, sequenceTask} from 'material2-build-tools';
6+
import {materialPackage} from '../packages';
67

78
// There are no type definitions available for these imports.
89
const gulpRename = require('gulp-rename');
910

10-
const {packagesDir, outputDir} = buildConfig;
11+
const {outputDir} = buildConfig;
12+
const {packageRoot, packageOut} = materialPackage;
1113

1214
/** Path to the directory where all releases are created. */
1315
const releasesDir = join(outputDir, 'releases');
1416

15-
/** Path to the output of the Material package. */
16-
const materialOutputPath = join(outputDir, 'packages', 'material');
17-
18-
// Path to the sources of the Material package.
19-
const materialPath = join(packagesDir, 'lib');
2017
// Path to the release output of material.
2118
const releasePath = join(releasesDir, 'material');
2219
// The entry-point for the scss theming bundle.
23-
const themingEntryPointPath = join(materialPath, 'core', 'theming', '_all-theme.scss');
20+
const themingEntryPointPath = join(packageRoot, 'core', 'theming', '_all-theme.scss');
2421
// Output path for the scss theming bundle.
2522
const themingBundlePath = join(releasePath, '_theming.scss');
2623
// Matches all pre-built theme css files
27-
const prebuiltThemeGlob = join(materialOutputPath, '**/theming/prebuilt/*.css?(.map)');
24+
const prebuiltThemeGlob = join(packageOut, '**/theming/prebuilt/*.css?(.map)');
2825
// Matches all SCSS files in the library.
29-
const allScssGlob = join(materialPath, '**/*.scss');
26+
const allScssGlob = join(packageRoot, '**/*.scss');
3027

3128
/**
3229
* Overwrite the release task for the material package. The material release will include special
3330
* files, like a bundled theming SCSS file or all prebuilt themes.
3431
*/
35-
task('material:build-release', ['material:prepare-release'], () => composeRelease('material'));
32+
task('material:build-release', ['material:prepare-release'], () => composeRelease(materialPackage));
3633

3734
/**
3835
* Task that will build the material package. It will also copy all prebuilt themes and build

tools/package-tools/build-bundles.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@ import {createRollupBundle} from './rollup-helpers';
55
import {remapSourcemap} from './sourcemap-remap';
66
import {transpileFile} from './typescript-transpile';
77
import {buildConfig} from './build-config';
8-
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
98

109
/** Directory where all bundles will be created in. */
1110
const bundlesDir = join(buildConfig.outputDir, 'bundles');
1211

13-
1412
/** Builds bundles for the primary entry-point w/ given entry file, e.g. @angular/cdk */
1513
export async function buildPrimaryEntryPointBundles(entryFile: string, packageName: string) {
1614
return createBundlesForEntryPoint({
@@ -23,18 +21,9 @@ export async function buildPrimaryEntryPointBundles(entryFile: string, packageNa
2321
});
2422
}
2523

26-
/** Builds bundles for all secondary entry-points for a given package, e.g. 'cdk' */
27-
export async function buildAllSecondaryEntryPointBundles(packageName: string) {
28-
const rootPackageDir = join(buildConfig.outputDir, 'packages', packageName);
29-
30-
return Promise.all(getSecondaryEntryPointsForPackage(packageName)
31-
.map(entryPointName => buildSecondaryEntryPointBundles(
32-
join(rootPackageDir, entryPointName, `index.js`), packageName, entryPointName)));
33-
}
34-
3524
/** Builds bundles for a single secondary entry-point w/ given entry file, e.g. @angular/cdk/a11y */
36-
export async function buildSecondaryEntryPointBundles(
37-
entryFile: string, packageName: string, entryPointName: string) {
25+
export async function buildSecondaryEntryPointBundles(entryFile: string, packageName: string,
26+
entryPointName: string) {
3827
return createBundlesForEntryPoint({
3928
entryFile,
4029
moduleName: `ng.${packageName}.${entryPointName}`,

tools/package-tools/build-package.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {join} from 'path';
2+
import {main as tsc} from '@angular/tsc-wrapped';
3+
import {buildConfig} from './build-config';
4+
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
5+
import {
6+
buildPrimaryEntryPointBundles,
7+
buildSecondaryEntryPointBundles
8+
} from 'material2-build-tools';
9+
10+
const {packagesDir, outputDir} = buildConfig;
11+
12+
/** Name of the tsconfig file that is responsible for building a package. */
13+
const buildTsconfigName = 'tsconfig-build.json';
14+
15+
/** Name of the tsconfig file that is responsible for building the tests. */
16+
const testsTsconfigName = 'tsconfig-tests.json';
17+
18+
export class BuildPackage {
19+
20+
/** Path to the package sources. */
21+
packageRoot: string;
22+
23+
/** Path to the package output. */
24+
packageOut: string;
25+
26+
/** Secondary entry points for the package. */
27+
secondaryEntryPoints: string[];
28+
29+
/** Path to the entry file of the package in the output directory. */
30+
private entryFilePath: string;
31+
32+
/** Path to the tsconfig file, which will be used to build the package. */
33+
private tsconfigBuild: string;
34+
35+
/** Path to the tsconfig file, which will be used to build the tests. */
36+
private tsconfigTests: string;
37+
38+
constructor(public packageName: string, public dependencies: BuildPackage[] = []) {
39+
this.packageRoot = join(packagesDir, packageName);
40+
this.packageOut = join(outputDir, 'packages', packageName);
41+
42+
this.tsconfigBuild = join(this.packageRoot, buildTsconfigName);
43+
this.tsconfigTests = join(this.packageRoot, testsTsconfigName);
44+
45+
this.entryFilePath = join(this.packageOut, 'index.js');
46+
47+
this.secondaryEntryPoints = getSecondaryEntryPointsForPackage(packageName);
48+
}
49+
50+
/** Compiles the package sources with all secondary entry points. */
51+
async compile() {
52+
await this._compileEntryPoint(buildTsconfigName);
53+
54+
// Walk through every secondary entry point and build the TypeScript sources sequentially.
55+
for (const entryPoint of this.secondaryEntryPoints) {
56+
await this._compileEntryPoint(buildTsconfigName, entryPoint);
57+
}
58+
}
59+
60+
/** Compiles the TypeScript test source files for the package. */
61+
async compileTests() {
62+
await this._compileEntryPoint(testsTsconfigName);
63+
}
64+
65+
/** Creates all bundles for the package and all associated entry points. */
66+
async createBundles() {
67+
await buildPrimaryEntryPointBundles(this.entryFilePath, this.packageName);
68+
69+
for (const entryPoint of this.secondaryEntryPoints) {
70+
const entryPointEntryFilePath = join(this.packageOut, entryPoint, 'index.js');
71+
await buildSecondaryEntryPointBundles(entryPointEntryFilePath, this.packageName, entryPoint);
72+
}
73+
}
74+
75+
/** Compiles the TypeScript sources of a primary or secondary entry point. */
76+
private async _compileEntryPoint(tsconfigName: string, secondaryEntryPoint?: string) {
77+
const entryPointPath = join(this.packageRoot, secondaryEntryPoint || '');
78+
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);
79+
80+
await tsc(entryPointTsconfigPath, {basePath: entryPointPath});
81+
}
82+
}

tools/package-tools/build-release.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {createMetadataReexportFile} from './metadata-reexport';
88
import {getSecondaryEntryPointsForPackage} from './secondary-entry-points';
99
import {createEntryPointPackageJson} from './entry-point-package-json';
1010
import {buildConfig} from './build-config';
11+
import {BuildPackage} from './build-package';
1112

1213
const {packagesDir, outputDir, projectDir} = buildConfig;
1314

@@ -19,46 +20,46 @@ const bundlesDir = join(outputDir, 'bundles');
1920
* release folder structure. The output will also contain a README and the according package.json
2021
* file. Additionally the package will be Closure Compiler and AOT compatible.
2122
*/
22-
export function composeRelease(packageName: string, options: ComposeReleaseOptions = {}) {
23-
// To avoid refactoring of the project the package material will map to the source path `lib/`.
24-
const sourcePath = join(packagesDir, packageName === 'material' ? 'lib' : packageName);
25-
const packagePath = join(outputDir, 'packages', packageName);
23+
export function composeRelease(buildPackage: BuildPackage) {
24+
const {packageName, packageOut, packageRoot} = buildPackage;
2625
const releasePath = join(outputDir, 'releases', packageName);
2726

28-
inlinePackageMetadataFiles(packagePath);
27+
inlinePackageMetadataFiles(packageOut);
2928

30-
copyFiles(packagePath, '**/*.+(d.ts|metadata.json)', join(releasePath, 'typings'));
29+
copyFiles(packageOut, '**/*.+(d.ts|metadata.json)', join(releasePath, 'typings'));
3130
copyFiles(bundlesDir, `${packageName}?(-*).umd.js?(.map)`, join(releasePath, 'bundles'));
3231
copyFiles(bundlesDir, `${packageName}?(.es5).js?(.map)`, join(releasePath, '@angular'));
3332
copyFiles(join(bundlesDir, packageName), '**', join(releasePath, '@angular', packageName));
3433
copyFiles(projectDir, 'LICENSE', releasePath);
3534
copyFiles(packagesDir, 'README.md', releasePath);
36-
copyFiles(sourcePath, 'package.json', releasePath);
35+
copyFiles(packageRoot, 'package.json', releasePath);
3736

3837
replaceVersionPlaceholders(releasePath);
3938
createTypingsReexportFile(releasePath, './typings/index', packageName);
4039
createMetadataReexportFile(releasePath, './typings/index', packageName);
4140

42-
if (options.useSecondaryEntryPoints) {
43-
createFilesForSecondaryEntryPoint(packageName, packagePath, releasePath);
41+
if (buildPackage.secondaryEntryPoints.length) {
42+
createFilesForSecondaryEntryPoint(buildPackage, releasePath);
4443
}
4544
}
4645

4746
/** Creates files necessary for a secondary entry-point. */
48-
function createFilesForSecondaryEntryPoint(packageName: string, packagePath: string,
49-
releasePath: string) {
47+
function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePath: string) {
48+
const {packageName, packageOut} = buildPackage;
49+
5050
getSecondaryEntryPointsForPackage(packageName).forEach(entryPointName => {
5151
// Create a directory in the root of the package for this entry point that contains
5252
// * A package.json that lists the different bundle locations
5353
// * An index.d.ts file that re-exports the index.d.ts from the typings/ directory
5454
// * A metadata.json re-export for this entry-point's metadata.
5555
const entryPointDir = join(releasePath, entryPointName);
56+
5657
mkdirpSync(entryPointDir);
5758
createEntryPointPackageJson(entryPointDir, packageName, entryPointName);
5859

5960
// Copy typings and metadata from tsc output location into the entry-point.
6061
copyFiles(
61-
join(packagePath, entryPointName),
62+
join(packageOut, entryPointName),
6263
'**/*.+(d.ts|metadata.json)',
6364
join(entryPointDir, 'typings'));
6465

@@ -73,7 +74,3 @@ function createFilesForSecondaryEntryPoint(packageName: string, packagePath: str
7374
createMetadataReexportFile(releasePath, `./${entryPointName}/index`, entryPointName);
7475
});
7576
}
76-
77-
interface ComposeReleaseOptions {
78-
useSecondaryEntryPoints?: boolean;
79-
}

0 commit comments

Comments
 (0)