build: update packaging to match angular/angular (#3751)

* build: restructure release output

* build: inline metadata.json resources

* build: output re-export meatadata.json file in package root
This commit is contained in:
Jeremy Elbourn
2017-03-24 14:06:45 -07:00
committed by GitHub
parent a25e7bb09b
commit 71229756a5
38 changed files with 940 additions and 698 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ const path = require('path');
// Register TS compilation.
require('ts-node').register({
project: path.join(__dirname, 'tools/gulp')
project: path.join(__dirname, 'tools/gulp/tsconfig.json')
});
require('./tools/gulp/gulpfile');
+5 -4
View File
@@ -66,7 +66,6 @@
"glob": "^7.1.1",
"google-cloud": "^0.48.0",
"gulp": "^3.9.1",
"gulp-better-rollup": "^1.0.2",
"gulp-clean": "^0.3.2",
"gulp-clean-css": "^3.0.3",
"gulp-cli": "^1.2.2",
@@ -83,6 +82,7 @@
"gulp-transform": "^1.1.0",
"hammerjs": "^2.0.8",
"highlight.js": "^9.9.0",
"http-rewrite-middleware": "^0.1.6",
"image-diff": "^1.6.3",
"jasmine-core": "^2.5.2",
"karma": "^1.5.0",
@@ -99,16 +99,17 @@
"node-sass": "^4.5.0",
"protractor": "^5.1.1",
"resolve-bin": "^0.4.0",
"rollup": "^0.41.6",
"run-sequence": "^1.2.2",
"sass": "^0.5.0",
"selenium-webdriver": "^3.1.0",
"stylelint": "^7.8.0",
"travis-after-modes": "0.0.7",
"ts-node": "^2.1.0",
"ts-node": "^3.0.0",
"tslint": "^4.4.2",
"tslint-no-unused-var": "0.0.6",
"typescript": "~2.1.6",
"uglify-js": "^2.8.7",
"typescript": "~2.1.1",
"uglify-js": "^2.8.14",
"web-animations-js": "^2.2.2"
}
}
+6 -6
View File
@@ -8,7 +8,7 @@
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="@angular/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">
<link href="dist/packages/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">
<!-- FontAwesome for md-icon demo. -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
@@ -16,11 +16,11 @@
<body>
<demo-app>Loading...</demo-app>
<script src="vendor/core-js/client/core.js"></script>
<script src="vendor/web-animations-js/web-animations.min.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
<script src="vendor/hammerjs/hammer.min.js"></script>
<script src="node_modules/core-js/client/core.js"></script>
<script src="node_modules/web-animations-js/web-animations.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/hammerjs/hammer.min.js"></script>
<script>
System.import('system-config.js').then(function () {
+16 -13
View File
@@ -3,25 +3,28 @@ declare const System: any;
// Apply the CLI SystemJS configuration.
System.config({
paths: {
'node:*': 'node_modules/*',
},
map: {
'rxjs': 'vendor/rxjs',
'rxjs': 'node:rxjs',
'main': 'main.js',
// Angular specific mappings.
'@angular/core': 'vendor/@angular/core/bundles/core.umd.js',
'@angular/common': 'vendor/@angular/common/bundles/common.umd.js',
'@angular/compiler': 'vendor/@angular/compiler/bundles/compiler.umd.js',
'@angular/http': 'vendor/@angular/http/bundles/http.umd.js',
'@angular/forms': 'vendor/@angular/forms/bundles/forms.umd.js',
'@angular/router': 'vendor/@angular/router/bundles/router.umd.js',
'@angular/animations': 'vendor/@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'vendor/@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser': 'vendor/@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/core': 'node:@angular/core/bundles/core.umd.js',
'@angular/common': 'node:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'node:@angular/compiler/bundles/compiler.umd.js',
'@angular/http': 'node:@angular/http/bundles/http.umd.js',
'@angular/forms': 'node:@angular/forms/bundles/forms.umd.js',
'@angular/router': 'node:@angular/router/bundles/router.umd.js',
'@angular/animations': 'node:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'node:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser': 'node:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/animations':
'vendor/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'node:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/platform-browser-dynamic':
'vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/material': '@angular/material/bundles/material.umd.js'
'node:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/material': 'dist/bundles/material.umd.js'
},
packages: {
// Thirdparty barrels.
+3 -16
View File
@@ -1,22 +1,10 @@
/* Config file for the Angular Compiler. Paths need to be relative to the dist folder. */
{
"extends": "./tsconfig",
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "es2015", "dom"],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"target": "es5",
"baseUrl": "",
"typeRoots": [
"../node_modules/@types/!(node)"
],
"paths": {
"@angular/material": [
"./@angular/material"
]
"@angular/material": ["./material"]
}
},
"files": [
@@ -25,7 +13,6 @@
"./main-aot.ts"
],
"angularCompilerOptions": {
"skipTemplateCodegen": false,
"debug": true
"skipTemplateCodegen": false
}
}
+3 -8
View File
@@ -8,7 +8,7 @@
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "../../dist/",
"outDir": "../../dist/packages/demo-app",
"sourceMap": true,
"target": "es5",
"stripInternal": false,
@@ -18,7 +18,7 @@
],
"paths": {
"@angular/material": [
"../../dist/@angular/material"
"../../dist/packages/material"
]
}
},
@@ -27,10 +27,5 @@
"./demo-app-module.ts",
"./system-config.ts",
"./main.ts"
],
"angularCompilerOptions": {
"genDir": "../../dist",
"skipTemplateCodegen": true,
"debug": true
}
]
}
+6 -6
View File
@@ -8,7 +8,7 @@
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="@angular/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">
<link href="dist/packages/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">
<!-- FontAwesome for md-icon demo. -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
@@ -16,11 +16,11 @@
<body>
<e2e-app>Loading...</e2e-app>
<script src="vendor/core-js/client/core.js"></script>
<script src="vendor/web-animations-js/web-animations.min.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
<script src="vendor/hammerjs/hammer.min.js"></script>
<script src="node_modules/core-js/client/core.js"></script>
<script src="node_modules/web-animations-js/web-animations.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/hammerjs/hammer.min.js"></script>
<script>
System.import('system-config.js').then(function () {
+16 -15
View File
@@ -3,27 +3,28 @@ declare const System: any;
// Apply the CLI SystemJS configuration.
System.config({
paths: {
'node:*': 'node_modules/*',
},
map: {
'rxjs': 'vendor/rxjs',
'rxjs': 'node:rxjs',
'main': 'main.js',
// Angular specific mappings.
'@angular/core': 'vendor/@angular/core/bundles/core.umd.js',
'@angular/common': 'vendor/@angular/common/bundles/common.umd.js',
'@angular/compiler': 'vendor/@angular/compiler/bundles/compiler.umd.js',
'@angular/http': 'vendor/@angular/http/bundles/http.umd.js',
'@angular/forms': 'vendor/@angular/forms/bundles/forms.umd.js',
'@angular/router': 'vendor/@angular/router/bundles/router.umd.js',
'@angular/animations': 'vendor/@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'vendor/@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'node:@angular/core/bundles/core.umd.js',
'@angular/common': 'node:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'node:@angular/compiler/bundles/compiler.umd.js',
'@angular/http': 'node:@angular/http/bundles/http.umd.js',
'@angular/forms': 'node:@angular/forms/bundles/forms.umd.js',
'@angular/router': 'node:@angular/router/bundles/router.umd.js',
'@angular/animations': 'node:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'node:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser': 'node:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/animations':
'vendor/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/platform-browser': 'vendor/@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/testing':
'vendor/@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'node:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/platform-browser-dynamic':
'vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/material': '@angular/material/bundles/material.umd.js'
'node:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/material': 'dist/bundles/material.umd.js'
},
packages: {
// Thirdparty barrels.
+2 -2
View File
@@ -8,7 +8,7 @@
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "../../dist/",
"outDir": "../../dist/packages/e2e-app",
"sourceMap": true,
"target": "es5",
"stripInternal": false,
@@ -18,7 +18,7 @@
],
"paths": {
"@angular/material": [
"../../dist/@angular/material"
"../../dist/packages/material"
]
}
},
+6
View File
@@ -0,0 +1,6 @@
Angular Material
=======
The sources for this package are in the main [Angular Material](https://github.com/angular/material2) repo. Please file issues and pull requests against that repo.
License: MIT
-3
View File
@@ -29,7 +29,4 @@ export class MdMenuModule {
export * from './menu';
export {MdMenuTrigger} from './menu-trigger';
export {fadeInItems, transformMenu} from './menu-animations';
export {MdMenu} from './menu-directive';
export {MdMenuItem} from './menu-item';
+3 -2
View File
@@ -3,8 +3,9 @@
"version": "2.0.0-beta.2",
"description": "Angular Material",
"main": "./bundles/material.umd.js",
"module": "./index.js",
"typings": "./index.d.ts",
"module": "./@angular/material.es5.js",
"es2015": "./@angular/material.js",
"typings": "./material.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/angular/material2.git"
-4
View File
@@ -36,7 +36,3 @@ class MdProgressSpinnerModule {
export {MdProgressSpinnerModule};
export * from './progress-spinner';
/** @deprecated */
export {MdProgressSpinnerModule as MdProgressCircleModule};
export {MdProgressSpinner as MdProgressCircle};
@@ -1,3 +1,9 @@
/**
* @module
* @description
* Entry point for all public APIs of Angular Material.
*/
export * from './core';
export * from './module';
+22 -22
View File
@@ -3,40 +3,40 @@ declare const System: any;
// Apply the CLI SystemJS configuration.
System.config({
paths: {
'node:*': 'node_modules/*'
},
map: {
'rxjs': 'vendor/rxjs',
'rxjs': 'node:rxjs',
'main': 'main.js',
// Angular specific mappings.
'@angular/core': 'vendor/@angular/core/bundles/core.umd.js',
'@angular/core/testing': 'vendor/@angular/core/bundles/core-testing.umd.js',
'@angular/common': 'vendor/@angular/common/bundles/common.umd.js',
'@angular/common/testing': 'vendor/@angular/common/bundles/common-testing.umd.js',
'@angular/compiler': 'vendor/@angular/compiler/bundles/compiler.umd.js',
'@angular/compiler/testing': 'vendor/@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/http': 'vendor/@angular/http/bundles/http.umd.js',
'@angular/http/testing': 'vendor/@angular/http/bundles/http-testing.umd.js',
'@angular/forms': 'vendor/@angular/forms/bundles/forms.umd.js',
'@angular/forms/testing': 'vendor/@angular/forms/bundles/forms-testing.umd.js',
'@angular/animations': 'vendor/@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'vendor/@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'node:@angular/core/bundles/core.umd.js',
'@angular/core/testing': 'node:@angular/core/bundles/core-testing.umd.js',
'@angular/common': 'node:@angular/common/bundles/common.umd.js',
'@angular/common/testing': 'node:@angular/common/bundles/common-testing.umd.js',
'@angular/compiler': 'node:@angular/compiler/bundles/compiler.umd.js',
'@angular/compiler/testing': 'node:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/http': 'node:@angular/http/bundles/http.umd.js',
'@angular/http/testing': 'node:@angular/http/bundles/http-testing.umd.js',
'@angular/forms': 'node:@angular/forms/bundles/forms.umd.js',
'@angular/forms/testing': 'node:@angular/forms/bundles/forms-testing.umd.js',
'@angular/animations': 'node:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'node:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser/animations':
'vendor/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/platform-browser': 'vendor/@angular/platform-browser/bundles/platform-browser.umd.js',
'node:@angular/platform-browser/bundles/platform-browser-animations.umd',
'@angular/platform-browser':
'node:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/testing':
'vendor/@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'node:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic':
'vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'node:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/platform-browser-dynamic/testing':
'vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
'node:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js'
},
packages: {
// Thirdparty barrels.
'rxjs': { main: 'index' },
'@angular/material': {
format: 'cjs',
main: 'material.umd.js'
},
// Set the default extension for the root package, because otherwise the demo-app can't
// be built within the production mode. Due to missing file extensions.
'.': {
+13
View File
@@ -0,0 +1,13 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"types": ["jasmine"],
"experimentalDecorators": true
},
"include": [
"system-config-spec.ts",
"**/*.spec.ts"
]
}
+17 -18
View File
@@ -1,31 +1,30 @@
{
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"emitDecoratorMetadata": true,
"stripInternal": false,
"experimentalDecorators": true,
"lib": ["es6", "es2015", "dom"],
"module": "es2015",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "../../dist/@angular/material",
"outDir": "../../dist/packages/material",
"paths": {},
"rootDir": ".",
"sourceMap": true,
"target": "es6",
"inlineSources": true,
"stripInternal": false,
"baseUrl": "",
"typeRoots": [
"../../node_modules/@types/!(node)"
],
"types": [
"jasmine",
"rx/rx.all"
]
"target": "es2015",
"lib": ["es2015", "dom"],
"skipLibCheck": true,
"types": []
},
"files": [
"public_api.ts",
"typings.d.ts"
],
"angularCompilerOptions": {
"genDir": "../../dist",
"skipTemplateCodegen": true,
"debug": true
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"flatModuleOutFile": "index.js",
"flatModuleId": "@angular/material",
"skipTemplateCodegen": true
}
}
+1 -1
View File
@@ -17,4 +17,4 @@
"suppressExcessPropertyErrors": "true",
"suppressImplicitAnyIndexErrors": "true",
"module": "commonjs"
}
}
+4 -4
View File
@@ -4,12 +4,12 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
__karma__.loaded = function () {};
var baseDir = '/base/dist/';
var configFile = baseDir + '@angular/material/system-config-spec.js';
var baseDir = '/base';
var configFile = baseDir + '/dist/packages/material/system-config-spec.js';
var specFiles = Object.keys(window.__karma__.files).filter(isMaterialSpecFile);
// Configure the base path for dist/
System.config({baseURL: baseDir});
System.config({ baseURL: baseDir });
// Load the spec SystemJS configuration file.
System.import(configFile)
@@ -28,7 +28,7 @@ function runMaterialSpecs() {
/** Whether the specified file is part of Angular Material. */
function isMaterialSpecFile(path) {
return path.slice(-8) === '.spec.js' && path.indexOf('vendor') === -1;
return path.slice(-8) === '.spec.js' && path.indexOf('node_modules') === -1;
}
/** Configures Angular's TestBed. */
+18 -25
View File
@@ -16,43 +16,36 @@ module.exports = (config) => {
require('karma-coverage')
],
files: [
{pattern: 'dist/vendor/core-js/client/core.js', included: true, watched: false},
{pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false},
{pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/proxy.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/sync-test.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/jasmine-patch.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false},
{pattern: 'dist/vendor/zone.js/dist/fake-async-test.js', included: true, watched: false},
{pattern: 'dist/vendor/hammerjs/hammer.min.js', included: true, watched: false},
{pattern: 'node_modules/core-js/client/core.js', included: true, watched: false},
{pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/zone.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/proxy.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/sync-test.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/jasmine-patch.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/async-test.js', included: true, watched: false},
{pattern: 'node_modules/zone.js/dist/fake-async-test.js', included: true, watched: false},
{pattern: 'node_modules/hammerjs/hammer.min.js', included: true, watched: false},
// Include all Angular dependencies
{pattern: 'node_modules/@angular/**/*', included: false, watched: false},
{pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
{pattern: 'test/karma-test-shim.js', included: true, watched: false},
// paths loaded via module imports
{pattern: 'dist/**/*.js', included: false, watched: true},
// Include a Material theme in the test suite.
{pattern: 'dist/**/core/theming/prebuilt/indigo-pink.css', included: true, watched: true},
// include one of the themes
{pattern: 'dist/**/prebuilt/indigo-pink.css', included: true, watched: true},
// paths loaded via Angular's component compiler
// (these paths need to be rewritten, see proxies section)
{pattern: 'dist/**/*.html', included: false, watched: true},
{pattern: 'dist/**/*.css', included: false, watched: true},
{pattern: 'dist/packages/material/**/*', included: false, watched: true},
// paths to support debugging with source maps in dev tools
{pattern: 'dist/**/*.ts', included: false, watched: false},
{pattern: 'dist/**/*.js.map', included: false, watched: false}
],
proxies: {
// required for component assets fetched by Angular's compiler
'/components/': '/base/dist/components/',
'/core/': '/base/dist/core/',
},
customLaunchers: customLaunchers,
preprocessors: {
'dist/@angular/material/**/*.js': ['sourcemap']
'dist/**/*.js': ['sourcemap']
},
reporters: ['dots'],
+13 -1
View File
@@ -5,8 +5,20 @@ 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');
export const DIST_COMPONENTS_ROOT = join(DIST_ROOT, '@angular/material');
/** 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');
/** Output subdirectory where the npm package will be staged for publish */
export const DIST_RELEASE = join(DIST_ROOT, 'release');
export const DIST_DEMOAPP = join(DIST_ROOT, 'packages', 'demo-app');
export const DIST_E2EAPP = join(DIST_ROOT, 'packages', 'e2e-app');
export const COVERAGE_RESULT_FILE = join(DIST_ROOT, 'coverage', 'coverage-summary.json');
+1 -3
View File
@@ -1,6 +1,5 @@
import './tasks/ci';
import './tasks/clean';
import './tasks/components';
import './tasks/default';
import './tasks/development';
import './tasks/docs';
@@ -8,9 +7,8 @@ import './tasks/e2e';
import './tasks/lint';
import './tasks/release';
import './tasks/screenshots';
import './tasks/serve';
import './tasks/unit-test';
import './tasks/docs';
import './tasks/aot';
import './tasks/payload';
import './tasks/coverage';
import './tasks/library';
+17 -16
View File
@@ -1,21 +1,22 @@
import {task} from 'gulp';
import {copySync} from 'fs-extra';
import {DIST_DEMOAPP, DIST_RELEASE} from '../constants';
import {sequenceTask, execNodeTask} from '../util/task_helpers';
import {join} from 'path';
import {DIST_ROOT} from '../constants';
import {execNodeTask, sequenceTask} from '../util/task_helpers';
/** Copies the source files of the demo-app to the dist folder. */
task('aot:copy', [':build:devapp:scss', ':build:devapp:assets']);
const tsconfigFile = join(DIST_DEMOAPP, 'tsconfig-aot.json');
/**
* Prepares the AOT compilation by copying the demo-app and building the components with their
* associated metadata files from the Angular compiler.
*/
task('aot:prepare', sequenceTask(
'clean',
['aot:copy', 'build:components', ':build:components:ngc'])
);
/** Builds the demo-app and library. To be able to run NGC, apply the metadata workaround. */
task('aot:deps', sequenceTask('build:devapp', ':package:release', 'aot:copy-release'));
/** Builds the demo-app with the Angular compiler to verify that all components work. */
task('aot:build', ['aot:prepare'], execNodeTask(
'@angular/compiler-cli', 'ngc', ['-p', join(DIST_ROOT, 'tsconfig-aot.json')])
);
// As a workaround for https://github.com/angular/angular/issues/12249, we need to
// copy the Material ESM output inside of the demo-app output.
task('aot:copy-release', () => copySync(DIST_RELEASE, join(DIST_DEMOAPP, 'material')));
/** Build the demo-app and a release to confirm that the library is AOT-compatible. */
task('aot:build', sequenceTask('aot:deps', 'aot:compiler-cli'));
/** Build the demo-app and a release to confirm that the library is AOT-compatible. */
task('aot:compiler-cli', execNodeTask(
'@angular/compiler-cli', 'ngc', ['-p', tsconfigFile]
));
+1
View File
@@ -3,4 +3,5 @@ import {DIST_ROOT} from '../constants';
import {cleanTask} from '../util/task_helpers';
/** Deletes the dist/ directory. */
task('clean', cleanTask(DIST_ROOT));
-154
View File
@@ -1,154 +0,0 @@
import {task, watch, src, dest} from 'gulp';
import {ScriptTarget, ModuleKind} from 'typescript';
import * as path from 'path';
import {
DIST_COMPONENTS_ROOT, PROJECT_ROOT, COMPONENTS_DIR, HTML_MINIFIER_OPTIONS, LICENSE_BANNER
} from '../constants';
import {
sassBuildTask, tsBuildTask, execNodeTask, sequenceTask,
triggerLivereload
} from '../util/task_helpers';
// There are no type definitions available for these imports.
const inlineResources = require('../../../scripts/release/inline-resources');
const gulpRollup = require('gulp-better-rollup');
const gulpMinifyHtml = require('gulp-htmlmin');
const gulpIf = require('gulp-if');
/** Path to tsconfig file for the components. */
const tsconfigPath = path.join(COMPONENTS_DIR, 'tsconfig.json');
/** Asset files to be added to the components output. */
const assetFiles = [
path.join(COMPONENTS_DIR, '**/*.html'),
path.join(COMPONENTS_DIR, '**/*.scss'),
path.join(COMPONENTS_DIR, 'package.json'),
path.join(PROJECT_ROOT, 'README.md'),
path.join(PROJECT_ROOT, 'LICENSE'),
];
/** Builds components to UMD bundle. */
task('build:components', [':build:components:bundle:umd']);
/** Builds components for Angular Material releases */
task(':build:components:release', sequenceTask(
':build:components:bundle:umd',
':build:components:bundle:esm',
':build:components:ngc'
));
/** Builds components typescript in ES5, ES6 target. For specs Karma needs CJS output. */
task(':build:components:ts:es5', tsBuildTask(tsconfigPath, { target: ScriptTarget.ES5 }));
task(':build:components:ts:es6', tsBuildTask(tsconfigPath, { target: ScriptTarget.ES2015 }));
task(':build:components:ts:spec', tsBuildTask(tsconfigPath, {
target: ScriptTarget.ES5, module: ModuleKind.CommonJS
}));
/** Tasks to create a UMD or ES bundle */
task(':build:components:bundle:umd', sequenceTask(
':build:components:ts:es5', ':build:components:inline', ':build:components:rollup:umd'
));
task(':build:components:bundle:esm', sequenceTask(
':build:components:ts:es6', ':build:components:inline', ':build:components:rollup:esm'
));
/** Copies all component assets to the build output. */
task(':build:components:assets', () => {
return src(assetFiles)
.pipe(gulpIf(/.html$/, gulpMinifyHtml(HTML_MINIFIER_OPTIONS)))
.pipe(dest(DIST_COMPONENTS_ROOT));
});
/** Compiles the components SCSS into minified CSS. */
task(':build:components:scss', sassBuildTask(DIST_COMPONENTS_ROOT, COMPONENTS_DIR, true));
/** Builds a ES6 bundle for all components. */
task(':build:components:rollup:esm', () => {
return src(path.join(DIST_COMPONENTS_ROOT, 'index.js'))
.pipe(createRollupBundle('es', 'material.js'))
.pipe(dest(path.join(DIST_COMPONENTS_ROOT, 'bundles')));
});
/** Builds a UMD bundle (ES5) for all components. */
task(':build:components:rollup:umd', () => {
return src(path.join(DIST_COMPONENTS_ROOT, 'index.js'))
.pipe(createRollupBundle('umd', 'material.umd.js'))
.pipe(dest(path.join(DIST_COMPONENTS_ROOT, 'bundles')));
});
/** Builds components with resources (html, css) inlined into the built JS. */
task(':build:components:inline', sequenceTask(
[':build:components:scss', ':build:components:assets'],
':inline-resources',
));
/** Inlines resources (html, css) into the JS output. */
task(':inline-resources', () => inlineResources(DIST_COMPONENTS_ROOT));
/** Generates metadata.json files for all of the components. */
task(':build:components:ngc', ['build:components'], execNodeTask(
'@angular/compiler-cli', 'ngc', ['-p', tsconfigPath]
));
/** [Watch task] Rebuilds (ESM output) whenever ts, scss, or html sources change. */
task(':watch:components', () => {
watch(path.join(COMPONENTS_DIR, '**/*.ts'), ['build:components', triggerLivereload]);
watch(path.join(COMPONENTS_DIR, '**/*.scss'), ['build:components', triggerLivereload]);
watch(path.join(COMPONENTS_DIR, '**/*.html'), ['build:components', triggerLivereload]);
});
const ROLLUP_GLOBALS = {
// Angular dependencies
'@angular/core': 'ng.core',
'@angular/common': 'ng.common',
'@angular/forms': 'ng.forms',
'@angular/http': 'ng.http',
'@angular/animations': 'ng.animations',
'@angular/animations/browser': 'ng.animations.browser',
'@angular/platform-browser': 'ng.platformBrowser',
'@angular/platform-browser/animations': 'ng.platformBrowser.animations',
'@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic',
// Rxjs dependencies
'rxjs/Subject': 'Rx',
'rxjs/add/observable/fromEvent': 'Rx.Observable',
'rxjs/add/observable/forkJoin': 'Rx.Observable',
'rxjs/add/observable/of': 'Rx.Observable',
'rxjs/add/observable/merge': 'Rx.Observable',
'rxjs/add/observable/throw': 'Rx.Observable',
'rxjs/add/operator/auditTime': 'Rx.Observable.prototype',
'rxjs/add/operator/toPromise': 'Rx.Observable.prototype',
'rxjs/add/operator/map': 'Rx.Observable.prototype',
'rxjs/add/operator/filter': 'Rx.Observable.prototype',
'rxjs/add/operator/do': 'Rx.Observable.prototype',
'rxjs/add/operator/share': 'Rx.Observable.prototype',
'rxjs/add/operator/finally': 'Rx.Observable.prototype',
'rxjs/add/operator/catch': 'Rx.Observable.prototype',
'rxjs/add/operator/first': 'Rx.Observable.prototype',
'rxjs/add/operator/startWith': 'Rx.Observable.prototype',
'rxjs/add/operator/switchMap': 'Rx.Observable.prototype',
'rxjs/Observable': 'Rx'
};
/** Creates a rollup bundles of the Material components.*/
function createRollupBundle(format: string, outFile: string) {
let rollupOptions = {
context: 'this',
external: Object.keys(ROLLUP_GLOBALS)
};
let rollupGenerateOptions = {
// Keep the moduleId empty because we don't want to force developers to a specific moduleId.
moduleId: '',
moduleName: 'ng.material',
banner: LICENSE_BANNER,
format: format,
dest: outFile,
globals: ROLLUP_GLOBALS,
};
return gulpRollup(rollupOptions, rollupGenerateOptions);
}
+11 -14
View File
@@ -1,33 +1,30 @@
import {task, watch} from 'gulp';
import * as path from 'path';
import {DIST_ROOT, SOURCE_ROOT} from '../constants';
import {
sassBuildTask, tsBuildTask, copyTask, buildAppTask, vendorTask,
serverTask, sequenceTask, triggerLivereload
sassBuildTask, tsBuildTask, copyTask, buildAppTask, sequenceTask, triggerLivereload,
serverTask
} from '../util/task_helpers';
import {join} from 'path';
const appDir = path.join(SOURCE_ROOT, 'demo-app');
const outDir = DIST_ROOT;
const appDir = join(SOURCE_ROOT, 'demo-app');
const outDir = join(DIST_ROOT, 'packages', 'demo-app');
task(':watch:devapp', () => {
watch(path.join(appDir, '**/*.ts'), [':build:devapp:ts', triggerLivereload]);
watch(path.join(appDir, '**/*.scss'), [':build:devapp:scss', triggerLivereload]);
watch(path.join(appDir, '**/*.html'), [':build:devapp:assets', triggerLivereload]);
watch(join(appDir, '**/*.ts'), [':build:devapp:ts', triggerLivereload]);
watch(join(appDir, '**/*.scss'), [':build:devapp:scss', triggerLivereload]);
watch(join(appDir, '**/*.html'), [':build:devapp:assets', triggerLivereload]);
});
/** Path to the demo-app tsconfig file. */
const tsconfigPath = path.join(appDir, 'tsconfig.json');
const tsconfigPath = join(appDir, 'tsconfig.json');
task(':build:devapp:vendor', vendorTask());
task(':build:devapp:ts', tsBuildTask(tsconfigPath));
task(':build:devapp:scss', sassBuildTask(outDir, appDir));
task(':build:devapp:assets', copyTask(appDir, outDir));
task('build:devapp', buildAppTask('devapp'));
task(':serve:devapp', serverTask(true));
task(':serve:devapp', serverTask(outDir, true));
task('serve:devapp', ['build:devapp'], sequenceTask(
[':serve:devapp', ':watch:components', ':watch:devapp']
[':serve:devapp', 'library:watch', ':watch:devapp']
));
+12 -20
View File
@@ -1,19 +1,18 @@
import {task, watch} from 'gulp';
import * as path from 'path';
import {SOURCE_ROOT, DIST_ROOT, PROJECT_ROOT} from '../constants';
import {SOURCE_ROOT, DIST_E2EAPP, PROJECT_ROOT} from '../constants';
import {
tsBuildTask, copyTask, buildAppTask, execNodeTask,
vendorTask, sequenceTask, serverTask
tsBuildTask, copyTask, buildAppTask, execNodeTask, sequenceTask, serverTask
} from '../util/task_helpers';
const gulpRunSequence = require('run-sequence');
// There are no type definitions available for these imports.
const gulpConnect = require('gulp-connect');
const appDir = path.join(SOURCE_ROOT, 'e2e-app');
const outDir = DIST_ROOT;
const PROTRACTOR_CONFIG_PATH = path.join(PROJECT_ROOT, 'test/protractor.conf.js');
const outDir = DIST_E2EAPP;
const PROTRACTOR_CONFIG_PATH = path.join(PROJECT_ROOT, 'test/protractor.conf.js');
const tsconfigPath = path.join(appDir, 'tsconfig.json');
task(':watch:e2eapp', () => {
@@ -21,9 +20,6 @@ task(':watch:e2eapp', () => {
watch(path.join(appDir, '**/*.html'), [':build:e2eapp:assets']);
});
/** Copies e2e app dependencies to build output. */
task(':build:e2eapp:vendor', vendorTask());
/** Builds e2e app ts to js. */
task(':build:e2eapp:ts', tsBuildTask(tsconfigPath));
@@ -40,7 +36,7 @@ task(':test:protractor:setup', execNodeTask('protractor', 'webdriver-manager', [
task(':test:protractor', execNodeTask('protractor', [PROTRACTOR_CONFIG_PATH]));
/** Starts up the e2e app server. */
task(':serve:e2eapp', serverTask(false));
task(':serve:e2eapp', serverTask(outDir, false));
/** Terminates the e2e app server */
task(':serve:e2eapp:stop', gulpConnect.serverClose);
@@ -52,17 +48,13 @@ task('serve:e2eapp', sequenceTask('build:e2eapp', ':serve:e2eapp'));
* [Watch task] Builds and serves e2e app, rebuilding whenever the sources change.
* This should only be used when running e2e tests locally.
*/
task('serve:e2eapp:watch', ['serve:e2eapp', ':watch:components', ':watch:e2eapp']);
task('serve:e2eapp:watch', ['serve:e2eapp', 'library:watch', ':watch:e2eapp']);
/**
* Builds and serves the e2e-app and runs protractor once the e2e-app is ready.
*/
task('e2e', (done: (err?: string) => void) => {
gulpRunSequence(
':test:protractor:setup',
'serve:e2eapp',
':test:protractor',
':serve:e2eapp:stop',
(err: any) => done(err)
);
});
task('e2e', sequenceTask(
[':test:protractor:setup', 'serve:e2eapp'],
':test:protractor',
':serve:e2eapp:stop',
));
+93
View File
@@ -0,0 +1,93 @@
import {task, watch} from 'gulp';
import {join} from 'path';
import {main as tsc} from '@angular/tsc-wrapped';
import {SOURCE_ROOT, DIST_BUNDLES, DIST_MATERIAL} from '../constants';
import {sequenceTask, sassBuildTask, copyTask, triggerLivereload} from '../util/task_helpers';
import {createRollupBundle} from '../util/rollup-helper';
import {transpileFile} from '../util/ts-compiler';
import {ScriptTarget, ModuleKind} from 'typescript';
import {writeFileSync} from 'fs';
// There are no type definitions available for these imports.
const inlineResources = require('../../../scripts/release/inline-resources');
const uglify = require('uglify-js');
const libraryRoot = join(SOURCE_ROOT, 'lib');
const tsconfigPath = join(libraryRoot, 'tsconfig.json');
// Paths to the different output directories.
const materialDir = DIST_MATERIAL;
const bundlesDir = DIST_BUNDLES;
const esmMainFile = join(materialDir, 'index.js');
task('library:build', sequenceTask(
'clean',
['library:build:esm', 'library:assets'],
// Inline assets into ESM output.
'library:assets:inline',
// Build bundles on top of inlined ESM output.
'library:build:bundles',
));
/** [Watch task] Rebuilds the library whenever TS, SCSS, or HTML files change. */
task('library:watch', () => {
watch(join(libraryRoot, '**/*.ts'), ['library:build', triggerLivereload]);
watch(join(libraryRoot, '**/*.scss'), ['library:build', triggerLivereload]);
watch(join(libraryRoot, '**/*.html'), ['library:build', triggerLivereload]);
});
/**
* TypeScript compilation tasks. Tasks are creating ESM, FESM, UMD bundles for releases.
**/
task('library:build:esm', () => tsc(tsconfigPath, {basePath: libraryRoot}));
task('library:build:bundles', () => buildModuleEntry(esmMainFile));
/** Builds a module entry-point. If no entry name is specified it builds the whole library. */
async function buildModuleEntry(entryFile: string, entryName = '') {
let baseFileName = entryName ? `material-${entryName}` : 'material';
let moduleName = entryName ? `ng.material.${entryName}` : 'ng.material';
// List of paths for the specified entrypoint.
let fesm2015File = join(bundlesDir, `${baseFileName}.js`);
let fesm2014File = join(bundlesDir, `${baseFileName}.es5.js`);
let umdFile = join(bundlesDir, `${baseFileName}.umd.js`);
let umdMinFile = join(bundlesDir, `${baseFileName}.umd.min.js`);
// Build FESM-2015 bundle file.
await createRollupBundle({
moduleName: moduleName,
entry: entryFile,
dest: fesm2015File,
format: 'es',
});
// Downlevel FESM-2015 file to ES5.
transpileFile(fesm2015File, fesm2014File, {
target: ScriptTarget.ES5,
module: ModuleKind.ES2015,
allowJs: true
});
// Create UMD bundle of FESM-2014 output.
await createRollupBundle({
moduleName: moduleName,
entry: fesm2014File,
dest: umdFile,
format: 'umd'
});
// Output a minified version of the UMD bundle
writeFileSync(umdMinFile, uglify.minify(umdFile, { preserveComments: 'license' }).code);
}
/**
* Asset tasks. Building SaSS files and inlining CSS, HTML files into the ESM output.
**/
task('library:assets', ['library:assets:scss', 'library:assets:html']);
task('library:assets:scss', sassBuildTask(materialDir, libraryRoot, true));
task('library:assets:html', copyTask(join(libraryRoot, '**/*.+(html|scss)'), materialDir));
task('library:assets:inline', () => inlineResources(materialDir));
+2 -1
View File
@@ -1,10 +1,11 @@
import gulp = require('gulp');
import {execNodeTask} from '../util/task_helpers';
import {DIST_MATERIAL} from '../constants';
gulp.task('lint', ['tslint', 'stylelint', 'madge']);
/** Task that runs madge to detect circular dependencies. */
gulp.task('madge', ['build:release'], execNodeTask('madge', ['--circular', './dist']));
gulp.task('madge', ['library:build'], execNodeTask('madge', ['--circular', DIST_MATERIAL]));
/** Task to lint Angular Material's scss stylesheets. */
gulp.task('stylelint', execNodeTask(
+13 -20
View File
@@ -1,22 +1,21 @@
import {task} from 'gulp';
import {join} from 'path';
import {statSync, readFileSync} from 'fs';
import {DIST_COMPONENTS_ROOT} from '../constants';
import {statSync} from 'fs';
import {DIST_ROOT} from '../constants';
import {spawnSync} from 'child_process';
import {isTravisPushBuild} from '../util/travis-ci';
import {openFirebaseDashboardDatabase} from '../util/firebase';
// There are no type definitions available for these imports.
const uglifyJs = require('uglify-js');
const BUNDLE_PATH = join(DIST_COMPONENTS_ROOT, 'bundles', 'material.umd.js');
const bundlesDir = join(DIST_ROOT, 'bundles');
/** Task which runs test against the size of whole library. */
task('payload', ['build:release'], () => {
task('payload', ['library:build'], () => {
let results = {
umd_kb: getFilesize(BUNDLE_PATH),
umd_minified_uglify_kb: getUglifiedSize(BUNDLE_PATH),
umd_kb: getBundleSize('material.umd.js'),
umd_minified_uglify_kb: getBundleSize('material.umd.min.js'),
fesm_2015: getBundleSize('material.js'),
fesm_2014: getBundleSize('material.es5.js'),
timestamp: Date.now()
};
@@ -30,22 +29,16 @@ task('payload', ['build:release'], () => {
});
/** Returns the size of the given library bundle. */
function getBundleSize(bundleName: string) {
return getFilesize(join(bundlesDir, bundleName));
}
/** Returns the size of a file in kilobytes. */
function getFilesize(filePath: string) {
return statSync(filePath).size / 1000;
}
/** Returns the size of a uglify minified file in kilobytes */
function getUglifiedSize(filePath: string) {
let fileContent = readFileSync(filePath, 'utf-8');
let compressedFile = uglifyJs.minify(fileContent, {
fromString: true
});
return Buffer.byteLength(compressedFile.code, 'utf8') / 1000;
}
/** Publishes the given results to the firebase database. */
function publishResults(results: any) {
let latestSha = spawnSync('git', ['rev-parse', 'HEAD']).stdout.toString().trim();
+124 -29
View File
@@ -1,30 +1,84 @@
import {spawn} from 'child_process';
import {existsSync, statSync} from 'fs';
import {task} from 'gulp';
import gulpRunSequence = require('run-sequence');
import path = require('path');
import minimist = require('minimist');
import {existsSync, statSync, writeFileSync, readFileSync} from 'fs-extra';
import {join, basename} from 'path';
import {task, src, dest} from 'gulp';
import {execTask, sequenceTask} from '../util/task_helpers';
import {
DIST_RELEASE, DIST_BUNDLES, DIST_MATERIAL, COMPONENTS_DIR, LICENSE_BANNER, DIST_ROOT
} from '../constants';
import * as minimist from 'minimist';
import {execTask, cleanTask} from '../util/task_helpers';
import {DIST_COMPONENTS_ROOT} from '../constants';
// There are no type definitions available for these imports.
const glob = require('glob');
/** Parse command-line arguments for release task. */
const argv = minimist(process.argv.slice(3));
/** Removes redundant spec files from the release. TypeScript creates definition files for specs. */
// TODO(devversion): tsconfig files should share code and don't generate spec files for releases.
task(':build:release:clean-spec', cleanTask('dist/**/*+(-|.)spec.*'));
// Matches all Typescript definition files for Material.
const typingsGlob = join(DIST_MATERIAL, '**/*.+(d.ts|metadata.json)');
// Matches the "package.json" and "README.md" file that needs to be shipped.
const assetsGlob = join(COMPONENTS_DIR, '+(package.json|README.md)');
// Matches all UMD bundles inside of the bundles distribution.
const umdGlob = join(DIST_BUNDLES, '*.umd.*');
// Matches all flat ESM bundles (e.g material.js and material.es5.js)
const fesmGlob = [join(DIST_BUNDLES, '*.js'), `!${umdGlob}`];
task('build:release', sequenceTask(
'library:build',
':package:release',
));
task('build:release', function(done: () => void) {
// Synchronously run those tasks.
gulpRunSequence(
'clean',
':build:components:release',
':build:release:clean-spec',
done
);
/** Task that combines intermediate build artifacts into the release package structure. */
task(':package:release', sequenceTask(
[':package:typings', ':package:umd', ':package:fesm', ':package:assets'],
':inline-metadata-resources',
':package:metadata',
));
/** Writes a re-export metadata */
task(':package:metadata', () => {
const metadataReExport =
`{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./typings/index"}]}`;
writeFileSync(join(DIST_RELEASE, 'material.metadata.json'), metadataReExport, 'utf-8');
});
/** Inlines the html and css resources into all metadata.json files in dist/ */
task(':inline-metadata-resources', () => {
// Create a map of fileName -> fullFilePath. This is needed because the templateUrl and
// styleUrls for each component use just the filename because, in the source, the component
// and the resources live in the same directory.
const componentResources = new Map<string, string>();
glob(join(DIST_ROOT, '**/*.+(html|css)'), (err: any, resourceFilePaths: any) => {
for (const path of resourceFilePaths) {
componentResources.set(basename(path), path);
}
});
// Find all metadata files. For each one, parse the JSON content, inline the resources, and
// reserialize and rewrite back to the original location.
glob(join(DIST_ROOT, '**/*.metadata.json'), (err: any, metadataFilePaths: any) => {
for (const path of metadataFilePaths) {
let metadata = JSON.parse(readFileSync(path, 'utf-8'));
inlineMetadataResources(metadata, componentResources);
writeFileSync(path , JSON.stringify(metadata), 'utf-8');
}
});
});
task(':package:assets', () => src(assetsGlob).pipe(dest(DIST_RELEASE)));
/** Copy all d.ts except the special flat typings from ngc to typings/ in the release package. */
task(':package:typings', () => {
return src(typingsGlob)
.pipe(dest(join(DIST_RELEASE, 'typings')))
.on('end', () => createTypingFile());
});
/** Copy umd bundles to the root of the release package. */
task(':package:umd', () => src(umdGlob).pipe((dest(join(DIST_RELEASE, 'bundles')))));
/** Copy primary entry-point FESM bundles to the @angular/ directory. */
task(':package:fesm', () => src(fesmGlob).pipe(dest(join(DIST_RELEASE, '@angular'))));
/** Make sure we're logged in. */
task(':publish:whoami', execTask('npm', ['whoami'], {
@@ -32,19 +86,30 @@ task(':publish:whoami', execTask('npm', ['whoami'], {
errMessage: 'You must be logged in to publish.'
}));
/** Create a typing file that links to the bundled definitions of NGC. */
function createTypingFile() {
writeFileSync(join(DIST_RELEASE, 'material.d.ts'),
LICENSE_BANNER + '\nexport * from "./typings/index";'
);
}
task(':publish:logout', execTask('npm', ['logout']));
function _execNpmPublish(label: string): Promise<{}> {
const packageDir = DIST_COMPONENTS_ROOT;
const packageDir = DIST_RELEASE;
if (!statSync(packageDir).isDirectory()) {
return;
}
if (!existsSync(path.join(packageDir, 'package.json'))) {
if (!existsSync(join(packageDir, 'package.json'))) {
throw new Error(`"${packageDir}" does not have a package.json.`);
}
if (!existsSync(join(packageDir, 'LICENSE'))) {
throw new Error(`"${packageDir}" does not have a LICENSE file`);
}
process.chdir(packageDir);
console.log(`Publishing material...`);
@@ -94,12 +159,42 @@ task(':publish', function(done: (err?: any) => void) {
.then(() => process.chdir(currentDir));
});
task('publish', function(done: () => void) {
gulpRunSequence(
':publish:whoami',
'build:release',
':publish',
':publish:logout',
done
);
});
task('publish', sequenceTask(
':publish:whoami',
'build:release',
':publish',
':publish:logout',
));
/**
* Recurse through a parsed metadata.json file and inline all html and css.
* Note: this assumes that all html and css files have a unique name.
*/
function inlineMetadataResources(metadata: any, componentResources: Map<string, string>) {
// Convert `templateUrl` to `template`
if (metadata.templateUrl) {
const fullResourcePath = componentResources.get(metadata.templateUrl);
metadata.template = readFileSync(fullResourcePath, 'utf-8');
delete metadata.templateUrl;
}
// Convert `styleUrls` to `styles`
if (metadata.styleUrls && metadata.styleUrls.length) {
metadata.styles = [];
for (const styleUrl of metadata.styleUrls) {
const fullResourcePath = componentResources.get(styleUrl);
metadata.styles.push(readFileSync(fullResourcePath, 'utf-8'));
}
delete metadata.styleUrls;
}
// We we did nothing at this node, go deeper.
if (!metadata.template && !metadata.styles) {
for (const property in metadata) {
if (typeof metadata[property] == 'object' && metadata[property]) {
inlineMetadataResources(metadata[property], componentResources);
}
}
}
}
-5
View File
@@ -1,5 +0,0 @@
import {task} from 'gulp';
import {serverTask} from '../util/task_helpers';
task('serve', serverTask());
+25 -40
View File
@@ -1,50 +1,35 @@
import gulp = require('gulp');
import path = require('path');
import gulpMerge = require('merge2');
import {join} from 'path';
import {task, watch} from 'gulp';
import {main as ngc} from '@angular/compiler-cli';
import {PROJECT_ROOT, COMPONENTS_DIR} from '../constants';
import {sequenceTask} from '../util/task_helpers';
const karma = require('karma');
// There are no type definitions available for these imports.
const runSequence = require('run-sequence');
/** Copies deps for unit tests to the build output. */
gulp.task(':build:test:vendor', function() {
const npmVendorFiles = [
'@angular', 'core-js/client', 'hammerjs', 'rxjs', 'systemjs/dist', 'zone.js/dist'
];
const tsconfigFile = join(COMPONENTS_DIR, 'tsconfig-specs.json');
return gulpMerge(
npmVendorFiles.map(function(root) {
const glob = path.join(root, '**/*.+(js|js.map)');
return gulp.src(path.join('node_modules', glob))
.pipe(gulp.dest(path.join('dist/vendor', root)));
}));
});
/** Builds the library with a tsconfig file that includes spec files. */
task(':test:build:library-specs', () => ngc(tsconfigFile, {basePath: COMPONENTS_DIR}));
/** Builds dependencies for unit tests. */
gulp.task(':test:deps', sequenceTask(
/** Builds everything that is necessary for karma. */
task(':test:build', sequenceTask(
'clean',
[
':build:test:vendor',
':build:components:assets',
':build:components:scss',
':build:components:ts:spec',
]
':test:build:library-specs',
'library:assets',
'library:assets:inline',
));
/** Build unit test dependencies and then inlines resources (html, css) into the JS output. */
gulp.task(':test:deps:inline', sequenceTask(':test:deps', ':inline-resources'));
/**
* Runs the unit tests once with inlined resources (html, css). Does not watch for changes.
*
* Runs the unit tests. Does not watch for changes.
* This task should be used when running tests on the CI server.
*/
gulp.task('test:single-run', [':test:deps:inline'], (done: () => void) => {
task('test:single-run', [':test:build'], (done: () => void) => {
// Load karma not outside. Karma pollutes Promise with a different implementation.
let karma = require('karma');
new karma.Server({
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js'),
configFile: join(PROJECT_ROOT, 'test/karma.conf.js'),
singleRun: true
}, (exitCode: number) => {
// Immediately exit the process if Karma reported errors, because due to
@@ -64,12 +49,14 @@ gulp.task('test:single-run', [':test:deps:inline'], (done: () => void) => {
*
* This task should be used when running unit tests locally.
*/
gulp.task('test', [':test:deps'], () => {
let patternRoot = path.join(COMPONENTS_DIR, '**/*');
task('test', [':test:build'], () => {
let patternRoot = join(COMPONENTS_DIR, '**/*');
// 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: path.join(PROJECT_ROOT, 'test/karma.conf.js'),
configFile: join(PROJECT_ROOT, 'test/karma.conf.js'),
autoWatch: false,
singleRun: false
});
@@ -86,8 +73,6 @@ gulp.task('test', [':test:deps'], () => {
server.start();
server.on('browser_register', () => runTests());
// Watch for file changes, rebuild and run the tests.
gulp.watch(patternRoot + '.ts', () => runSequence(':build:components:ts:spec', runTests));
gulp.watch(patternRoot + '.scss', () => runSequence(':build:components:scss', runTests));
gulp.watch(patternRoot + '.html', () => runSequence(':build:components:assets', runTests));
// Whenever a file change has been recognized, rebuild and re-run the tests.
watch(patternRoot + '.+(ts|scss|html)', () => runSequence(':test:build', runTests));
});
+5 -13
View File
@@ -1,25 +1,17 @@
{
"compilerOptions": {
"declaration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "es2015"],
"lib": ["es2015", "dom"],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "../../dist/gulp",
"rootDir": ".",
"sourceMap": true,
"target": "es5",
"inlineSources": true,
"stripInternal": false,
"baseUrl": "",
"typeRoots": [
"../../node_modules/@types"
],
"types": [
"node"
]
}
},
"files": [
"gulpfile.ts"
]
}
+64
View File
@@ -0,0 +1,64 @@
import {LICENSE_BANNER} from '../constants';
// There are no type definitions available for these imports.
const rollup = require('rollup');
const ROLLUP_GLOBALS = {
// Angular dependencies
'@angular/animations': 'ng.animations',
'@angular/core': 'ng.core',
'@angular/common': 'ng.common',
'@angular/forms': 'ng.forms',
'@angular/http': 'ng.http',
'@angular/platform-browser': 'ng.platformBrowser',
'@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic',
'@angular/platform-browser/animations': 'ng.platformBrowser.animations',
// Rxjs dependencies
'rxjs/Subject': 'Rx',
'rxjs/add/observable/fromEvent': 'Rx.Observable',
'rxjs/add/observable/forkJoin': 'Rx.Observable',
'rxjs/add/observable/of': 'Rx.Observable',
'rxjs/add/observable/merge': 'Rx.Observable',
'rxjs/add/observable/throw': 'Rx.Observable',
'rxjs/add/operator/auditTime': 'Rx.Observable.prototype',
'rxjs/add/operator/toPromise': 'Rx.Observable.prototype',
'rxjs/add/operator/map': 'Rx.Observable.prototype',
'rxjs/add/operator/filter': 'Rx.Observable.prototype',
'rxjs/add/operator/do': 'Rx.Observable.prototype',
'rxjs/add/operator/share': 'Rx.Observable.prototype',
'rxjs/add/operator/finally': 'Rx.Observable.prototype',
'rxjs/add/operator/catch': 'Rx.Observable.prototype',
'rxjs/add/operator/first': 'Rx.Observable.prototype',
'rxjs/add/operator/startWith': 'Rx.Observable.prototype',
'rxjs/add/operator/switchMap': 'Rx.Observable.prototype',
'rxjs/Observable': 'Rx'
};
export type BundleConfig = {
entry: string;
dest: string;
format: string;
moduleName: string;
};
/** Creates a rollup bundles of the Material components.*/
export function createRollupBundle(config: BundleConfig): Promise<any> {
let bundleOptions = {
context: 'this',
external: Object.keys(ROLLUP_GLOBALS),
entry: config.entry
};
let writeOptions = {
// 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,
format: config.format,
dest: config.dest,
globals: ROLLUP_GLOBALS,
};
return rollup.rollup(bundleOptions).then((bundle: any) => bundle.write(writeOptions));
}
+27 -14
View File
@@ -3,8 +3,6 @@ import * as fs from 'fs';
import * as gulp from 'gulp';
import * as path from 'path';
import {NPM_VENDOR_FILES, PROJECT_ROOT, DIST_ROOT} from '../constants';
import {CompilerOptions} from 'typescript';
import {compileProject} from './ts-compiler';
/* Those imports lack typings. */
const gulpClean = require('gulp-clean');
@@ -16,7 +14,9 @@ const gulpConnect = require('gulp-connect');
const gulpIf = require('gulp-if');
const gulpCleanCss = require('gulp-clean-css');
// There are no type definitions available for these imports.
const resolveBin = require('resolve-bin');
const httpRewrite = require('http-rewrite-middleware');
/** If the string passed in is a glob, returns it, otherwise append '**\/*' to it. */
function _globify(maybeGlob: string, suffix = '**/*') {
@@ -34,8 +34,8 @@ function _globify(maybeGlob: string, suffix = '**/*') {
/** Creates a task that runs the TypeScript compiler */
export function tsBuildTask(tsConfigPath: string, extraOptions?: CompilerOptions) {
return () => compileProject(tsConfigPath, extraOptions);
export function tsBuildTask(tsConfigPath: string) {
return execNodeTask('typescript', 'tsc', ['-p', tsConfigPath]);
}
@@ -134,14 +134,14 @@ export function cleanTask(glob: string) {
/** Build an task that depends on all application build tasks. */
export function buildAppTask(appName: string) {
const buildTasks = ['vendor', 'ts', 'scss', 'assets']
const buildTasks = ['ts', 'scss', 'assets']
.map(taskName => `:build:${appName}:${taskName}`)
.filter(taskName => gulp.hasTask(taskName));
return (done: () => void) => {
gulpRunSequence(
'clean',
'build:components',
'library:build',
[...buildTasks],
done
);
@@ -150,22 +150,35 @@ export function buildAppTask(appName: string) {
/** Create a task that copies vendor files in the proper destination. */
export function vendorTask() {
export function vendorTask(outDir = path.join(DIST_ROOT, 'vendor')) {
return () => gulpMerge(
NPM_VENDOR_FILES.map(root => {
const glob = path.join(PROJECT_ROOT, 'node_modules', root, '**/*.+(js|js.map)');
return gulp.src(glob).pipe(gulp.dest(path.join(DIST_ROOT, 'vendor', root)));
NPM_VENDOR_FILES.map(pkg => {
const glob = path.join(PROJECT_ROOT, 'node_modules', pkg, '**/*.+(js|js.map)');
return gulp.src(glob).pipe(gulp.dest(path.join(outDir, pkg)));
}));
}
/** Create a task that serves the dist folder. */
export function serverTask(livereload = true) {
/**
* Create a task that serves a given directory in the project.
* The server rewrites all node_module/ or dist/ requests to the correct directory.
*/
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);
return () => {
gulpConnect.server({
root: 'dist/',
root: PROJECT_ROOT,
livereload: livereload,
port: 4200,
fallback: 'dist/index.html'
fallback: path.join(packagePath, 'index.html'),
middleware: () => {
return [httpRewrite.getMiddleware([
{ from: '^/node_modules/(.*)$', to: '/node_modules/$1' },
{ from: '^/dist/(.*)$', to: '/dist/$1' },
{ from: '^(.*)$', to: `/${relativePath}/$1` }
])];
}
});
};
}
+12 -1
View File
@@ -1,9 +1,10 @@
import * as ts from 'typescript';
import * as path from 'path';
import * as fs from 'fs';
import * as chalk from 'chalk';
/** Compiles a TypeScript project with possible extra options. */
export function compileProject(project: string, options: ts.CompilerOptions) {
export function compileProject(project: string, options: ts.CompilerOptions = {}) {
let parsed = parseProjectConfig(project, options);
let program = ts.createProgram(parsed.fileNames, parsed.options);
let baseDir = program.getCurrentDirectory();
@@ -16,6 +17,16 @@ export function compileProject(project: string, options: ts.CompilerOptions) {
reportDiagnostics(emitResult.diagnostics, baseDir);
}
/** Reads a input file and transpiles it into a new file. */
export function transpileFile(inputPath: string, outputPath: string, options: ts.CompilerOptions) {
let inputFile = fs.readFileSync(inputPath, 'utf-8');
let transpiled = ts.transpileModule(inputFile, { compilerOptions: options });
reportDiagnostics(transpiled.diagnostics);
fs.writeFileSync(outputPath, transpiled.outputText);
}
/** Parses a TypeScript project configuration. */
function parseProjectConfig(project: string, options: ts.CompilerOptions) {
let config = ts.readConfigFile(project, ts.sys.readFile).config;
+372 -217
View File
File diff suppressed because it is too large Load Diff