|
1 | 1 | import {task, watch, src, dest} from 'gulp'; |
| 2 | +import {ScriptTarget, ModuleKind} from 'typescript'; |
2 | 3 | import * as path from 'path'; |
3 | 4 |
|
4 | 5 | import { |
5 | 6 | DIST_COMPONENTS_ROOT, PROJECT_ROOT, COMPONENTS_DIR, HTML_MINIFIER_OPTIONS, LICENSE_BANNER |
6 | 7 | } from '../constants'; |
7 | 8 | import { |
8 | | - sassBuildTask, tsBuildTask, execNodeTask, copyTask, sequenceTask, |
| 9 | + sassBuildTask, tsBuildTask, execNodeTask, sequenceTask, |
9 | 10 | triggerLivereload |
10 | 11 | } from '../util/task_helpers'; |
11 | 12 |
|
12 | | -// No typings for these. |
| 13 | +// There are no type definitions available for these imports. |
13 | 14 | const inlineResources = require('../../../scripts/release/inline-resources'); |
14 | 15 | const gulpRollup = require('gulp-better-rollup'); |
15 | | -const gulpMinifyCss = require('gulp-clean-css'); |
16 | 16 | const gulpMinifyHtml = require('gulp-htmlmin'); |
17 | 17 | const gulpIf = require('gulp-if'); |
18 | 18 |
|
| 19 | +/** Path to tsconfig file for the components. */ |
| 20 | +const tsconfigPath = path.join(COMPONENTS_DIR, 'tsconfig.json'); |
19 | 21 |
|
20 | | -// NOTE: there are two build "modes" in this file, based on which tsconfig is used. |
21 | | -// When `tsconfig.json` is used, we are outputting ES6 modules and a UMD bundle. This is used |
22 | | -// for serving and for release. |
23 | | -// |
24 | | -// When `tsconfig-spec.json` is used, we are outputting CommonJS modules. This is used |
25 | | -// for unit tests (karma). |
26 | | - |
27 | | -/** Path to the tsconfig used for ESM output. */ |
28 | | -const tsconfigPath = path.relative(PROJECT_ROOT, path.join(COMPONENTS_DIR, 'tsconfig-srcs.json')); |
| 22 | +/** Asset files to be added to the components output. */ |
| 23 | +const assetFiles = [ |
| 24 | + path.join(COMPONENTS_DIR, '**/*.html'), |
| 25 | + path.join(COMPONENTS_DIR, 'package.json'), |
| 26 | + path.join(PROJECT_ROOT, 'README.md'), |
| 27 | + path.join(PROJECT_ROOT, 'LICENSE'), |
| 28 | +]; |
29 | 29 |
|
| 30 | +/** Builds components to UMD bundle. */ |
| 31 | +task('build:components', [':build:components:bundle:umd']); |
30 | 32 |
|
31 | | -/** [Watch task] Rebuilds (ESM output) whenever ts, scss, or html sources change. */ |
32 | | -task(':watch:components', () => { |
33 | | - watch(path.join(COMPONENTS_DIR, '**/*.ts'), ['build:components', triggerLivereload]); |
34 | | - watch(path.join(COMPONENTS_DIR, '**/*.scss'), ['build:components', triggerLivereload]); |
35 | | - watch(path.join(COMPONENTS_DIR, '**/*.html'), ['build:components', triggerLivereload]); |
36 | | -}); |
37 | | - |
| 33 | +/** Builds components for Angular Material releases */ |
| 34 | +task(':build:components:release', sequenceTask( |
| 35 | + ':build:components:bundle:umd', |
| 36 | + ':build:components:bundle:esm', |
| 37 | + ':build:components:ngc' |
| 38 | +)); |
38 | 39 |
|
39 | | -/** Builds component typescript only (ESM output). */ |
40 | | -task(':build:components:ts', tsBuildTask(path.join(COMPONENTS_DIR, 'tsconfig-srcs.json'))); |
| 40 | +/** Builds components typescript in ES5, ES6 target. For specs Karma needs CJS output. */ |
| 41 | +task(':build:components:ts:es5', tsBuildTask(tsconfigPath, { target: ScriptTarget.ES5 })); |
| 42 | +task(':build:components:ts:es6', tsBuildTask(tsconfigPath, { target: ScriptTarget.ES6 })); |
| 43 | +task(':build:components:ts:spec', tsBuildTask(tsconfigPath, { |
| 44 | + target: ScriptTarget.ES5, module: ModuleKind.CommonJS |
| 45 | +})); |
41 | 46 |
|
42 | | -/** Builds components typescript for tests (CJS output). */ |
43 | | -task(':build:components:spec', tsBuildTask(COMPONENTS_DIR)); |
| 47 | +/** Tasks to create a UMD or ES bundle */ |
| 48 | +task(':build:components:bundle:umd', sequenceTask( |
| 49 | + ':build:components:ts:es5', ':build:components:inline', ':build:components:rollup:umd' |
| 50 | +)); |
44 | 51 |
|
45 | | -/** Copies assets (html, markdown) to build output. */ |
46 | | -task(':build:components:assets', copyTask([ |
47 | | - path.join(COMPONENTS_DIR, '**/*.!(ts|spec.ts)'), |
48 | | - path.join(PROJECT_ROOT, 'README.md'), |
49 | | - path.join(PROJECT_ROOT, 'LICENSE'), |
50 | | -], DIST_COMPONENTS_ROOT)); |
| 52 | +task(':build:components:bundle:esm', sequenceTask( |
| 53 | + ':build:components:ts:es6', ':build:components:inline', ':build:components:rollup:esm' |
| 54 | +)); |
51 | 55 |
|
52 | | -/** Minifies the HTML and CSS assets in the distribution folder. */ |
53 | | -task(':build:components:assets:minify', () => { |
54 | | - return src('**/*.+(html|css)', { cwd: DIST_COMPONENTS_ROOT}) |
55 | | - .pipe(gulpIf(/.css$/, gulpMinifyCss(), gulpMinifyHtml(HTML_MINIFIER_OPTIONS))) |
| 56 | +/** Copies all component assets to the build output. */ |
| 57 | +task(':build:components:assets', () => { |
| 58 | + return src(assetFiles) |
| 59 | + .pipe(gulpIf(/.html$/, gulpMinifyHtml(HTML_MINIFIER_OPTIONS))) |
56 | 60 | .pipe(dest(DIST_COMPONENTS_ROOT)); |
57 | 61 | }); |
58 | 62 |
|
59 | | -/** Builds scss into css. */ |
60 | | -task(':build:components:scss', sassBuildTask(DIST_COMPONENTS_ROOT, COMPONENTS_DIR)); |
61 | | - |
62 | | -/** Builds the UMD bundle for all of Angular Material. */ |
63 | | -task(':build:components:rollup', () => { |
64 | | - const globals: {[name: string]: string} = { |
65 | | - // Angular dependencies |
66 | | - '@angular/core': 'ng.core', |
67 | | - '@angular/common': 'ng.common', |
68 | | - '@angular/forms': 'ng.forms', |
69 | | - '@angular/http': 'ng.http', |
70 | | - '@angular/platform-browser': 'ng.platformBrowser', |
71 | | - '@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic', |
72 | | - |
73 | | - // Rxjs dependencies |
74 | | - 'rxjs/Subject': 'Rx', |
75 | | - 'rxjs/add/observable/fromEvent': 'Rx.Observable', |
76 | | - 'rxjs/add/observable/forkJoin': 'Rx.Observable', |
77 | | - 'rxjs/add/observable/of': 'Rx.Observable', |
78 | | - 'rxjs/add/observable/merge': 'Rx.Observable', |
79 | | - 'rxjs/add/observable/throw': 'Rx.Observable', |
80 | | - 'rxjs/add/operator/auditTime': 'Rx.Observable.prototype', |
81 | | - 'rxjs/add/operator/toPromise': 'Rx.Observable.prototype', |
82 | | - 'rxjs/add/operator/map': 'Rx.Observable.prototype', |
83 | | - 'rxjs/add/operator/filter': 'Rx.Observable.prototype', |
84 | | - 'rxjs/add/operator/do': 'Rx.Observable.prototype', |
85 | | - 'rxjs/add/operator/share': 'Rx.Observable.prototype', |
86 | | - 'rxjs/add/operator/finally': 'Rx.Observable.prototype', |
87 | | - 'rxjs/add/operator/catch': 'Rx.Observable.prototype', |
88 | | - 'rxjs/add/operator/first': 'Rx.Observable.prototype', |
89 | | - 'rxjs/add/operator/startWith': 'Rx.Observable.prototype', |
90 | | - 'rxjs/add/operator/switchMap': 'Rx.Observable.prototype', |
91 | | - 'rxjs/Observable': 'Rx' |
92 | | - }; |
93 | | - |
94 | | - const rollupOptions = { |
95 | | - context: 'this', |
96 | | - external: Object.keys(globals) |
97 | | - }; |
98 | | - |
99 | | - const rollupGenerateOptions = { |
100 | | - // Keep the moduleId empty because we don't want to force developers to a specific moduleId. |
101 | | - moduleId: '', |
102 | | - moduleName: 'ng.material', |
103 | | - format: 'umd', |
104 | | - globals, |
105 | | - banner: LICENSE_BANNER, |
106 | | - dest: 'material.umd.js' |
107 | | - }; |
| 63 | +/** Compiles the components SCSS into minified CSS. */ |
| 64 | +task(':build:components:scss', sassBuildTask(DIST_COMPONENTS_ROOT, COMPONENTS_DIR, true)); |
108 | 65 |
|
| 66 | +/** Builds a ES6 bundle for all components. */ |
| 67 | +task(':build:components:rollup:esm', () => { |
109 | 68 | return src(path.join(DIST_COMPONENTS_ROOT, 'index.js')) |
110 | | - .pipe(gulpRollup(rollupOptions, rollupGenerateOptions)) |
| 69 | + .pipe(createRollupBundle('es', 'material.js')) |
111 | 70 | .pipe(dest(path.join(DIST_COMPONENTS_ROOT, 'bundles'))); |
112 | 71 | }); |
113 | 72 |
|
114 | | -/** Builds components with resources (html, css) inlined into the built JS (ESM output). */ |
| 73 | +/** Builds a UMD bundle (ES5) for all components. */ |
| 74 | +task(':build:components:rollup:umd', () => { |
| 75 | + return src(path.join(DIST_COMPONENTS_ROOT, 'index.js')) |
| 76 | + .pipe(createRollupBundle('umd', 'material.umd.js')) |
| 77 | + .pipe(dest(path.join(DIST_COMPONENTS_ROOT, 'bundles'))); |
| 78 | +}); |
| 79 | + |
| 80 | + |
| 81 | +/** Builds components with resources (html, css) inlined into the built JS. */ |
115 | 82 | task(':build:components:inline', sequenceTask( |
116 | | - [':build:components:ts', ':build:components:scss', ':build:components:assets'], |
| 83 | + [':build:components:scss', ':build:components:assets'], |
117 | 84 | ':inline-resources', |
118 | 85 | )); |
119 | 86 |
|
120 | | -/** Builds components with minified HTML and CSS inlined into the built JS. */ |
121 | | -task(':build:components:inline:release', sequenceTask( |
122 | | - [':build:components:ts', ':build:components:scss', ':build:components:assets'], |
123 | | - ':build:components:assets:minify', |
124 | | - ':inline-resources' |
125 | | -)); |
126 | | - |
127 | | -/** Inlines resources (html, css) into the JS output (for either ESM or CJS output). */ |
| 87 | +/** Inlines resources (html, css) into the JS output. */ |
128 | 88 | task(':inline-resources', () => inlineResources(DIST_COMPONENTS_ROOT)); |
129 | 89 |
|
130 | | -/** Builds components to ESM output and UMD bundle. */ |
131 | | -task('build:components', sequenceTask(':build:components:inline', ':build:components:rollup')); |
132 | | -task('build:components:release', sequenceTask( |
133 | | - ':build:components:inline:release', ':build:components:rollup' |
134 | | -)); |
135 | | - |
136 | 90 | /** Generates metadata.json files for all of the components. */ |
137 | | -task(':build:components:ngc', ['build:components:release'], execNodeTask( |
| 91 | +task(':build:components:ngc', ['build:components'], execNodeTask( |
138 | 92 | '@angular/compiler-cli', 'ngc', ['-p', tsconfigPath] |
139 | 93 | )); |
| 94 | + |
| 95 | +/** [Watch task] Rebuilds (ESM output) whenever ts, scss, or html sources change. */ |
| 96 | +task(':watch:components', () => { |
| 97 | + watch(path.join(COMPONENTS_DIR, '**/*.ts'), ['build:components', triggerLivereload]); |
| 98 | + watch(path.join(COMPONENTS_DIR, '**/*.scss'), ['build:components', triggerLivereload]); |
| 99 | + watch(path.join(COMPONENTS_DIR, '**/*.html'), ['build:components', triggerLivereload]); |
| 100 | +}); |
| 101 | + |
| 102 | +const ROLLUP_GLOBALS = { |
| 103 | + // Angular dependencies |
| 104 | + '@angular/core': 'ng.core', |
| 105 | + '@angular/common': 'ng.common', |
| 106 | + '@angular/forms': 'ng.forms', |
| 107 | + '@angular/http': 'ng.http', |
| 108 | + '@angular/platform-browser': 'ng.platformBrowser', |
| 109 | + '@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic', |
| 110 | + |
| 111 | + // Rxjs dependencies |
| 112 | + 'rxjs/Subject': 'Rx', |
| 113 | + 'rxjs/add/observable/fromEvent': 'Rx.Observable', |
| 114 | + 'rxjs/add/observable/forkJoin': 'Rx.Observable', |
| 115 | + 'rxjs/add/observable/of': 'Rx.Observable', |
| 116 | + 'rxjs/add/observable/merge': 'Rx.Observable', |
| 117 | + 'rxjs/add/observable/throw': 'Rx.Observable', |
| 118 | + 'rxjs/add/operator/auditTime': 'Rx.Observable.prototype', |
| 119 | + 'rxjs/add/operator/toPromise': 'Rx.Observable.prototype', |
| 120 | + 'rxjs/add/operator/map': 'Rx.Observable.prototype', |
| 121 | + 'rxjs/add/operator/filter': 'Rx.Observable.prototype', |
| 122 | + 'rxjs/add/operator/do': 'Rx.Observable.prototype', |
| 123 | + 'rxjs/add/operator/share': 'Rx.Observable.prototype', |
| 124 | + 'rxjs/add/operator/finally': 'Rx.Observable.prototype', |
| 125 | + 'rxjs/add/operator/catch': 'Rx.Observable.prototype', |
| 126 | + 'rxjs/add/operator/first': 'Rx.Observable.prototype', |
| 127 | + 'rxjs/add/operator/startWith': 'Rx.Observable.prototype', |
| 128 | + 'rxjs/add/operator/switchMap': 'Rx.Observable.prototype', |
| 129 | + 'rxjs/Observable': 'Rx' |
| 130 | +}; |
| 131 | + |
| 132 | +/** Creates a rollup bundles of the Material components.*/ |
| 133 | +function createRollupBundle(format: string, outFile: string) { |
| 134 | + let rollupOptions = { |
| 135 | + context: 'this', |
| 136 | + external: Object.keys(ROLLUP_GLOBALS) |
| 137 | + }; |
| 138 | + |
| 139 | + let rollupGenerateOptions = { |
| 140 | + // Keep the moduleId empty because we don't want to force developers to a specific moduleId. |
| 141 | + moduleId: '', |
| 142 | + moduleName: 'ng.material', |
| 143 | + banner: LICENSE_BANNER, |
| 144 | + format: format, |
| 145 | + dest: outFile, |
| 146 | + globals: ROLLUP_GLOBALS, |
| 147 | + }; |
| 148 | + |
| 149 | + return gulpRollup(rollupOptions, rollupGenerateOptions); |
| 150 | +} |
0 commit comments