Skip to content

Commit 7dcb9fd

Browse files
committed
build: ship esm bundle
* Now ships a Flat / ESM bundle (similar as for Angular 4+ releases) * In future PRs we will remove the single ES-files and can just link to the ES bundle (as in angular/angular).
1 parent 02f4bc3 commit 7dcb9fd

11 files changed

+197
-153
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@types/node": "^7.0.4",
5252
"@types/run-sequence": "^0.0.28",
5353
"@types/rx": "2.5.33",
54+
"autoprefixer": "^6.7.6",
5455
"axe-core": "^2.1.7",
5556
"axe-webdriverjs": "^0.5.0",
5657
"conventional-changelog": "^1.1.0",
@@ -62,7 +63,6 @@
6263
"glob": "^7.1.1",
6364
"google-cloud": "^0.45.1",
6465
"gulp": "^3.9.1",
65-
"gulp-autoprefixer": "^3.1.1",
6666
"gulp-better-rollup": "^1.0.2",
6767
"gulp-clean": "^0.3.2",
6868
"gulp-clean-css": "^2.3.2",
@@ -73,6 +73,7 @@
7373
"gulp-htmlmin": "^3.0.0",
7474
"gulp-if": "^2.0.2",
7575
"gulp-markdown": "^1.2.0",
76+
"gulp-postcss": "^6.3.0",
7677
"gulp-rename": "^1.2.2",
7778
"gulp-sass": "^3.1.0",
7879
"gulp-sourcemaps": "^2.4.0",

src/lib/tsconfig-srcs.json

-33
This file was deleted.

src/lib/tsconfig.json

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@
44
"emitDecoratorMetadata": true,
55
"experimentalDecorators": true,
66
"lib": ["es6", "es2015", "dom"],
7-
"module": "commonjs",
7+
"module": "es2015",
88
"moduleResolution": "node",
99
"noEmitOnError": true,
1010
"noImplicitAny": true,
1111
"outDir": "../../dist/@angular/material",
1212
"rootDir": ".",
1313
"sourceMap": true,
14-
"target": "es5",
14+
"target": "es6",
1515
"inlineSources": true,
1616
"stripInternal": false,
1717
"baseUrl": "",
18-
"paths": {
19-
},
2018
"typeRoots": [
2119
"../../node_modules/@types/!(node)"
2220
],

tools/gulp/task_helpers.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,24 @@ import * as fs from 'fs';
33
import * as gulp from 'gulp';
44
import * as path from 'path';
55
import {NPM_VENDOR_FILES, PROJECT_ROOT, DIST_ROOT, SASS_AUTOPREFIXER_OPTIONS} from './constants';
6+
import {compileProject} from './util/ts-compiler';
7+
import {CompilerOptions} from 'typescript';
68

7-
8-
/** Those imports lack typings. */
9+
/* Those imports lack typings. */
910
const gulpClean = require('gulp-clean');
1011
const gulpMerge = require('merge2');
1112
const gulpRunSequence = require('run-sequence');
1213
const gulpSass = require('gulp-sass');
1314
const gulpSourcemaps = require('gulp-sourcemaps');
14-
const gulpAutoprefixer = require('gulp-autoprefixer');
15+
const gulpPostcss = require('gulp-postcss');
1516
const gulpConnect = require('gulp-connect');
17+
const gulpIf = require('gulp-if');
18+
const gulpCleanCss = require('gulp-clean-css');
19+
1620
const resolveBin = require('resolve-bin');
1721
const firebaseAdmin = require('firebase-admin');
1822
const gcloud = require('google-cloud');
19-
23+
const autoprefixer = require('autoprefixer');
2024

