mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build: dynamic build config for packaging (#4939)
* build: dynamic build config for packaging * Make discussed changes
This commit is contained in:
committed by
Andrew Seguin
parent
22e14490d2
commit
bae213d5f7
@@ -1,44 +0,0 @@
|
||||
import {join} from 'path';
|
||||
|
||||
export const MATERIAL_VERSION = require('../../package.json').version;
|
||||
|
||||
export const PROJECT_ROOT = join(__dirname, '../..');
|
||||
export const SOURCE_ROOT = join(PROJECT_ROOT, 'src');
|
||||
|
||||
/** Root build output directory */
|
||||
export const DIST_ROOT = join(PROJECT_ROOT, 'dist');
|
||||
|
||||
/** Output subdirectory where all bundles will be written (flat ES modules and UMD) */
|
||||
export const DIST_BUNDLES = join(DIST_ROOT, 'bundles');
|
||||
|
||||
/** Output subdirectory where all library artifacts will be written (compiled JS, CSS, etc.) */
|
||||
export const DIST_MATERIAL = join(DIST_ROOT, 'packages', 'material');
|
||||
export const DIST_CDK = join(DIST_ROOT, 'packages', 'cdk');
|
||||
export const DIST_DEMOAPP = join(DIST_ROOT, 'packages', 'demo-app');
|
||||
export const DIST_E2EAPP = join(DIST_ROOT, 'packages', 'e2e-app');
|
||||
export const DIST_EXAMPLES = join(DIST_ROOT, 'packages', 'examples');
|
||||
|
||||
export const DIST_RELEASES = join(DIST_ROOT, 'releases');
|
||||
|
||||
export const COVERAGE_RESULT_FILE = join(DIST_ROOT, 'coverage', 'coverage-summary.json');
|
||||
|
||||
export const HTML_MINIFIER_OPTIONS = {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
caseSensitive: true,
|
||||
removeAttributeQuotes: false
|
||||
};
|
||||
|
||||
/** Packages that will be published to NPM by the release task. */
|
||||
export const RELEASE_PACKAGES = [
|
||||
'cdk',
|
||||
'material',
|
||||
];
|
||||
|
||||
export const LICENSE_BANNER = `/**
|
||||
* @license Angular Material v${MATERIAL_VERSION}
|
||||
* Copyright (c) 2017 Google, Inc. https://material.angular.io/
|
||||
* License: MIT
|
||||
*/`;
|
||||
|
||||
export const COMPONENTS_DIR = join(SOURCE_ROOT, 'lib');
|
||||
@@ -1,6 +1,6 @@
|
||||
import {createPackageBuildTasks} from './packaging/build-tasks-gulp';
|
||||
|
||||
/** Create gulp tasks to build the different packages in the project. */
|
||||
// Create gulp tasks to build the different packages in the project.
|
||||
createPackageBuildTasks('cdk');
|
||||
createPackageBuildTasks('material', ['cdk']);
|
||||
createPackageBuildTasks('material-examples', ['material']);
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
import {join} from 'path';
|
||||
import {ScriptTarget, ModuleKind} from 'typescript';
|
||||
import {DIST_BUNDLES} from '../build-config';
|
||||
import {uglifyJsFile} from './minify-sources';
|
||||
import {createRollupBundle} from './rollup-helpers';
|
||||
import {remapSourcemap} from './sourcemap-remap';
|
||||
import {transpileFile} from './typescript-transpile';
|
||||
import {buildConfig} from './build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const uglify = require('uglify-js');
|
||||
const sorcery = require('sorcery');
|
||||
|
||||
/** Directory where all bundles will be created in. */
|
||||
const bundlesDir = join(buildConfig.outputDir, 'bundles');
|
||||
|
||||
/** Builds the bundles for the specified package. */
|
||||
export async function buildPackageBundles(entryFile: string, packageName: string) {
|
||||
const moduleName = `ng.${packageName}`;
|
||||
|
||||
// List of paths to the package bundles.
|
||||
const fesm2015File = join(DIST_BUNDLES, `${packageName}.js`);
|
||||
const fesm2014File = join(DIST_BUNDLES, `${packageName}.es5.js`);
|
||||
const umdFile = join(DIST_BUNDLES, `${packageName}.umd.js`);
|
||||
const umdMinFile = join(DIST_BUNDLES, `${packageName}.umd.min.js`);
|
||||
const fesm2015File = join(bundlesDir, `${packageName}.js`);
|
||||
const fesm2014File = join(bundlesDir, `${packageName}.es5.js`);
|
||||
const umdFile = join(bundlesDir, `${packageName}.umd.js`);
|
||||
const umdMinFile = join(bundlesDir, `${packageName}.umd.min.js`);
|
||||
|
||||
// Build FESM-2015 bundle file.
|
||||
await createRollupBundle({
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import {findBuildConfig} from './find-build-config';
|
||||
|
||||
export interface BuildConfig {
|
||||
/** Current version of the project. */
|
||||
projectVersion: string;
|
||||
/** Path to the root of the project. */
|
||||
projectDir: string;
|
||||
/** Path to the directory where all packages are living. */
|
||||
packagesDir: string;
|
||||
/** Path to the directory where the output will be stored. */
|
||||
outputDir: string;
|
||||
/** License banner that will be placed inside of every bundle. */
|
||||
licenseBanner: string;
|
||||
}
|
||||
|
||||
// Search for a build config by walking up the current working directory of the Node process.
|
||||
const buildConfigPath = findBuildConfig();
|
||||
|
||||
if (!buildConfigPath) {
|
||||
throw 'Material2 Build tools were not able to find a build config. ' +
|
||||
'Please create a "build-config.js" file in your project.';
|
||||
}
|
||||
|
||||
// Load the config file using a basic CommonJS import.
|
||||
export const buildConfig = require(buildConfigPath) as BuildConfig;
|
||||
@@ -1,11 +1,16 @@
|
||||
import {join} from 'path';
|
||||
import {DIST_BUNDLES, DIST_ROOT, SOURCE_ROOT, PROJECT_ROOT} from '../build-config';
|
||||
import {copyFiles} from '../util/copy-files';
|
||||
import {addPureAnnotationsToFile} from './pure-annotations';
|
||||
import {updatePackageVersion} from './package-versions';
|
||||
import {inlinePackageMetadataFiles} from './metadata-inlining';
|
||||
import {createTypingsReexportFile} from './typings-reexport';
|
||||
import {createMetadataReexportFile} from './metadata-reexport';
|
||||
import {buildConfig} from './build-config';
|
||||
|
||||
const {packagesDir, outputDir, projectDir} = buildConfig;
|
||||
|
||||
/** Directory where all bundles will be created in. */
|
||||
const bundlesDir = join(outputDir, 'bundles');
|
||||
|
||||
/**
|
||||
* Copies different output files into a folder structure that follows the `angular/angular`
|
||||
@@ -14,17 +19,17 @@ import {createMetadataReexportFile} from './metadata-reexport';
|
||||
*/
|
||||
export function composeRelease(packageName: string) {
|
||||
// To avoid refactoring of the project the package material will map to the source path `lib/`.
|
||||
const sourcePath = join(SOURCE_ROOT, packageName === 'material' ? 'lib' : packageName);
|
||||
const packagePath = join(DIST_ROOT, 'packages', packageName);
|
||||
const releasePath = join(DIST_ROOT, 'releases', packageName);
|
||||
const sourcePath = join(packagesDir, packageName === 'material' ? 'lib' : packageName);
|
||||
const packagePath = join(outputDir, 'packages', packageName);
|
||||
const releasePath = join(outputDir, 'releases', packageName);
|
||||
|
||||
inlinePackageMetadataFiles(packagePath);
|
||||
|
||||
copyFiles(packagePath, '**/*.+(d.ts|metadata.json)', join(releasePath, 'typings'));
|
||||
copyFiles(DIST_BUNDLES, `${packageName}.umd?(.min).js?(.map)`, join(releasePath, 'bundles'));
|
||||
copyFiles(DIST_BUNDLES, `${packageName}?(.es5).js?(.map)`, join(releasePath, '@angular'));
|
||||
copyFiles(PROJECT_ROOT, 'LICENSE', releasePath);
|
||||
copyFiles(SOURCE_ROOT, 'README.md', releasePath);
|
||||
copyFiles(bundlesDir, `${packageName}.umd?(.min).js?(.map)`, join(releasePath, 'bundles'));
|
||||
copyFiles(bundlesDir, `${packageName}?(.es5).js?(.map)`, join(releasePath, '@angular'));
|
||||
copyFiles(projectDir, 'LICENSE', releasePath);
|
||||
copyFiles(packagesDir, 'README.md', releasePath);
|
||||
copyFiles(sourcePath, 'package.json', releasePath);
|
||||
|
||||
updatePackageVersion(releasePath);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {task, watch, src, dest} from 'gulp';
|
||||
import {join} from 'path';
|
||||
import {main as tsc} from '@angular/tsc-wrapped';
|
||||
import {SOURCE_ROOT, DIST_ROOT, HTML_MINIFIER_OPTIONS} from '../build-config';
|
||||
import {buildConfig} from './build-config';
|
||||
import {sequenceTask, sassBuildTask, copyTask, triggerLivereload} from '../util/task_helpers';
|
||||
import {composeRelease} from './build-release';
|
||||
import {buildPackageBundles} from './build-bundles';
|
||||
@@ -10,6 +10,15 @@ import {inlineResourcesForDirectory} from './inline-resources';
|
||||
// There are no type definitions available for these imports.
|
||||
const htmlmin = require('gulp-htmlmin');
|
||||
|
||||
const {packagesDir, outputDir} = buildConfig;
|
||||
|
||||
const htmlMinifierOptions = {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
caseSensitive: true,
|
||||
removeAttributeQuotes: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a set of gulp tasks that can build the specified package.
|
||||
* @param packageName Name of the package. Needs to be similar to the directory name in `src/`.
|
||||
@@ -17,8 +26,8 @@ const htmlmin = require('gulp-htmlmin');
|
||||
*/
|
||||
export function createPackageBuildTasks(packageName: string, requiredPackages: string[] = []) {
|
||||
// To avoid refactoring of the project the package material will map to the source path `lib/`.
|
||||
const packageRoot = join(SOURCE_ROOT, packageName === 'material' ? 'lib' : packageName);
|
||||
const packageOut = join(DIST_ROOT, 'packages', packageName);
|
||||
const packageRoot = join(packagesDir, packageName === 'material' ? 'lib' : packageName);
|
||||
const packageOut = join(outputDir, 'packages', packageName);
|
||||
|
||||
const tsconfigBuild = join(packageRoot, 'tsconfig-build.json');
|
||||
const tsconfigTests = join(packageRoot, 'tsconfig-tests.json');
|
||||
@@ -81,7 +90,7 @@ export function createPackageBuildTasks(packageName: string, requiredPackages: s
|
||||
task(`${packageName}:assets:scss`, sassBuildTask(packageOut, packageRoot, true));
|
||||
task(`${packageName}:assets:copy-styles`, copyTask(stylesGlob, packageOut));
|
||||
task(`${packageName}:assets:html`, () => {
|
||||
return src(htmlGlob).pipe(htmlmin(HTML_MINIFIER_OPTIONS)).pipe(dest(packageOut));
|
||||
return src(htmlGlob).pipe(htmlmin(htmlMinifierOptions)).pipe(dest(packageOut));
|
||||
});
|
||||
|
||||
task(`${packageName}:assets:inline`, () => inlineResourcesForDirectory(packageOut));
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import {resolve, dirname, join} from 'path';
|
||||
import {existsSync} from 'fs';
|
||||
|
||||
/** Name of the build config file. */
|
||||
const BUILD_CONFIG_FILENAME = 'build-config.js';
|
||||
|
||||
/** Method that searches for a build config file that will be used for packaging. */
|
||||
export function findBuildConfig(): string {
|
||||
let currentDir = process.cwd();
|
||||
|
||||
while (!existsSync(resolve(currentDir, BUILD_CONFIG_FILENAME))) {
|
||||
let parentDir = dirname(currentDir);
|
||||
|
||||
if (parentDir === currentDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
currentDir = parentDir;
|
||||
}
|
||||
|
||||
return join(currentDir, BUILD_CONFIG_FILENAME);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import {writeFileSync} from 'fs';
|
||||
import {join} from 'path';
|
||||
import {MATERIAL_VERSION} from '../build-config';
|
||||
import {buildConfig} from './build-config';
|
||||
|
||||
/** Version of the project that will be used to replace the placeholder. */
|
||||
const {projectVersion} = buildConfig;
|
||||
|
||||
/** Updates the `package.json` file of the specified package. Replaces the version placeholder. */
|
||||
export function updatePackageVersion(packageDir: string) {
|
||||
@@ -8,7 +11,7 @@ export function updatePackageVersion(packageDir: string) {
|
||||
const packageConfig = require(packagePath);
|
||||
|
||||
// Replace the `0.0.0-PLACEHOLDER` version name with the version of the root package.json file.
|
||||
packageConfig.version = packageConfig.version.replace('0.0.0-PLACEHOLDER', MATERIAL_VERSION);
|
||||
packageConfig.version = packageConfig.version.replace('0.0.0-PLACEHOLDER', projectVersion);
|
||||
|
||||
writeFileSync(packagePath, JSON.stringify(packageConfig, null, 2));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {LICENSE_BANNER} from '../build-config';
|
||||
import {buildConfig} from './build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const rollup = require('rollup');
|
||||
@@ -69,7 +69,7 @@ export function createRollupBundle(config: BundleConfig): Promise<any> {
|
||||
// Keep the moduleId empty because we don't want to force developers to a specific moduleId.
|
||||
moduleId: '',
|
||||
moduleName: config.moduleName || 'ng.material',
|
||||
banner: LICENSE_BANNER,
|
||||
banner: buildConfig.licenseBanner,
|
||||
format: config.format,
|
||||
dest: config.dest,
|
||||
globals: ROLLUP_GLOBALS,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {writeFileSync} from 'fs';
|
||||
import {LICENSE_BANNER} from '../build-config';
|
||||
import {buildConfig} from './build-config';
|
||||
import {join} from 'path';
|
||||
|
||||
/** Create a typing file that links to the bundled definitions of NGC. */
|
||||
export function createTypingsReexportFile(outputDir: string, entryName: string) {
|
||||
writeFileSync(join(outputDir, `${entryName}.d.ts`),
|
||||
LICENSE_BANNER + '\nexport * from "./typings/index";'
|
||||
buildConfig.licenseBanner + '\nexport * from "./typings/index";'
|
||||
);
|
||||
}
|
||||
|
||||
+13
-4
@@ -1,10 +1,19 @@
|
||||
import {task} from 'gulp';
|
||||
import {copySync} from 'fs-extra';
|
||||
import {DIST_DEMOAPP, DIST_RELEASES} from '../build-config';
|
||||
import {sequenceTask, execNodeTask} from '../util/task_helpers';
|
||||
import {join} from 'path';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
const tsconfigFile = join(DIST_DEMOAPP, 'tsconfig-aot.json');
|
||||
const {outputDir} = buildConfig;
|
||||
|
||||
/** Path to the directory where all releases are living. */
|
||||
const releasesDir = join(outputDir, 'releases');
|
||||
|
||||
/** Path to the demo-app output directory. */
|
||||
const demoAppOut = join(outputDir, 'packages', 'demo-app');
|
||||
|
||||
/** Path to the tsconfig file that builds the AOT files. */
|
||||
const tsconfigFile = join(demoAppOut, 'tsconfig-aot.json');
|
||||
|
||||
/** Builds the demo-app and material. To be able to run NGC, apply the metadata workaround. */
|
||||
task('aot:deps', sequenceTask(
|
||||
@@ -16,8 +25,8 @@ task('aot:deps', sequenceTask(
|
||||
// As a workaround for https://github.com/angular/angular/issues/12249, we need to
|
||||
// copy the Material and CDK ESM output inside of the demo-app output.
|
||||
task('aot:copy-release', () => {
|
||||
copySync(join(DIST_RELEASES, 'material'), join(DIST_DEMOAPP, 'material'));
|
||||
copySync(join(DIST_RELEASES, 'cdk'), join(DIST_DEMOAPP, 'cdk'));
|
||||
copySync(join(releasesDir, 'material'), join(demoAppOut, 'material'));
|
||||
copySync(join(releasesDir, 'cdk'), join(demoAppOut, 'cdk'));
|
||||
});
|
||||
|
||||
/** Build the demo-app and a release to confirm that the library is AOT-compatible. */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {task} from 'gulp';
|
||||
import {DIST_ROOT} from '../build-config';
|
||||
import {cleanTask} from '../util/task_helpers';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
|
||||
/** Deletes the dist/ directory. */
|
||||
task('clean', cleanTask(DIST_ROOT));
|
||||
task('clean', cleanTask(buildConfig.outputDir));
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import {task} from 'gulp';
|
||||
import {join} from 'path';
|
||||
import {existsSync} from 'fs-extra';
|
||||
import {COVERAGE_RESULT_FILE} from '../build-config';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {isTravisMasterBuild} from '../util/travis-ci';
|
||||
import {openFirebaseDashboardApp} from '../util/firebase';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
/** Path to the file that includes all coverage information form Karma. */
|
||||
const coverageResultFile = join(buildConfig.outputDir, 'coverage/coverage-summary.json');
|
||||
|
||||
task('coverage:upload', () => {
|
||||
if (!existsSync(COVERAGE_RESULT_FILE)) {
|
||||
if (!existsSync(coverageResultFile)) {
|
||||
throw new Error('No coverage file has been found!');
|
||||
}
|
||||
|
||||
@@ -14,7 +18,7 @@ task('coverage:upload', () => {
|
||||
throw new Error('Coverage results will be only uploaded inside of Travis Push builds.');
|
||||
}
|
||||
|
||||
let results = require(COVERAGE_RESULT_FILE)['total'];
|
||||
let results = require(coverageResultFile)['total'];
|
||||
|
||||
// To reduce database payload, the covered lines won't be pushed to the Firebase database.
|
||||
delete results['linesCovered'];
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
import {task, watch} from 'gulp';
|
||||
import {DIST_ROOT, SOURCE_ROOT, PROJECT_ROOT, DIST_BUNDLES, DIST_MATERIAL} from '../build-config';
|
||||
import {
|
||||
sassBuildTask, tsBuildTask, copyTask, buildAppTask, sequenceTask, triggerLivereload,
|
||||
serverTask
|
||||
} from '../util/task_helpers';
|
||||
import {join} from 'path';
|
||||
import {copyFiles} from '../util/copy-files';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
// These imports don't have any typings provided.
|
||||
const firebaseTools = require('firebase-tools');
|
||||
|
||||
const appDir = join(SOURCE_ROOT, 'demo-app');
|
||||
const outDir = join(DIST_ROOT, 'packages', 'demo-app');
|
||||
const {outputDir, packagesDir, projectDir} = buildConfig;
|
||||
|
||||
/** Path to the directory where all bundles live. */
|
||||
const bundlesDir = join(outputDir, 'bundles');
|
||||
|
||||
const appDir = join(packagesDir, 'demo-app');
|
||||
const outDir = join(outputDir, 'packages', 'demo-app');
|
||||
|
||||
/** Path to the output of the Material package. */
|
||||
const materialOutPath = join(outputDir, 'packages', 'material');
|
||||
|
||||
/** Array of vendors that are required to serve the demo-app. */
|
||||
const appVendors = [
|
||||
@@ -29,7 +37,7 @@ task(':watch:devapp', () => {
|
||||
// The themes for the demo-app are built by the demo-app using the SCSS mixins from Material.
|
||||
// Therefore when the CSS files have been changed the SCSS mixins have been refreshed and
|
||||
// copied over. Rebuilt the theme CSS using the updated SCSS mixins.
|
||||
watch(join(DIST_MATERIAL, '**/*.css'), [':build:devapp:scss', triggerLivereload]);
|
||||
watch(join(materialOutPath, '**/*.css'), [':build:devapp:scss', triggerLivereload]);
|
||||
});
|
||||
|
||||
/** Path to the demo-app tsconfig file. */
|
||||
@@ -48,9 +56,9 @@ task('serve:devapp', ['build:devapp'], sequenceTask(
|
||||
|
||||
/** Task that copies all vendors into the demo-app package. Allows hosting the app on firebase. */
|
||||
task('stage-deploy:devapp', ['build:devapp'], () => {
|
||||
copyFiles(join(PROJECT_ROOT, 'node_modules'), vendorGlob, join(outDir, 'node_modules'));
|
||||
copyFiles(DIST_BUNDLES, '*.+(js|map)', join(outDir, 'dist/bundles'));
|
||||
copyFiles(DIST_MATERIAL, '**/prebuilt/*.+(css|map)', join(outDir, 'dist/packages/material'));
|
||||
copyFiles(join(projectDir, 'node_modules'), vendorGlob, join(outDir, 'node_modules'));
|
||||
copyFiles(bundlesDir, '*.+(js|map)', join(outDir, 'dist/bundles'));
|
||||
copyFiles(materialOutPath, '**/prebuilt/*.+(css|map)', join(outDir, 'dist/packages/material'));
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -58,7 +66,7 @@ task('stage-deploy:devapp', ['build:devapp'], () => {
|
||||
* set for project directory using the Firebase CLI.
|
||||
*/
|
||||
task('deploy:devapp', ['stage-deploy:devapp'], () => {
|
||||
return firebaseTools.deploy({cwd: PROJECT_ROOT, only: 'hosting'})
|
||||
return firebaseTools.deploy({cwd: projectDir, only: 'hosting'})
|
||||
// Firebase tools opens a persistent websocket connection and the process will never exit.
|
||||
.then(() => { console.log('Successfully deployed the demo-app to firebase'); process.exit(0); })
|
||||
.catch((err: any) => { console.log(err); process.exit(1); });
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {task, src, dest} from 'gulp';
|
||||
import {Dgeni} from 'dgeni';
|
||||
import * as path from 'path';
|
||||
import {DIST_ROOT, HTML_MINIFIER_OPTIONS, SOURCE_ROOT} from '../build-config';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const markdown = require('gulp-markdown');
|
||||
@@ -13,7 +13,9 @@ const htmlmin = require('gulp-htmlmin');
|
||||
const hljs = require('highlight.js');
|
||||
const dom = require('gulp-dom');
|
||||
|
||||
const DIST_DOCS = path.join(DIST_ROOT, 'docs');
|
||||
const {outputDir, packagesDir} = buildConfig;
|
||||
|
||||
const DIST_DOCS = path.join(outputDir, 'docs');
|
||||
|
||||
// Our docs contain comments of the form `<!-- example(...) -->` which serve as placeholders where
|
||||
// example code should be inserted. We replace these comments with divs that have a
|
||||
@@ -48,6 +50,14 @@ const MARKDOWN_TAGS_TO_CLASS_ALIAS = [
|
||||
'code',
|
||||
];
|
||||
|
||||
// Options for the html-minifier that minifies the generated HTML files.
|
||||
const htmlMinifierOptions = {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
caseSensitive: true,
|
||||
removeAttributeQuotes: false
|
||||
};
|
||||
|
||||
/** Generate all docs content. */
|
||||
task('docs', [
|
||||
'markdown-docs',
|
||||
@@ -105,13 +115,13 @@ task('api-docs', () => {
|
||||
/** Generates minified html api docs. */
|
||||
task('minified-api-docs', ['api-docs'], () => {
|
||||
return src('dist/docs/api/*.html')
|
||||
.pipe(htmlmin(HTML_MINIFIER_OPTIONS))
|
||||
.pipe(htmlmin(htmlMinifierOptions))
|
||||
.pipe(dest('dist/docs/api/'));
|
||||
});
|
||||
|
||||
/** Copies example sources to be used as plunker assets for the docs site. */
|
||||
task('plunker-example-assets', () => {
|
||||
src(path.join(SOURCE_ROOT, 'material-examples', '**/*'))
|
||||
src(path.join(packagesDir, 'material-examples', '**/*'))
|
||||
.pipe(dest(path.join(DIST_DOCS, 'plunker', 'examples')));
|
||||
});
|
||||
|
||||
|
||||
+11
-6
@@ -1,16 +1,21 @@
|
||||
import {task, watch} from 'gulp';
|
||||
import {join} from 'path';
|
||||
import {SOURCE_ROOT, DIST_E2EAPP, PROJECT_ROOT, DIST_RELEASES} from '../build-config';
|
||||
import {ngcBuildTask, copyTask, execNodeTask, sequenceTask, serverTask} from '../util/task_helpers';
|
||||
import {copySync} from 'fs-extra';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const gulpConnect = require('gulp-connect');
|
||||
|
||||
const appDir = join(SOURCE_ROOT, 'e2e-app');
|
||||
const outDir = DIST_E2EAPP;
|
||||
const {outputDir, packagesDir, projectDir} = buildConfig;
|
||||
|
||||
const PROTRACTOR_CONFIG_PATH = join(PROJECT_ROOT, 'test/protractor.conf.js');
|
||||
/** Path to the directory where all releases are created. */
|
||||
const releasesDir = join(outputDir, 'releases');
|
||||
|
||||
const appDir = join(packagesDir, 'e2e-app');
|
||||
const outDir = join(outputDir, 'packages', 'e2e-app');
|
||||
|
||||
const PROTRACTOR_CONFIG_PATH = join(projectDir, 'test/protractor.conf.js');
|
||||
const tsconfigPath = join(outDir, 'tsconfig-build.json');
|
||||
|
||||
/** Glob that matches all files that need to be copied to the output folder. */
|
||||
@@ -69,7 +74,7 @@ task('serve:e2eapp:watch', ['serve:e2eapp', 'material:watch', ':watch:e2eapp']);
|
||||
// As a workaround for https://github.com/angular/angular/issues/12249, we need to
|
||||
// copy the Material and CDK ESM output inside of the demo-app output.
|
||||
task('e2e-app:copy-release', () => {
|
||||
copySync(join(DIST_RELEASES, 'material'), join(outDir, 'material'));
|
||||
copySync(join(DIST_RELEASES, 'cdk'), join(outDir, 'cdk'));
|
||||
copySync(join(releasesDir, 'material'), join(outDir, 'material'));
|
||||
copySync(join(releasesDir, 'cdk'), join(outDir, 'cdk'));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {task} from 'gulp';
|
||||
import {execNodeTask} from '../util/task_helpers';
|
||||
import {DIST_MATERIAL, DIST_CDK} from '../build-config';
|
||||
import {join} from 'path';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
/** Glob that matches all SCSS or CSS files that should be linted. */
|
||||
const stylesGlob = '+(tools|src)/**/*.+(css|scss)';
|
||||
@@ -10,11 +11,17 @@ const tsLintBaseFlags = [
|
||||
'-c', 'tslint.json', '+(src|e2e|tools)/**/*.ts', '--exclude', '**/node_modules/**/*'
|
||||
];
|
||||
|
||||
/** Path to the output of the Material package. */
|
||||
const materialOutPath = join(buildConfig.outputDir, 'packages', 'material');
|
||||
|
||||
/** Path to the output of the CDK package. */
|
||||
const cdkOutPath = join(buildConfig.outputDir, 'packages', 'cdk');
|
||||
|
||||
task('lint', ['tslint', 'stylelint', 'madge']);
|
||||
|
||||
/** Task that runs madge to detect circular dependencies. */
|
||||
task('madge', ['material:clean-build'], execNodeTask(
|
||||
'madge', ['--circular', DIST_MATERIAL, DIST_CDK])
|
||||
'madge', ['--circular', materialOutPath, cdkOutPath])
|
||||
);
|
||||
|
||||
/** Task to lint Angular Material's scss stylesheets. */
|
||||
|
||||
@@ -3,22 +3,29 @@ import {join} from 'path';
|
||||
import {writeFileSync} from 'fs';
|
||||
import {Bundler} from 'scss-bundle';
|
||||
import {sequenceTask} from '../util/task_helpers';
|
||||
import {COMPONENTS_DIR, DIST_MATERIAL, DIST_RELEASES} from '../build-config';
|
||||
import {composeRelease} from '../packaging/build-release';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const gulpRename = require('gulp-rename');
|
||||
|
||||
const {packagesDir, outputDir} = buildConfig;
|
||||
|
||||
/** Path to the directory where all releases are created. */
|
||||
const releasesDir = join(outputDir, 'releases');
|
||||
|
||||
// Path to the sources of the Material package.
|
||||
const materialPath = join(packagesDir, 'lib');
|
||||
// Path to the release output of material.
|
||||
const releasePath = join(DIST_RELEASES, 'material');
|
||||
const releasePath = join(releasesDir, 'material');
|
||||
// The entry-point for the scss theming bundle.
|
||||
const themingEntryPointPath = join(COMPONENTS_DIR, 'core', 'theming', '_all-theme.scss');
|
||||
const themingEntryPointPath = join(materialPath, 'core', 'theming', '_all-theme.scss');
|
||||
// Output path for the scss theming bundle.
|
||||
const themingBundlePath = join(releasePath, '_theming.scss');
|
||||
// Matches all pre-built theme css files
|
||||
const prebuiltThemeGlob = join(DIST_MATERIAL, '**/theming/prebuilt/*.css?(.map)');
|
||||
const prebuiltThemeGlob = join(materialPath, '**/theming/prebuilt/*.css?(.map)');
|
||||
// Matches all SCSS files in the library.
|
||||
const allScssGlob = join(COMPONENTS_DIR, '**/*.scss');
|
||||
const allScssGlob = join(materialPath, '**/*.scss');
|
||||
|
||||
/**
|
||||
* Overwrite the release task for the material package. The material release will include special
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {task} from 'gulp';
|
||||
import {join} from 'path';
|
||||
import {statSync} from 'fs';
|
||||
import {DIST_ROOT} from '../build-config';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {isTravisMasterBuild} from '../util/travis-ci';
|
||||
import {openFirebaseDashboardApp} from '../util/firebase';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
const bundlesDir = join(DIST_ROOT, 'bundles');
|
||||
/** Path to the directory where all bundles are living. */
|
||||
const bundlesDir = join(buildConfig.outputDir, 'bundles');
|
||||
|
||||
/** Task which runs test against the size of material. */
|
||||
task('payload', ['material:clean-build'], () => {
|
||||
|
||||
@@ -3,17 +3,23 @@ import {existsSync, statSync} from 'fs-extra';
|
||||
import {join} from 'path';
|
||||
import {task} from 'gulp';
|
||||
import {execTask, sequenceTask} from '../util/task_helpers';
|
||||
import {DIST_RELEASES, RELEASE_PACKAGES} from '../build-config';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
import {yellow, green, red, grey} from 'chalk';
|
||||
import * as minimist from 'minimist';
|
||||
|
||||
/** Packages that will be published to NPM by the release task. */
|
||||
export const releasePackages = [
|
||||
'cdk',
|
||||
'material',
|
||||
];
|
||||
|
||||
/** Parse command-line arguments for release task. */
|
||||
const argv = minimist(process.argv.slice(3));
|
||||
|
||||
/** Task that builds all releases that will be published. */
|
||||
task(':publish:build-releases', sequenceTask(
|
||||
'clean',
|
||||
RELEASE_PACKAGES.map(packageName => `${packageName}:build-release`)
|
||||
releasePackages.map(packageName => `${packageName}:build-release`)
|
||||
));
|
||||
|
||||
/** Make sure we're logged in. */
|
||||
@@ -26,7 +32,7 @@ task(':publish:logout', execTask('npm', ['logout']));
|
||||
|
||||
|
||||
function _execNpmPublish(label: string, packageName: string): Promise<{}> {
|
||||
const packageDir = join(DIST_RELEASES, packageName);
|
||||
const packageDir = join(buildConfig.outputDir, 'releases', packageName);
|
||||
|
||||
if (!statSync(packageDir).isDirectory()) {
|
||||
return;
|
||||
@@ -83,12 +89,12 @@ task(':publish', async () => {
|
||||
}
|
||||
console.log('');
|
||||
|
||||
if (RELEASE_PACKAGES.length > 1) {
|
||||
if (releasePackages.length > 1) {
|
||||
console.warn(red('Warning: Multiple packages will be released if proceeding.'));
|
||||
}
|
||||
|
||||
// Iterate over every declared release package and publish it on NPM.
|
||||
for (const packageName of RELEASE_PACKAGES) {
|
||||
for (const packageName of releasePackages) {
|
||||
await _execNpmPublish(label, packageName);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {join} from 'path';
|
||||
import {task, watch} from 'gulp';
|
||||
import {PROJECT_ROOT, SOURCE_ROOT} from '../build-config';
|
||||
import {sequenceTask} from '../util/task_helpers';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
// There are no type definitions available for these imports.
|
||||
const runSequence = require('run-sequence');
|
||||
|
||||
const {packagesDir, projectDir} = buildConfig;
|
||||
|
||||
/** Builds everything that is necessary for karma. */
|
||||
task(':test:build', sequenceTask(
|
||||
'clean',
|
||||
@@ -22,7 +24,7 @@ task('test:single-run', [':test:build'], (done: () => void) => {
|
||||
let karma = require('karma');
|
||||
|
||||
new karma.Server({
|
||||
configFile: join(PROJECT_ROOT, 'test/karma.conf.js'),
|
||||
configFile: join(projectDir, 'test/karma.conf.js'),
|
||||
singleRun: true
|
||||
}, (exitCode: number) => {
|
||||
// Immediately exit the process if Karma reported errors, because due to
|
||||
@@ -43,13 +45,13 @@ task('test:single-run', [':test:build'], (done: () => void) => {
|
||||
* This task should be used when running unit tests locally.
|
||||
*/
|
||||
task('test', [':test:build'], () => {
|
||||
let patternRoot = join(SOURCE_ROOT, '**/*');
|
||||
let patternRoot = join(packagesDir, '**/*');
|
||||
// Load karma not outside. Karma pollutes Promise with a different implementation.
|
||||
let karma = require('karma');
|
||||
|
||||
// Configure the Karma server and override the autoWatch and singleRun just in case.
|
||||
let server = new karma.Server({
|
||||
configFile: join(PROJECT_ROOT, 'test/karma.conf.js'),
|
||||
configFile: join(projectDir, 'test/karma.conf.js'),
|
||||
autoWatch: false,
|
||||
singleRun: false
|
||||
});
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import {task} from 'gulp';
|
||||
import {DIST_RELEASES, DIST_ROOT, SOURCE_ROOT} from '../build-config';
|
||||
import {ngcBuildTask, tsBuildTask, copyTask, sequenceTask, execTask} from '../util/task_helpers';
|
||||
import {join} from 'path';
|
||||
import {copySync} from 'fs-extra';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
const appDir = join(SOURCE_ROOT, 'universal-app');
|
||||
const outDir = join(DIST_ROOT, 'packages', 'universal-app');
|
||||
const {outputDir, packagesDir} = buildConfig;
|
||||
|
||||
/** Path to the directory where all releases are created. */
|
||||
const releasesDir = join(outputDir, 'releases');
|
||||
|
||||
const appDir = join(packagesDir, 'universal-app');
|
||||
const outDir = join(outputDir, 'packages', 'universal-app');
|
||||
|
||||
// Paths to the different tsconfig files of the Universal app.
|
||||
// Building the sources in the output directory is part of the workaround for
|
||||
@@ -44,6 +49,6 @@ task('universal:build-prerender-ts', tsBuildTask(tsconfigPrerenderPath));
|
||||
// As a workaround for https://github.com/angular/angular/issues/12249, we need to
|
||||
// copy the Material and CDK ESM output inside of the universal-app output.
|
||||
task('universal:copy-release', () => {
|
||||
copySync(join(DIST_RELEASES, 'material'), join(outDir, 'material'));
|
||||
copySync(join(DIST_RELEASES, 'cdk'), join(outDir, 'cdk'));
|
||||
copySync(join(releasesDir, 'material'), join(outDir, 'material'));
|
||||
copySync(join(releasesDir, 'cdk'), join(outDir, 'cdk'));
|
||||
});
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import {task} from 'gulp';
|
||||
import {DIST_RELEASES, RELEASE_PACKAGES} from '../build-config';
|
||||
import {readFileSync} from 'fs';
|
||||
import {join} from 'path';
|
||||
import {green, red} from 'chalk';
|
||||
import {sequenceTask} from '../util/task_helpers';
|
||||
import {releasePackages} from './publish';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
/** Path to the directory where all releases are created. */
|
||||
const releasesDir = join(buildConfig.outputDir, 'releases');
|
||||
|
||||
/** RegExp that matches Angular component inline styles that contain a sourcemap reference. */
|
||||
const inlineStylesSourcemapRegex = /styles: ?\[["'].*sourceMappingURL=.*["']/;
|
||||
@@ -15,10 +19,10 @@ task('validate-release', sequenceTask(':publish:build-releases', 'validate-relea
|
||||
|
||||
/** Task that checks the release bundles for any common mistakes before releasing to the public. */
|
||||
task('validate-release:check-bundles', () => {
|
||||
const bundleFailures = RELEASE_PACKAGES
|
||||
.map(packageName => join(DIST_RELEASES, packageName, '@angular', `${packageName}.js`))
|
||||
const bundleFailures = releasePackages
|
||||
.map(packageName => join(releasesDir, packageName, '@angular', `${packageName}.js`))
|
||||
.map(packageBundle => checkPackageBundle(packageBundle))
|
||||
.map((failures, index) => ({failures, packageName: RELEASE_PACKAGES[index]}));
|
||||
.map((failures, index) => ({failures, packageName: releasePackages[index]}));
|
||||
|
||||
bundleFailures.forEach(({failures, packageName}) => {
|
||||
failures.forEach(failure => console.error(red(`Failure (${packageName}): ${failure}`)));
|
||||
|
||||
@@ -2,8 +2,8 @@ import * as child_process from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
import {PROJECT_ROOT} from '../build-config';
|
||||
import {yellow} from 'chalk';
|
||||
import {buildConfig} from '../packaging/build-config';
|
||||
|
||||
/* Those imports lack typings. */
|
||||
const gulpClean = require('gulp-clean');
|
||||
@@ -17,6 +17,8 @@ const gulpCleanCss = require('gulp-clean-css');
|
||||
const resolveBin = require('resolve-bin');
|
||||
const httpRewrite = require('http-rewrite-middleware');
|
||||
|
||||
const {projectDir} = buildConfig;
|
||||
|
||||
/** If the string passed in is a glob, returns it, otherwise append '**\/*' to it. */
|
||||
function _globify(maybeGlob: string, suffix = '**/*') {
|
||||
if (maybeGlob.indexOf('*') != -1) {
|
||||
@@ -157,11 +159,11 @@ export function buildAppTask(appName: string) {
|
||||
*/
|
||||
export function serverTask(packagePath: string, livereload = true) {
|
||||
// The http-rewrite-middlware only supports relative paths as rewrite destinations.
|
||||
let relativePath = path.relative(PROJECT_ROOT, packagePath);
|
||||
const relativePath = path.relative(projectDir, packagePath);
|
||||
|
||||
return () => {
|
||||
gulpConnect.server({
|
||||
root: PROJECT_ROOT,
|
||||
root: projectDir,
|
||||
livereload: livereload,
|
||||
port: 4200,
|
||||
fallback: path.join(packagePath, 'index.html'),
|
||||
|
||||
Reference in New Issue
Block a user