Skip to content

Commit bae213d

Browse files
devversionandrewseguin
authored andcommitted
build: dynamic build config for packaging (#4939)
* build: dynamic build config for packaging * Make discussed changes
1 parent 22e1449 commit bae213d

25 files changed

+241
-125
lines changed

build-config.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Build configuration for the packaging tool. This file will be automatically detected and used
3+
* to build the different packages inside of Material.
4+
*/
5+
const {join} = require('path');
6+
7+
/** Current version of the project*/
8+
const buildVersion = require('./package.json').version;
9+
10+
/** License that will be placed inside of all created bundles. */
11+
const buildLicense = `/**
12+
* @license Angular Material v${buildVersion}
13+
* Copyright (c) 2017 Google, Inc. https://material.angular.io/
14+
* License: MIT
15+
*/`;
16+
17+
module.exports = {
18+
projectVersion: buildVersion,
19+
projectDir: __dirname,
20+
packagesDir: join(__dirname, 'src'),
21+
outputDir: join(__dirname, 'dist'),
22+
licenseBanner: buildLicense
23+
};

tools/gulp/build-config.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

tools/gulp/gulpfile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {createPackageBuildTasks} from './packaging/build-tasks-gulp';
22

3-
/** Create gulp tasks to build the different packages in the project. */
3+
// Create gulp tasks to build the different packages in the project.
44
createPackageBuildTasks('cdk');
55
createPackageBuildTasks('material', ['cdk']);
66
createPackageBuildTasks('material-examples', ['material']);

tools/gulp/packaging/build-bundles.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
import {join} from 'path';
22
import {ScriptTarget, ModuleKind} from 'typescript';
3-
import {DIST_BUNDLES} from '../build-config';
43
import {uglifyJsFile} from './minify-sources';
54
import {createRollupBundle} from './rollup-helpers';
65
import {remapSourcemap} from './sourcemap-remap';
76
import {transpileFile} from './typescript-transpile';
7+
import {buildConfig} from './build-config';
88

99
// There are no type definitions available for these imports.
1010
const uglify = require('uglify-js');
1111
const sorcery = require('sorcery');
1212

13+
/** Directory where all bundles will be created in. */
14+
const bundlesDir = join(buildConfig.outputDir, 'bundles');
15+
1316
/** Builds the bundles for the specified package. */
1417
export async function buildPackageBundles(entryFile: string, packageName: string) {
1518
const moduleName = `ng.${packageName}`;
1619

1720
// List of paths to the package bundles.
18-
const fesm2015File = join(DIST_BUNDLES, `${packageName}.js`);
19-
const fesm2014File = join(DIST_BUNDLES, `${packageName}.es5.js`);
20-
const umdFile = join(DIST_BUNDLES, `${packageName}.umd.js`);
21-
const umdMinFile = join(DIST_BUNDLES, `${packageName}.umd.min.js`);
21+
const fesm2015File = join(bundlesDir, `${packageName}.js`);
22+
const fesm2014File = join(bundlesDir, `${packageName}.es5.js`);
23+
const umdFile = join(bundlesDir, `${packageName}.umd.js`);
24+
const umdMinFile = join(bundlesDir, `${packageName}.umd.min.js`);
2225

2326
// Build FESM-2015 bundle file.
2427
await createRollupBundle({
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {findBuildConfig} from './find-build-config';
2+
3+
export interface BuildConfig {
4+
/** Current version of the project. */
5+
projectVersion: string;
6+
/** Path to the root of the project. */
7+
projectDir: string;
8+
/** Path to the directory where all packages are living. */
9+
packagesDir: string;
10+
/** Path to the directory where the output will be stored. */
11+
outputDir: string;
12+
/** License banner that will be placed inside of every bundle. */
13+
licenseBanner: string;
14+
}
15+
16+
// Search for a build config by walking up the current working directory of the Node process.
17+
const buildConfigPath = findBuildConfig();
18+
19+
if (!buildConfigPath) {
20+
throw 'Material2 Build tools were not able to find a build config. ' +
21+
'Please create a "build-config.js" file in your project.';
22+
}
23+
24+
// Load the config file using a basic CommonJS import.
25+
export const buildConfig = require(buildConfigPath) as BuildConfig;

tools/gulp/packaging/build-release.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import {join} from 'path';
2-
import {DIST_BUNDLES, DIST_ROOT, SOURCE_ROOT, PROJECT_ROOT} from '../build-config';
32
import {copyFiles} from '../util/copy-files';
43
import {addPureAnnotationsToFile} from './pure-annotations';
54
import {updatePackageVersion} from './package-versions';
65
import {inlinePackageMetadataFiles} from './metadata-inlining';
76
import {createTypingsReexportFile} from './typings-reexport';
87
import {createMetadataReexportFile} from './metadata-reexport';
8+
import {buildConfig} from './build-config';
9+
10+
const {packagesDir, outputDir, projectDir} = buildConfig;
11+
12+
/** Directory where all bundles will be created in. */
13+
const bundlesDir = join(outputDir, 'bundles');
914

1015
/**
1116
* Copies different output files into a folder structure that follows the `angular/angular`
@@ -14,17 +19,17 @@ import {createMetadataReexportFile} from './metadata-reexport';
1419
*/
1520
export function composeRelease(packageName: string) {
1621
// To avoid refactoring of the project the package material will map to the source path `lib/`.
17-
const sourcePath = join(SOURCE_ROOT, packageName === 'material' ? 'lib' : packageName);
18-
const packagePath = join(DIST_ROOT, 'packages', packageName);
19-
const releasePath = join(DIST_ROOT, 'releases', packageName);
22+
const sourcePath = join(packagesDir, packageName === 'material' ? 'lib' : packageName);
23+
const packagePath = join(outputDir, 'packages', packageName);
24+
const releasePath = join(outputDir, 'releases', packageName);
2025

2126
inlinePackageMetadataFiles(packagePath);
2227

2328
copyFiles(packagePath, '**/*.+(d.ts|metadata.json)', join(releasePath, 'typings'));
24-
copyFiles(DIST_BUNDLES, `${packageName}.umd?(.min).js?(.map)`, join(releasePath, 'bundles'));
25-
copyFiles(DIST_BUNDLES, `${packageName}?(.es5).js?(.map)`, join(releasePath, '@angular'));
26-
copyFiles(PROJECT_ROOT, 'LICENSE', releasePath);
27-
copyFiles(SOURCE_ROOT, 'README.md', releasePath);
29+
copyFiles(bundlesDir, `${packageName}.umd?(.min).js?(.map)`, join(releasePath, 'bundles'));
30+
copyFiles(bundlesDir, `${packageName}?(.es5).js?(.map)`, join(releasePath, '@angular'));
31+
copyFiles(projectDir, 'LICENSE', releasePath);
32+
copyFiles(packagesDir, 'README.md', releasePath);
2833
copyFiles(sourcePath, 'package.json', releasePath);
2934

3035
updatePackageVersion(releasePath);

tools/gulp/packaging/build-tasks-gulp.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {task, watch, src, dest} from 'gulp';
22
import {join} from 'path';
33
import {main as tsc} from '@angular/tsc-wrapped';
4-
import {SOURCE_ROOT, DIST_ROOT, HTML_MINIFIER_OPTIONS} from '../build-config';
4+
import {buildConfig} from './build-config';
55
import {sequenceTask, sassBuildTask, copyTask, triggerLivereload} from '../util/task_helpers';
66
import {composeRelease} from './build-release';
77
import {buildPackageBundles} from './build-bundles';
@@ -10,15 +10,24 @@ import {inlineResourcesForDirectory} from './inline-resources';
1010
// There are no type definitions available for these imports.
1111
const htmlmin = require('gulp-htmlmin');
1212

13+
const {packagesDir, outputDir} = buildConfig;
14+
15+
const htmlMinifierOptions = {
16+
collapseWhitespace: true,
17+
removeComments: true,
18+
caseSensitive: true,
19+
removeAttributeQuotes: false
20+
};
21+
1322
/**
1423
* Creates a set of gulp tasks that can build the specified package.
1524
* @param packageName Name of the package. Needs to be similar to the directory name in `src/`.
1625
* @param requiredPackages Required packages that will be built before building the current package.
1726
*/
1827
export function createPackageBuildTasks(packageName: string, requiredPackages: string[] = []) {
1928
// To avoid refactoring of the project the package material will map to the source path `lib/`.
20-
const packageRoot = join(SOURCE_ROOT, packageName === 'material' ? 'lib' : packageName);
21-
const packageOut = join(DIST_ROOT, 'packages', packageName);
29+
const packageRoot = join(packagesDir, packageName === 'material' ? 'lib' : packageName);
30+
const packageOut = join(outputDir, 'packages', packageName);
2231

2332
const tsconfigBuild = join(packageRoot, 'tsconfig-build.json');
2433
const tsconfigTests = join(packageRoot, 'tsconfig-tests.json');
@@ -81,7 +90,7 @@ export function createPackageBuildTasks(packageName: string, requiredPackages: s
8190
task(`${packageName}:assets:scss`, sassBuildTask(packageOut, packageRoot, true));
8291
task(`${packageName}:assets:copy-styles`, copyTask(stylesGlob, packageOut));
8392
task(`${packageName}:assets:html`, () => {
84-
return src(htmlGlob).pipe(htmlmin(HTML_MINIFIER_OPTIONS)).pipe(dest(packageOut));
93+
return src(htmlGlob).pipe(htmlmin(htmlMinifierOptions)).pipe(dest(packageOut));
8594
});
8695

8796
task(`${packageName}:assets:inline`, () => inlineResourcesForDirectory(packageOut));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {resolve, dirname, join} from 'path';
2+
import {existsSync} from 'fs';
3+
4+
/** Name of the build config file. */
5+
const BUILD_CONFIG_FILENAME = 'build-config.js';
6+
7+
/** Method that searches for a build config file that will be used for packaging. */
8+
export function findBuildConfig(): string {
9+
let currentDir = process.cwd();
10+
11+
while (!existsSync(resolve(currentDir, BUILD_CONFIG_FILENAME))) {
12+
let parentDir = dirname(currentDir);
13+
14+
if (parentDir === currentDir) {
15+
return null;
16+
}
17+
18+
currentDir = parentDir;
19+
}
20+
21+
return join(currentDir, BUILD_CONFIG_FILENAME);
22+
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import {writeFileSync} from 'fs';
22
import {join} from 'path';
3-
import {MATERIAL_VERSION} from '../build-config';
3+
import {buildConfig} from './build-config';
4+
5+
/** Version of the project that will be used to replace the placeholder. */
6+
const {projectVersion} = buildConfig;
47

58
/** Updates the `package.json` file of the specified package. Replaces the version placeholder. */
69
export function updatePackageVersion(packageDir: string) {
710
const packagePath = join(packageDir, 'package.json');
811
const packageConfig = require(packagePath);
912

1013
// Replace the `0.0.0-PLACEHOLDER` version name with the version of the root package.json file.
11-
packageConfig.version = packageConfig.version.replace('0.0.0-PLACEHOLDER', MATERIAL_VERSION);
14+
packageConfig.version = packageConfig.version.replace('0.0.0-PLACEHOLDER', projectVersion);
1215

1316
writeFileSync(packagePath, JSON.stringify(packageConfig, null, 2));
1417
}

tools/gulp/packaging/rollup-helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {LICENSE_BANNER} from '../build-config';
1+
import {buildConfig} from './build-config';
22

33
// There are no type definitions available for these imports.
44
const rollup = require('rollup');
@@ -69,7 +69,7 @@ export function createRollupBundle(config: BundleConfig): Promise<any> {
6969
// Keep the moduleId empty because we don't want to force developers to a specific moduleId.
7070
moduleId: '',
7171
moduleName: config.moduleName || 'ng.material',
72-
banner: LICENSE_BANNER,
72+
banner: buildConfig.licenseBanner,
7373
format: config.format,
7474
dest: config.dest,
7575
globals: ROLLUP_GLOBALS,

0 commit comments

Comments
 (0)