build(gulp): lazy-require modules in order to improve startup time

Closes #5498
This commit is contained in:
Igor Minar 2015-11-26 23:45:40 -08:00 committed by Igor Minar
parent 65bdf42903
commit a8c3b9d67c
3 changed files with 258 additions and 183 deletions

View File

@ -1,51 +1,30 @@
'use strict'; 'use strict';
var autoprefixer = require('gulp-autoprefixer');
var clangFormat = require('clang-format');
var del = require('del'); var del = require('del');
var exec = require('child_process').exec;
var fork = require('child_process').fork;
var gulp = require('gulp'); var gulp = require('gulp');
var gulpFormat = require('gulp-clang-format');
var gulpPlugins = require('gulp-load-plugins')(); var gulpPlugins = require('gulp-load-plugins')();
var sass = require('gulp-sass');
var shell = require('gulp-shell');
var spawn = require('child_process').spawn;
var runSequence = require('run-sequence');
var madge = require('madge');
var merge = require('merge'); var merge = require('merge');
var merge2 = require('merge2'); var merge2 = require('merge2');
var minimist = require('minimist');
var os = require('os');
var path = require('path'); var path = require('path');
var q = require('q'); var runSequence = require('run-sequence');
var shell = require('gulp-shell');
var licenseWrap = require('./tools/build/licensewrap'); var licenseWrap = require('./tools/build/licensewrap');
var analytics = require('./tools/analytics/analytics'); var analytics = require('./tools/analytics/analytics');
var watch = require('./tools/build/watch');
var pubget = require('./tools/build/pubget'); var pubget = require('./tools/build/pubget');
var proto = require('./tools/build/proto');
var linknodemodules = require('./tools/build/linknodemodules'); var linknodemodules = require('./tools/build/linknodemodules');
var pubbuild = require('./tools/build/pubbuild'); var pubbuild = require('./tools/build/pubbuild');
var dartanalyzer = require('./tools/build/dartanalyzer');
var dartapidocs = require('./tools/build/dartapidocs');
var jsserve = require('./tools/build/jsserve'); var jsserve = require('./tools/build/jsserve');
var pubserve = require('./tools/build/pubserve'); var pubserve = require('./tools/build/pubserve');
var karma = require('karma');
var minimist = require('minimist');
var runServerDartTests = require('./tools/build/run_server_dart_tests'); var runServerDartTests = require('./tools/build/run_server_dart_tests');
var sourcemaps = require('gulp-sourcemaps');
var tsc = require('gulp-typescript');
var util = require('./tools/build/util'); var util = require('./tools/build/util');
var bundler = require('./tools/build/bundle');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var insert = require('gulp-insert');
var buildRouter = require('./modules/angular1_router/build'); var buildRouter = require('./modules/angular1_router/build');
var uglify = require('gulp-uglify');
var shouldLog = require('./tools/build/logging'); var shouldLog = require('./tools/build/logging');
var dartSdk = require('./tools/build/dart'); var dartSdk = require('./tools/build/dart');
var browserProvidersConf = require('./browser-providers.conf.js'); var browserProvidersConf = require('./browser-providers.conf.js');
var os = require('os');
require('./tools/check-environment')( require('./tools/check-environment')(
{requiredNpmVersion: '>=2.14.7', requiredNodeVersion: '>=4.2.1'}); {requiredNpmVersion: '>=2.14.7', requiredNodeVersion: '>=4.2.1'});
@ -119,7 +98,9 @@ function sequenceComplete(done) {
var treatTestErrorsAsFatal = true; var treatTestErrorsAsFatal = true;
function runJasmineTests(globs, done) { function runJasmineTests(globs, done) {
var fork = require('child_process').fork;
var args = ['--'].concat(globs); var args = ['--'].concat(globs);
fork('./tools/cjs-jasmine', args, {stdio: 'inherit'}) fork('./tools/cjs-jasmine', args, {stdio: 'inherit'})
.on('close', function jasmineCloseHandler(exitCode) { .on('close', function jasmineCloseHandler(exitCode) {
if (exitCode && treatTestErrorsAsFatal) { if (exitCode && treatTestErrorsAsFatal) {
@ -220,6 +201,8 @@ gulp.task('build/pubspec.dart',
// //
// See #2437 for more info. // See #2437 for more info.
gulp.task('!build/remove-pub-symlinks', function(done) { gulp.task('!build/remove-pub-symlinks', function(done) {
var exec = require('child_process').exec;
if (process.platform == 'win32') { if (process.platform == 'win32') {
done(); done();
return; return;
@ -238,16 +221,29 @@ gulp.task('!build/remove-pub-symlinks', function(done) {
// ------------ // ------------
// dartanalyzer // dartanalyzer
gulp.task('build/analyze.dart',
dartanalyzer(gulp, gulpPlugins, {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER}));
gulp.task('build/analyze.ddc.dart', gulp.task('build/analyze.dart', () => {
dartanalyzer(gulp, gulpPlugins, var dartanalyzer = require('./tools/build/dartanalyzer');
{dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true}));
return dartanalyzer(gulp, gulpPlugins, {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER});
});
gulp.task('build/analyze.ddc.dart', () => {
var dartanalyzer = require('./tools/build/dartanalyzer');
return dartanalyzer(gulp, gulpPlugins,
{dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true});
});
gulp.task('build/check.apidocs.dart', () => {
var dartapidocs = require('./tools/build/dartapidocs');
return dartapidocs(gulp, gulpPlugins,
{dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN});
});
gulp.task('build/check.apidocs.dart',
dartapidocs(gulp, gulpPlugins,
{dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN}));
// ------------ // ------------
// pubbuild // pubbuild
@ -262,6 +258,9 @@ gulp.task(
// formatting // formatting
function doCheckFormat() { function doCheckFormat() {
var clangFormat = require('clang-format');
var gulpFormat = require('gulp-clang-format');
return gulp.src(['modules/**/*.ts', 'tools/**/*.ts', '!**/typings/**/*.d.ts', 'gulpfile.js']) return gulp.src(['modules/**/*.ts', 'tools/**/*.ts', '!**/typings/**/*.d.ts', 'gulpfile.js'])
.pipe(gulpFormat.checkFormat('file', clangFormat)); .pipe(gulpFormat.checkFormat('file', clangFormat));
} }
@ -305,6 +304,8 @@ gulp.task('lint', ['build.tools'], function() {
// ------------ // ------------
// check circular dependencies in Node.js context // check circular dependencies in Node.js context
gulp.task('build/checkCircularDependencies', function(done) { gulp.task('build/checkCircularDependencies', function(done) {
var madge = require('madge');
var dependencyObject = madge(CONFIG.dest.js.dev.es5, { var dependencyObject = madge(CONFIG.dest.js.dev.es5, {
format: 'cjs', format: 'cjs',
paths: [CONFIG.dest.js.dev.es5], paths: [CONFIG.dest.js.dev.es5],
@ -345,6 +346,8 @@ function proxyServeDart() {
// ------------------ // ------------------
// web servers // web servers
gulp.task('serve.js.dev', ['build.js'], function(neverDone) { gulp.task('serve.js.dev', ['build.js'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, '!broccoli.js.dev'); watch('modules/**', {ignoreInitial: true}, '!broccoli.js.dev');
jsServeDev(); jsServeDev();
}); });
@ -353,12 +356,16 @@ gulp.task('serve.js.prod', jsServeProd);
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'], gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'],
function(neverDone) { function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']); watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
jsServeDev(); jsServeDev();
}); });
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'], gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'],
function(neverDone) { function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']); watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
jsServeProd(); jsServeProd();
}); });
@ -392,6 +399,8 @@ gulp.task(
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks_external', port: 8008})); {command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks_external', port: 8008}));
gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) { gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
// Note: we are not using build.dart as the dart analyzer takes too long... // Note: we are not using build.dart as the dart analyzer takes too long...
watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']); watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']);
runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart'); runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart');
@ -402,6 +411,8 @@ gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
// CI tests suites // CI tests suites
function runKarma(configFile, done) { function runKarma(configFile, done) {
var exec = require('child_process').exec;
var cmd = process.platform === 'win32' ? 'node_modules\\.bin\\karma run ' : var cmd = process.platform === 'win32' ? 'node_modules\\.bin\\karma run ' :
'node node_modules/.bin/karma run '; 'node node_modules/.bin/karma run ';
cmd += configFile; cmd += configFile;
@ -473,14 +484,18 @@ function getBrowsersFromCLI(provider, isDart) {
}; };
} }
gulp.task('test.unit.js', ['build.js.dev'], function(done) { gulp.task('test.unit.js', ['build.js.dev'], function(neverDone) {
var watch = require('./tools/build/watch');
printModulesWarning(); printModulesWarning();
runSequence('!test.unit.js/karma-server', function() { runSequence('!test.unit.js/karma-server', function() {
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!test.unit.js/karma-run']); watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!test.unit.js/karma-run']);
}); });
}); });
gulp.task('watch.js.dev', ['build.js.dev'], function(done) { gulp.task('watch.js.dev', ['build.js.dev'], function(neverDone) {
var watch = require('./tools/build/watch');
printModulesWarning(); printModulesWarning();
watch('modules/**', ['!broccoli.js.dev']); watch('modules/**', ['!broccoli.js.dev']);
}); });
@ -507,6 +522,8 @@ gulp.task('test.unit.js.browserstack', ['build.js.dev'], function(done) {
}); });
function launchKarmaWithExternalBrowsers(reporters, browsers, done) { function launchKarmaWithExternalBrowsers(reporters, browsers, done) {
var karma = require('karma');
new karma.Server( new karma.Server(
{ {
configFile: __dirname + '/karma-js.conf.js', configFile: __dirname + '/karma-js.conf.js',
@ -524,6 +541,8 @@ function launchKarmaWithExternalBrowsers(reporters, browsers, done) {
} }
gulp.task('!test.unit.js/karma-server', function(done) { gulp.task('!test.unit.js/karma-server', function(done) {
var karma = require('karma');
var watchStarted = false; var watchStarted = false;
var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js'}); var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js'});
server.on('run_complete', function() { server.on('run_complete', function() {
@ -542,19 +561,25 @@ gulp.task('!test.unit.js/karma-run', function(done) {
runKarma('karma-js.conf.js', done); runKarma('karma-js.conf.js', done);
}); });
gulp.task('test.unit.router', function(done) { gulp.task('test.unit.router', function(neverDone) {
var watch = require('./tools/build/watch');
runSequence('!test.unit.router/karma-server', function() { runSequence('!test.unit.router/karma-server', function() {
watch('modules/**', ['buildRouter.dev', '!test.unit.router/karma-run']); watch('modules/**', ['buildRouter.dev', '!test.unit.router/karma-run']);
}); });
}); });
gulp.task('!test.unit.router/karma-server', function() { gulp.task('!test.unit.router/karma-server', function() {
var karma = require('karma');
new karma.Server({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'}) new karma.Server({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'})
.start(); .start();
}); });
gulp.task('!test.unit.router/karma-run', function(done) { gulp.task('!test.unit.router/karma-run', function(done) {
var karma = require('karma');
karma.runner.run({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'}, karma.runner.run({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'},
function(exitCode) { function(exitCode) {
// ignore exitCode, we don't want to fail the build in the interactive (non-ci) // ignore exitCode, we don't want to fail the build in the interactive (non-ci)
@ -571,6 +596,8 @@ gulp.task('test.unit.dart', function(done) {
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css', '!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
'!test.unit.dart/karma-server', '!test.unit.dart/karma-run', function(error) { '!test.unit.dart/karma-server', '!test.unit.dart/karma-run', function(error) {
var watch = require('./tools/build/watch');
// if initial build failed (likely due to build or formatting step) then exit // if initial build failed (likely due to build or formatting step) then exit
// otherwise karma server doesn't start and we can't continue running properly // otherwise karma server doesn't start and we can't continue running properly
if (error) { if (error) {
@ -611,6 +638,8 @@ gulp.task('watch.dart.dev', function(done) {
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css', '!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
function(error) { function(error) {
var watch = require('./tools/build/watch');
// if initial build failed (likely due to build or formatting step) then exit // if initial build failed (likely due to build or formatting step) then exit
// otherwise karma server doesn't start and we can't continue running properly // otherwise karma server doesn't start and we can't continue running properly
if (error) { if (error) {
@ -630,11 +659,15 @@ gulp.task('!test.unit.dart/karma-run', function(done) {
gulp.task('!test.unit.dart/karma-server', function() { gulp.task('!test.unit.dart/karma-server', function() {
var karma = require('karma');
new karma.Server({configFile: __dirname + '/karma-dart.conf.js', reporters: 'dots'}).start(); new karma.Server({configFile: __dirname + '/karma-dart.conf.js', reporters: 'dots'}).start();
}); });
gulp.task('test.unit.router/ci', function(done) { gulp.task('test.unit.router/ci', function(done) {
var karma = require('karma');
var browserConf = getBrowsersFromCLI(); var browserConf = getBrowsersFromCLI();
new karma.Server( new karma.Server(
{ {
@ -648,6 +681,8 @@ gulp.task('test.unit.router/ci', function(done) {
}); });
gulp.task('test.unit.js/ci', function(done) { gulp.task('test.unit.js/ci', function(done) {
var karma = require('karma');
var browserConf = getBrowsersFromCLI(); var browserConf = getBrowsersFromCLI();
new karma.Server( new karma.Server(
{ {
@ -670,6 +705,8 @@ gulp.task('test.unit.js.browserstack/ci', function(done) {
}); });
gulp.task('test.unit.dart/ci', function(done) { gulp.task('test.unit.dart/ci', function(done) {
var karma = require('karma');
var browserConf = getBrowsersFromCLI(null, true); var browserConf = getBrowsersFromCLI(null, true);
new karma.Server( new karma.Server(
{ {
@ -689,6 +726,8 @@ gulp.task('test.unit.cjs/ci', function(done) {
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) { gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
var watch = require('./tools/build/watch');
printModulesWarning(); printModulesWarning();
treatTestErrorsAsFatal = false; treatTestErrorsAsFatal = false;
watch('modules/**', ['!build.js.cjs', 'test.unit.cjs/ci']); watch('modules/**', ['!build.js.cjs', 'test.unit.cjs/ci']);
@ -696,7 +735,9 @@ gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone
// Use this target to continuously run dartvm unit-tests (such as transformer // Use this target to continuously run dartvm unit-tests (such as transformer
// tests) while coding. Note: these tests do not use Karma. // tests) while coding. Note: these tests do not use Karma.
gulp.task('test.unit.dartvm', function(done) { gulp.task('test.unit.dartvm', function(neverDone) {
var watch = require('./tools/build/watch');
runSequence( runSequence(
'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', 'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!test.unit.dartvm/run', function(error) { '!build/change_detect.dart', '!test.unit.dartvm/run', function(error) {
@ -723,13 +764,11 @@ gulp.task('test.unit.tools/ci', function(done) {
}); });
gulp.task('test.unit.tools', ['build/clean.tools'], function(done) { gulp.task('test.unit.tools', ['build/clean.tools'], function(neverDone) {
var watch = require('./tools/build/watch');
treatTestErrorsAsFatal = false; treatTestErrorsAsFatal = false;
var buildAndTest = ['!build.tools', 'test.unit.tools/ci']; watch(['tools/**', '!tools/**/test-fixtures/**'], ['!build.tools', 'test.unit.tools/ci']);
watch(['tools/**', '!tools/**/test-fixtures/**'], buildAndTest);
}); });
@ -781,6 +820,8 @@ gulp.task('!pre.test.typings.copyTypingsSpec', function() {
}); });
gulp.task('test.typings', gulp.task('test.typings',
['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() { ['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() {
var tsc = require('gulp-typescript');
return gulp.src([tmpdir + '/**']) return gulp.src([tmpdir + '/**'])
.pipe(tsc({ .pipe(tsc({
target: 'ES5', target: 'ES5',
@ -801,9 +842,7 @@ gulp.task('test.typings',
// //
// This task is expected to be run after build/tree.dart // This task is expected to be run after build/tree.dart
gulp.task('build/pure-packages.dart', function() { gulp.task('build/pure-packages.dart', function() {
var through2 = require('through2');
var yaml = require('js-yaml'); var yaml = require('js-yaml');
var originalPrefix = '../../dist/dart/';
return gulp.src([ return gulp.src([
'modules_dart/transform/**/*', 'modules_dart/transform/**/*',
@ -835,6 +874,9 @@ gulp.task('build.tools', ['build/clean.tools'],
// private task to build tools // private task to build tools
gulp.task('!build.tools', function() { gulp.task('!build.tools', function() {
var sourcemaps = require('gulp-sourcemaps');
var tsc = require('gulp-typescript');
var stream = gulp.src(['tools/**/*.ts']) var stream = gulp.src(['tools/**/*.ts'])
.pipe(sourcemaps.init()) .pipe(sourcemaps.init())
.pipe(tsc({ .pipe(tsc({
@ -925,12 +967,13 @@ var bundleConfig = {
// production build // production build
gulp.task('!bundle.js.prod', ['build.js.prod'], function() { gulp.task('!bundle.js.prod', ['build.js.prod'], function() {
var bundler = require('./tools/build/bundle');
var bundlerConfig = {sourceMaps: true}; var bundlerConfig = {sourceMaps: true};
return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.js', return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.js',
bundlerConfig) bundlerConfig)
.then(function() { .then(function() {
return q.all([ return Promise.all([
bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2', './dist/build/http.js', bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2', './dist/build/http.js',
bundlerConfig), bundlerConfig),
bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2',
@ -941,12 +984,13 @@ gulp.task('!bundle.js.prod', ['build.js.prod'], function() {
// minified production build // minified production build
gulp.task('!bundle.js.min', ['build.js.prod'], function() { gulp.task('!bundle.js.min', ['build.js.prod'], function() {
var bundler = require('./tools/build/bundle');
var bundlerConfig = {sourceMaps: true, minify: true}; var bundlerConfig = {sourceMaps: true, minify: true};
return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.min.js', return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.min.js',
bundlerConfig) bundlerConfig)
.then(function() { .then(function() {
return q.all([ return Promise.all([
bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2', bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2',
'./dist/build/http.min.js', bundlerConfig), './dist/build/http.min.js', bundlerConfig),
bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2',
@ -957,6 +1001,7 @@ gulp.task('!bundle.js.min', ['build.js.prod'], function() {
// development build // development build
gulp.task('!bundle.js.dev', ['build.js.dev'], function() { gulp.task('!bundle.js.dev', ['build.js.dev'], function() {
var bundler = require('./tools/build/bundle');
var bundlerConfig = {sourceMaps: true}; var bundlerConfig = {sourceMaps: true};
var devBundleConfig = merge(true, bundleConfig); var devBundleConfig = merge(true, bundleConfig);
@ -965,7 +1010,7 @@ gulp.task('!bundle.js.dev', ['build.js.dev'], function() {
return bundler.bundle(devBundleConfig, 'angular2/angular2', './dist/build/angular2.dev.js', return bundler.bundle(devBundleConfig, 'angular2/angular2', './dist/build/angular2.dev.js',
bundlerConfig) bundlerConfig)
.then(function() { .then(function() {
return q.all([ return Promise.all([
bundler.bundle(devBundleConfig, 'angular2/http - angular2/angular2', bundler.bundle(devBundleConfig, 'angular2/http - angular2/angular2',
'./dist/build/http.dev.js', bundlerConfig), './dist/build/http.dev.js', bundlerConfig),
bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2',
@ -976,8 +1021,11 @@ gulp.task('!bundle.js.dev', ['build.js.dev'], function() {
// WebWorker build // WebWorker build
gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() { gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() {
var bundler = require('./tools/build/bundle');
var devBundleConfig = merge(true, bundleConfig); var devBundleConfig = merge(true, bundleConfig);
devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"}); devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"});
return bundler.bundle(devBundleConfig, 'angular2/web_worker/ui', return bundler.bundle(devBundleConfig, 'angular2/web_worker/ui',
'./dist/build/web_worker/ui.dev.js', {sourceMaps: true}) './dist/build/web_worker/ui.dev.js', {sourceMaps: true})
.then(function() { .then(function() {
@ -987,8 +1035,11 @@ gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() {
}); });
gulp.task('!bundle.testing', ['build.js.dev'], function() { gulp.task('!bundle.testing', ['build.js.dev'], function() {
var bundler = require('./tools/build/bundle');
var devBundleConfig = merge(true, bundleConfig); var devBundleConfig = merge(true, bundleConfig);
devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"}); devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"});
return bundler.bundle(devBundleConfig, 'angular2/testing - angular2/angular2', return bundler.bundle(devBundleConfig, 'angular2/testing - angular2/angular2',
'./dist/js/bundle/testing.js', {sourceMaps: true}); './dist/js/bundle/testing.js', {sourceMaps: true});
}); });
@ -999,14 +1050,18 @@ gulp.task('!bundle.testing', ['build.js.dev'], function() {
// use System loader polyfills (like system.js and es6 loader). // use System loader polyfills (like system.js and es6 loader).
// see: https://github.com/systemjs/builder (SFX bundles). // see: https://github.com/systemjs/builder (SFX bundles).
gulp.task('!bundle.js.sfx.dev', ['build.js.dev'], function() { gulp.task('!bundle.js.sfx.dev', ['build.js.dev'], function() {
var bundler = require('./tools/build/bundle');
var devBundleConfig = merge(true, bundleConfig); var devBundleConfig = merge(true, bundleConfig);
devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'}); devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'});
return bundler.bundle(devBundleConfig, 'angular2/angular2_sfx', return bundler.bundle(devBundleConfig, 'angular2/angular2_sfx',
'./dist/build/angular2.sfx.dev.js', {sourceMaps: true}, './dist/build/angular2.sfx.dev.js', {sourceMaps: true},
/* self-executing */ true); /* self-executing */ true);
}); });
gulp.task('!bundles.js.umd', ['build.js.dev'], function() { gulp.task('!bundles.js.umd', ['build.js.dev'], function() {
var q = require('q');
var webpack = q.denodeify(require('webpack')); var webpack = q.denodeify(require('webpack'));
function resolveOptions(devOrProd) { function resolveOptions(devOrProd) {
@ -1046,6 +1101,9 @@ gulp.task('!bundles.js.umd', ['build.js.dev'], function() {
}); });
gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.external.deps'], function() { gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.external.deps'], function() {
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
// minify production bundles // minify production bundles
return gulp.src([ return gulp.src([
'dist/js/bundle/external-dependencies.js', 'dist/js/bundle/external-dependencies.js',
@ -1058,6 +1116,8 @@ gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.external.deps'], fu
}); });
gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() { gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() {
var bundler = require('./tools/build/bundle');
return merge2(addDevDependencies('angular2.js'), return merge2(addDevDependencies('angular2.js'),
bundler.modify(['dist/build/http.js'], 'http.js'), bundler.modify(['dist/build/http.js'], 'http.js'),
bundler.modify(['dist/build/router.js'], 'router.js')) bundler.modify(['dist/build/router.js'], 'router.js'))
@ -1065,6 +1125,9 @@ gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() {
}); });
gulp.task('!bundle.js.min.deps', ['!bundle.js.min'], function() { gulp.task('!bundle.js.min.deps', ['!bundle.js.min'], function() {
var bundler = require('./tools/build/bundle');
var uglify = require('gulp-uglify');
return merge2(addDevDependencies('angular2.min.js'), return merge2(addDevDependencies('angular2.min.js'),
bundler.modify(['dist/build/http.min.js'], 'http.min.js'), bundler.modify(['dist/build/http.min.js'], 'http.min.js'),
bundler.modify(['dist/build/router.min.js'], 'router.min.js')) bundler.modify(['dist/build/router.min.js'], 'router.min.js'))
@ -1095,12 +1158,17 @@ function insertRXLicense(source) {
} }
function addDevDependencies(outputFile) { function addDevDependencies(outputFile) {
var bundler = require('./tools/build/bundle');
var insert = require('gulp-insert');
return bundler.modify(JS_DEV_DEPS.concat(['dist/build/' + outputFile]), outputFile) return bundler.modify(JS_DEV_DEPS.concat(['dist/build/' + outputFile]), outputFile)
.pipe(insert.transform(insertRXLicense)) .pipe(insert.transform(insertRXLicense))
.pipe(gulp.dest('dist/js/bundle')); .pipe(gulp.dest('dist/js/bundle'));
} }
gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() { gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() {
var bundler = require('./tools/build/bundle');
return merge2(addDevDependencies('angular2.dev.js'), return merge2(addDevDependencies('angular2.dev.js'),
bundler.modify(['dist/build/http.dev.js'], 'http.dev.js'), bundler.modify(['dist/build/http.dev.js'], 'http.dev.js'),
bundler.modify(['dist/build/router.dev.js'], 'router.dev.js')) bundler.modify(['dist/build/router.dev.js'], 'router.dev.js'))
@ -1108,6 +1176,8 @@ gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() {
}); });
gulp.task('!bundle.js.sfx.dev.deps', ['!bundle.js.sfx.dev'], function() { gulp.task('!bundle.js.sfx.dev.deps', ['!bundle.js.sfx.dev'], function() {
var bundler = require('./tools/build/bundle');
return bundler.modify(JS_DEV_DEPS.concat(['dist/build/angular2.sfx.dev.js']), return bundler.modify(JS_DEV_DEPS.concat(['dist/build/angular2.sfx.dev.js']),
'angular2.sfx.dev.js') 'angular2.sfx.dev.js')
.pipe(gulp.dest('dist/js/bundle')); .pipe(gulp.dest('dist/js/bundle'));
@ -1157,10 +1227,14 @@ gulp.task('build', ['build.js', 'build.dart']);
// ------------ // ------------
// transform codegen // transform codegen
gulp.task('lint_protos.dart', function(done) { gulp.task('lint_protos.dart', function(done) {
var proto = require('./tools/build/proto');
return proto.lint({dir: 'modules_dart/transform/lib/src/transform/common/model/'}, done); return proto.lint({dir: 'modules_dart/transform/lib/src/transform/common/model/'}, done);
}); });
gulp.task('gen_protos.dart', function(done) { gulp.task('gen_protos.dart', function(done) {
var proto = require('./tools/build/proto');
return proto.generate( return proto.generate(
{ {
dir: 'modules_dart/transform/lib/src/transform/common/model/', dir: 'modules_dart/transform/lib/src/transform/common/model/',
@ -1177,6 +1251,8 @@ gulp.task('build.change_detect.dart', function(done) {
gulp.task('!build/change_detect.dart', function(done) { gulp.task('!build/change_detect.dart', function(done) {
var fs = require('fs'); var fs = require('fs');
var spawn = require('child_process').spawn;
var changeDetectDir = path.join(CONFIG.dest.dart, 'angular2/test/core/change_detection/'); var changeDetectDir = path.join(CONFIG.dest.dart, 'angular2/test/core/change_detection/');
var srcDir = path.join(changeDetectDir, 'generator'); var srcDir = path.join(changeDetectDir, 'generator');
var destDir = path.join(changeDetectDir, 'generated'); var destDir = path.join(changeDetectDir, 'generated');
@ -1198,6 +1274,9 @@ gulp.task('!build/change_detect.dart', function(done) {
// ------------ // ------------
// angular material testing rules // angular material testing rules
gulp.task('build.css.material', function() { gulp.task('build.css.material', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('modules/*/src/**/*.scss') return gulp.src('modules/*/src/**/*.scss')
.pipe(sass()) .pipe(sass())
.pipe(autoprefixer()) .pipe(autoprefixer())
@ -1216,6 +1295,9 @@ gulp.task('build.dart2js.material', function(done) {
}); });
gulp.task('build.dart.material.css', function() { gulp.task('build.dart.material.css', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('dist/dart/angular2_material/src/**/*.scss') return gulp.src('dist/dart/angular2_material/src/**/*.scss')
.pipe(sass()) .pipe(sass())
.pipe(autoprefixer()) .pipe(autoprefixer())
@ -1229,6 +1311,8 @@ gulp.task('build.dart.material', ['build/packages.dart'], function(done) {
gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); }); gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); });
gulp.task('benchpress.bundle', ['build/clean.benchpress.bundle', 'build.js.cjs'], function(cb) { gulp.task('benchpress.bundle', ['build/clean.benchpress.bundle', 'build.js.cjs'], function(cb) {
var bundler = require('./tools/build/bundle');
bundler.benchpressBundle(BENCHPRESS_BUNDLE_CONFIG.entries, BENCHPRESS_BUNDLE_CONFIG.packageJson, bundler.benchpressBundle(BENCHPRESS_BUNDLE_CONFIG.entries, BENCHPRESS_BUNDLE_CONFIG.packageJson,
BENCHPRESS_BUNDLE_CONFIG.includes, BENCHPRESS_BUNDLE_CONFIG.excludes, BENCHPRESS_BUNDLE_CONFIG.includes, BENCHPRESS_BUNDLE_CONFIG.excludes,
BENCHPRESS_BUNDLE_CONFIG.ignore, BENCHPRESS_BUNDLE_CONFIG.dest, cb); BENCHPRESS_BUNDLE_CONFIG.ignore, BENCHPRESS_BUNDLE_CONFIG.dest, cb);

View File

@ -9,114 +9,111 @@ var util = require('./util');
var yaml = require('js-yaml'); var yaml = require('js-yaml');
module.exports = function(gulp, plugins, config) { module.exports = function(gulp, plugins, config) {
return function() { var travisFoldEnd = travisFoldStart(`dartanalyzer-${config.use_ddc ? 'ddc' : ''}-${config.dest}`);
var travisFoldEnd = travisFoldStart(`dartanalyzer-${config.use_ddc ? 'ddc' : ''}-${config.dest}`); var tempFile = '_analyzer.dart';
var tempFile = '_analyzer.dart';
return util.forEachSubDirSequential(config.dest, function(dir) { return util.forEachSubDirSequential(config.dest, function(dir) {
var pubspecContents = fs.readFileSync(path.join(dir, 'pubspec.yaml')); var pubspecContents = fs.readFileSync(path.join(dir, 'pubspec.yaml'));
var pubspec = yaml.safeLoad(pubspecContents); var pubspec = yaml.safeLoad(pubspecContents);
var packageName = pubspec.name; var packageName = pubspec.name;
var libFiles = [].slice.call(glob.sync('lib/**/*.dart', {cwd: dir})); var libFiles = [].slice.call(glob.sync('lib/**/*.dart', {cwd: dir}));
var webFiles = [].slice.call(glob.sync('web/**/*.dart', {cwd: dir})); var webFiles = [].slice.call(glob.sync('web/**/*.dart', {cwd: dir}));
var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {cwd: dir})); var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {cwd: dir}));
var analyzeFile = ['library _analyzer;']; var analyzeFile = ['library _analyzer;'];
libFiles.concat(testFiles).concat(webFiles).forEach(function(fileName, index) { libFiles.concat(testFiles).concat(webFiles).forEach(function(fileName, index) {
if (fileName !== tempFile && fileName.indexOf("/packages/") === -1) { if (fileName !== tempFile && fileName.indexOf("/packages/") === -1) {
if (fileName.indexOf('lib') == 0) { if (fileName.indexOf('lib') == 0) {
fileName = 'package:' + packageName + '/' + path.relative('lib', fileName).replace(/\\/g, '/'); fileName = 'package:' + packageName + '/' +
} path.relative('lib', fileName).replace(/\\/g, '/');
analyzeFile.push('import "' + fileName + '" as mod' + index + ';'); }
} analyzeFile.push('import "' + fileName + '" as mod' + index + ';');
}); }
fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n')); });
var defer = Q.defer(); fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n'));
if (config.use_ddc) { var defer = Q.defer();
analyze(dir, defer.makeNodeResolver(), true); if (config.use_ddc) {
} else { analyze(dir, defer.makeNodeResolver(), true);
analyze(dir, defer.makeNodeResolver()); } else {
} analyze(dir, defer.makeNodeResolver());
return defer.promise; }
}).then(travisFoldEnd); return defer.promise;
}).then(travisFoldEnd);
function analyze(dirName, done, useDdc) { function analyze(dirName, done, useDdc) {
// TODO remove --package-warnings once dartanalyzer handles transitive libraries // TODO remove --package-warnings once dartanalyzer handles transitive libraries
var flags = ['--fatal-warnings', '--package-warnings', '--format=machine']; var flags = ['--fatal-warnings', '--package-warnings', '--format=machine'];
if (useDdc) { if (useDdc) {
console.log('Using DDC analyzer to analyze', dirName); console.log('Using DDC analyzer to analyze', dirName);
flags.push('--strong'); flags.push('--strong');
}
var args = flags.concat(tempFile);
var stream = spawn(config.command, args, {
// inherit stdin and stderr, but filter stdout
stdio: [process.stdin, process.stdout, 'pipe'],
cwd: dirName
});
// Filter out unused imports from our generated file.
// We don't reexports from the generated file
// as this could lead to name clashes when two files
// export the same thing.
var rl = readline.createInterface(
{input: stream.stderr, output: process.stdout, terminal: false});
var hintCount = 0;
var errorCount = 0;
var warningCount = 0;
rl.on('line', function(line) {
if (line == "find: > bin [: No such file or directory") {
//Skip bad output from Dart SDK .bat files on Windows
return;
}
var parsedLine = _AnalyzerOutputLine.parse(line);
if (!parsedLine) {
errorCount++;
console.log('Unexpected output: ' + line);
return;
}
// TODO remove once dartanalyzer handles transitive libraries
// skip errors in third-party packages
if (parsedLine.sourcePath.indexOf(dirName) == -1) {
return;
}
if (parsedLine.shouldIgnore()) {
return;
}
if (parsedLine.isHint) {
hintCount++;
} else if (parsedLine.isWarning) {
warningCount++;
} else {
errorCount++;
}
console.log(dirName + ':' + parsedLine);
});
stream.on('close', function() {
var error;
var report = [];
if (errorCount > 0) {
report.push(errorCount + ' error(s)');
}
if (warningCount > 0) {
report.push(warningCount + ' warning(s)');
}
if (hintCount > 0) {
report.push(hintCount + ' hint(s)');
}
if (report.length > 0) {
error = 'Dartanalyzer showed ' + report.join(', ');
}
done(error);
});
stream.on('error', function(error) {
done(error);
});
} }
};
var args = flags.concat(tempFile);
var stream = spawn(config.command, args, {
// inherit stdin and stderr, but filter stdout
stdio: [process.stdin, process.stdout, 'pipe'],
cwd: dirName
});
// Filter out unused imports from our generated file.
// We don't reexports from the generated file
// as this could lead to name clashes when two files
// export the same thing.
var rl =
readline.createInterface({input: stream.stderr, output: process.stdout, terminal: false});
var hintCount = 0;
var errorCount = 0;
var warningCount = 0;
rl.on('line', function(line) {
if (line == "find: > bin [: No such file or directory") {
// Skip bad output from Dart SDK .bat files on Windows
return;
}
var parsedLine = _AnalyzerOutputLine.parse(line);
if (!parsedLine) {
errorCount++;
console.log('Unexpected output: ' + line);
return;
}
// TODO remove once dartanalyzer handles transitive libraries
// skip errors in third-party packages
if (parsedLine.sourcePath.indexOf(dirName) == -1) {
return;
}
if (parsedLine.shouldIgnore()) {
return;
}
if (parsedLine.isHint) {
hintCount++;
} else if (parsedLine.isWarning) {
warningCount++;
} else {
errorCount++;
}
console.log(dirName + ':' + parsedLine);
});
stream.on('close', function() {
var error;
var report = [];
if (errorCount > 0) {
report.push(errorCount + ' error(s)');
}
if (warningCount > 0) {
report.push(warningCount + ' warning(s)');
}
if (hintCount > 0) {
report.push(hintCount + ' hint(s)');
}
if (report.length > 0) {
error = 'Dartanalyzer showed ' + report.join(', ');
}
done(error);
});
stream.on('error', function(error) { done(error); });
}
}; };
// See https://github.com/dart-lang/analyzer_cli/blob/master/lib/src/error_formatter.dart // See https://github.com/dart-lang/analyzer_cli/blob/master/lib/src/error_formatter.dart

View File

@ -5,41 +5,35 @@ var util = require('./util');
module.exports = function(gulp, plugins, config) { module.exports = function(gulp, plugins, config) {
config.output = config.output || 'doc/api'; config.output = config.output || 'doc/api';
return function() { return util.forEachSubDirSequential(config.dest, function(dir) {
return util.forEachSubDirSequential(config.dest, function(dir) { var defer = Q.defer();
var defer = Q.defer(); var done = defer.makeNodeResolver();
var done = defer.makeNodeResolver();
var supportedModules = [ var supportedModules = [
'dist/dart/angular2', 'dist/dart/angular2',
// TODO: blocked by https://github.com/angular/angular/issues/3518 // TODO: blocked by https://github.com/angular/angular/issues/3518
// 'dist/dart/angular2_material', // 'dist/dart/angular2_material',
'dist/dart/benchpress' 'dist/dart/benchpress'
]; ];
if (supportedModules.indexOf(dir) === -1) { if (supportedModules.indexOf(dir) === -1) {
done(); done();
} else { } else {
console.log('INFO: running dartdoc for ', dir); console.log('INFO: running dartdoc for ', dir);
var stream = spawn(config.command, ['--input=.', '--output=' + config.output], { var stream = spawn(config.command, ['--input=.', '--output=' + config.output],
stdio: [process.stdin, process.stdout, process.stderr], {stdio: [process.stdin, process.stdout, process.stderr], cwd: dir});
cwd: dir
});
stream.on('exit', function(code) { stream.on('exit', function(code) {
if (code !== 0) { if (code !== 0) {
done('ERROR: dartdoc exited with non-zero status ' + code); done('ERROR: dartdoc exited with non-zero status ' + code);
} else { } else {
done(); done();
} }
}); });
stream.on('error', function(e) { stream.on('error', function(e) { done('ERROR: dartdoc reported error: ' + e); });
done('ERROR: dartdoc reported error: ' + e); }
}); return defer.promise;
} });
return defer.promise;
});
};
}; };