2125
/** If the string passed in is a glob, returns it, otherwise append '**\/*' to it. */
2226
function _globify(maybeGlob: string, suffix = '**/*') {
@@ -34,18 +38,21 @@ function _globify(maybeGlob: string, suffix = '**/*') {
3438

3539

3640
/** Creates a task that runs the TypeScript compiler */
37-
export function tsBuildTask(tsConfigPath: string) {
38-
return execNodeTask('typescript', 'tsc', ['-p', tsConfigPath]);
41+
export function tsBuildTask(tsConfigPath: string, extraOptions?: CompilerOptions) {
42+
return () => {
43+
compileProject(tsConfigPath, extraOptions);
44+
};
3945
}
4046

4147

4248
/** Create a SASS Build Task. */
43-
export function sassBuildTask(dest: string, root: string) {
49+
export function sassBuildTask(dest: string, root: string, minify = false) {
4450
return () => {
4551
return gulp.src(_globify(root, '**/*.scss'))
46-
.pipe(gulpSourcemaps.init())
52+
.pipe(gulpSourcemaps.init({ loadMaps: true }))
4753
.pipe(gulpSass().on('error', gulpSass.logError))
48-
.pipe(gulpAutoprefixer(SASS_AUTOPREFIXER_OPTIONS))
54+
.pipe(gulpPostcss([autoprefixer(SASS_AUTOPREFIXER_OPTIONS)]))
55+
.pipe(gulpIf(minify, gulpCleanCss()))
4956
.pipe(gulpSourcemaps.write('.'))
5057
.pipe(gulp.dest(dest));
5158
};

tools/gulp/tasks/aot.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ task('aot:copy', [':build:devapp:scss', ':build:devapp:assets']);
1212
*/
1313
task('aot:prepare', sequenceTask(
1414
'clean',
15-
['aot:copy', 'build:components:release', ':build:components:ngc'])
15+
['aot:copy', 'build:components', ':build:components:ngc'])
1616
);
1717

1818
/** Builds the demo-app with the Angular compiler to verify that all components work. */

tools/gulp/tasks/components.ts

+111-100
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,150 @@
11
import {task, watch, src, dest} from 'gulp';
2+
import {ScriptTarget, ModuleKind} from 'typescript';
23
import * as path from 'path';
34

45
import {
56
DIST_COMPONENTS_ROOT, PROJECT_ROOT, COMPONENTS_DIR, HTML_MINIFIER_OPTIONS, LICENSE_BANNER
67
} from '../constants';
78
import {
8-
sassBuildTask, tsBuildTask, execNodeTask, copyTask, sequenceTask,
9+
sassBuildTask, tsBuildTask, execNodeTask, sequenceTask,
910
triggerLivereload
1011
} from '../task_helpers';
1112

12-
// No typings for these.
13+
// These imports lack of types.
1314
const inlineResources = require('../../../scripts/release/inline-resources');
1415
const gulpRollup = require('gulp-better-rollup');
15-
const gulpMinifyCss = require('gulp-clean-css');
1616
const gulpMinifyHtml = require('gulp-htmlmin');
1717
const gulpIf = require('gulp-if');
1818

19+
/** Path to tsconfig file for the components. */
20+
const tsconfigPath = path.join(COMPONENTS_DIR, 'tsconfig.json');
1921

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+
];
2929

30+
/** Builds components to UMD bundle. */
31+
task('build:components', [':build:components:bundle:umd']);
3032

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:es',
37+
':build:components:ngc'
38+
));
3839

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+
}));
4146

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+
));
4451

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:es', sequenceTask(
53+
':build:components:ts:es6', ':build:components:inline', ':build:components:rollup:es'
54+
));
5155

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)))
5660
.pipe(dest(DIST_COMPONENTS_ROOT));
5761
});
5862

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));
10865

66+
/** Builds a ES6 bundle for all components. */
67+
task(':build:components:rollup:es', () => {
10968
return src(path.join(DIST_COMPONENTS_ROOT, 'index.js'))
110-
.pipe(gulpRollup(rollupOptions, rollupGenerateOptions))
69+
.pipe(createRollupBundle('es', 'material.js'))
11170
.pipe(dest(path.join(DIST_COMPONENTS_ROOT, 'bundles')));
11271
});
11372

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. */
11582
task(':build:components:inline', sequenceTask(
116-
[':build:components:ts', ':build:components:scss', ':build:components:assets'],
83+
[':build:components:scss', ':build:components:assets'],
11784
':inline-resources',
11885
));
11986

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. */
12888
task(':inline-resources', () => inlineResources(DIST_COMPONENTS_ROOT));
12989

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-
13690
/** 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(
13892
'@angular/compiler-cli', 'ngc', ['-p', tsconfigPath]
13993
));
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

Comments
 (0)