diff --git a/gulpfile.js b/gulpfile.js index 03b25d1a58..99c708c083 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -58,13 +58,14 @@ if (cliArgs.projects) { // --projects=angular2,angular2_material => {angular2: true, angular2_material: true} var allProjects = - 'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground'; + 'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,bundle_deps'; var cliArgsProjects = (cliArgs.projects || allProjects) .split(',') .reduce((map, projectName) => { map[projectName] = true; return map; }, {}); +var generateEs6 = !cliArgs.projects; function printModulesWarning() { if (!cliArgs.projects && !process.env.CI) { @@ -302,11 +303,11 @@ gulp.task('lint', ['build.tools'], function() { // ------------ // check circular dependencies in Node.js context gulp.task('build/checkCircularDependencies', function(done) { - var dependencyObject = madge(CONFIG.dest.js.dev.es6, { - format: 'es6', - paths: [CONFIG.dest.js.dev.es6], + var dependencyObject = madge(CONFIG.dest.js.dev.es5, { + format: 'cjs', + paths: [CONFIG.dest.js.dev.es5], extensions: ['.js'], - onParseFile: function(data) { data.src = data.src.replace(/import \* as/g, "//import * as"); } + onParseFile: function(data) { data.src = data.src.replace(/\/\* circular \*\//g, "//"); } }); var circularDependencies = dependencyObject.circular().getArray(); if (circularDependencies.length > 0) { @@ -841,11 +842,15 @@ gulp.task('!build.tools', function() { gulp.task('broccoli.js.dev', ['build.tools'], function(done) { runSequence('!broccoli.js.dev', sequenceComplete(done)); }); -gulp.task('!broccoli.js.dev', - () => { return angularBuilder.rebuildBrowserDevTree(cliArgsProjects); }); +gulp.task( + '!broccoli.js.dev', + () => angularBuilder.rebuildBrowserDevTree( + {generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks})); -gulp.task('!broccoli.js.prod', - function() { return angularBuilder.rebuildBrowserProdTree(cliArgsProjects); }); +gulp.task( + '!broccoli.js.prod', + () => angularBuilder.rebuildBrowserProdTree( + {generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks})); gulp.task('build.js.dev', ['build/clean.js'], function(done) { runSequence('broccoli.js.dev', 'build.css.material', sequenceComplete(done)); @@ -868,7 +873,9 @@ var firstBuildJsCjs = true; * private task */ gulp.task('!build.js.cjs', function() { - return angularBuilder.rebuildNodeTree(cliArgsProjects) + return angularBuilder + .rebuildNodeTree( + {generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks}) .then(function() { if (firstBuildJsCjs) { firstBuildJsCjs = false; diff --git a/modules/angular2/src/common/forms/directives/checkbox_value_accessor.ts b/modules/angular2/src/common/forms/directives/checkbox_value_accessor.ts index 2e886a5dbb..2958d70b84 100644 --- a/modules/angular2/src/common/forms/directives/checkbox_value_accessor.ts +++ b/modules/angular2/src/common/forms/directives/checkbox_value_accessor.ts @@ -5,7 +5,6 @@ import {Self, forwardRef, Provider} from 'angular2/src/core/di'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'; import {CONST_EXPR} from 'angular2/src/facade/lang'; -import {setProperty} from './shared'; const CHECKBOX_VALUE_ACCESSOR = CONST_EXPR(new Provider( NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => CheckboxControlValueAccessor), multi: true})); @@ -30,7 +29,9 @@ export class CheckboxControlValueAccessor implements ControlValueAccessor { constructor(private _renderer: Renderer, private _elementRef: ElementRef) {} - writeValue(value: any): void { setProperty(this._renderer, this._elementRef, "checked", value); } + writeValue(value: any): void { + this._renderer.setElementProperty(this._elementRef, 'checked', value); + } registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; } registerOnTouched(fn: () => {}): void { this.onTouched = fn; } } diff --git a/modules/angular2/src/common/forms/directives/default_value_accessor.ts b/modules/angular2/src/common/forms/directives/default_value_accessor.ts index 836ee088b3..970270bbca 100644 --- a/modules/angular2/src/common/forms/directives/default_value_accessor.ts +++ b/modules/angular2/src/common/forms/directives/default_value_accessor.ts @@ -4,7 +4,6 @@ import {Renderer} from 'angular2/src/core/render'; import {Self, forwardRef, Provider} from 'angular2/src/core/di'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'; import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang'; -import {setProperty} from './shared'; const DEFAULT_VALUE_ACCESSOR = CONST_EXPR(new Provider( NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => DefaultValueAccessor), multi: true})); @@ -39,9 +38,9 @@ export class DefaultValueAccessor implements ControlValueAccessor { writeValue(value: any): void { var normalizedValue = isBlank(value) ? '' : value; - setProperty(this._renderer, this._elementRef, 'value', normalizedValue); + this._renderer.setElementProperty(this._elementRef, 'value', normalizedValue); } registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } -} +} \ No newline at end of file diff --git a/modules/angular2/src/common/forms/directives/number_value_accessor.ts b/modules/angular2/src/common/forms/directives/number_value_accessor.ts index 82c5caac46..d3dd233ff3 100644 --- a/modules/angular2/src/common/forms/directives/number_value_accessor.ts +++ b/modules/angular2/src/common/forms/directives/number_value_accessor.ts @@ -4,7 +4,6 @@ import {Renderer} from 'angular2/src/core/render'; import {Self, forwardRef, Provider} from 'angular2/src/core/di'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'; import {isBlank, CONST_EXPR, NumberWrapper} from 'angular2/src/facade/lang'; -import {setProperty} from './shared'; const NUMBER_VALUE_ACCESSOR = CONST_EXPR(new Provider( NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => NumberValueAccessor), multi: true})); @@ -34,7 +33,9 @@ export class NumberValueAccessor implements ControlValueAccessor { constructor(private _renderer: Renderer, private _elementRef: ElementRef) {} - writeValue(value: number): void { setProperty(this._renderer, this._elementRef, 'value', value); } + writeValue(value: number): void { + this._renderer.setElementProperty(this._elementRef, 'value', value); + } registerOnChange(fn: (_: number) => void): void { this.onChange = (value) => { fn(NumberWrapper.parseFloat(value)); }; diff --git a/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts b/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts index b27e66dc4c..2fe478a309 100644 --- a/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts +++ b/modules/angular2/src/common/forms/directives/select_control_value_accessor.ts @@ -6,7 +6,6 @@ import {Query, Directive} from 'angular2/src/core/metadata'; import {ObservableWrapper} from 'angular2/src/facade/async'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'; import {CONST_EXPR} from 'angular2/src/facade/lang'; -import {setProperty} from './shared'; const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider( NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SelectControlValueAccessor), multi: true})); @@ -50,7 +49,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor { writeValue(value: any): void { this.value = value; - setProperty(this._renderer, this._elementRef, "value", value); + this._renderer.setElementProperty(this._elementRef, 'value', value); } registerOnChange(fn: () => any): void { this.onChange = fn; } diff --git a/modules/angular2/src/common/forms/directives/shared.ts b/modules/angular2/src/common/forms/directives/shared.ts index e0f753dd88..a0a5bb53ec 100644 --- a/modules/angular2/src/common/forms/directives/shared.ts +++ b/modules/angular2/src/common/forms/directives/shared.ts @@ -9,8 +9,6 @@ import {NgControlGroup} from './ng_control_group'; import {Control, ControlGroup} from '../model'; import {Validators} from '../validators'; import {ControlValueAccessor} from './control_value_accessor'; -import {ElementRef, QueryList} from 'angular2/src/core/linker'; -import {Renderer} from 'angular2/src/core/render'; import {DefaultValueAccessor} from './default_value_accessor'; import {NumberValueAccessor} from './number_value_accessor'; import {CheckboxControlValueAccessor} from './checkbox_value_accessor'; @@ -57,11 +55,6 @@ function _throwError(dir: AbstractControlDirective, message: string): void { throw new BaseException(`${message} '${path}'`); } -export function setProperty(renderer: Renderer, elementRef: ElementRef, propName: string, - propValue: any) { - renderer.setElementProperty(elementRef, propName, propValue); -} - export function composeValidators(validators: /* Array */ any[]): Function { return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null; } diff --git a/modules/angular2/src/core/linker/element_injector.ts b/modules/angular2/src/core/linker/element_injector.ts index b684eef96c..13c210c49b 100644 --- a/modules/angular2/src/core/linker/element_injector.ts +++ b/modules/angular2/src/core/linker/element_injector.ts @@ -34,8 +34,8 @@ import {resolveProvider, ResolvedFactory, ResolvedProvider_} from 'angular2/src/ import {AttributeMetadata, QueryMetadata} from '../metadata/di'; -import * as viewModule from './view'; -import * as avmModule from './view_manager'; +import {AppViewContainer, AppView} from './view'; +/* circular */ import * as avmModule from './view_manager'; import {ViewContainerRef} from './view_container_ref'; import {ElementRef} from './element_ref'; import {TemplateRef} from './template_ref'; @@ -183,8 +183,8 @@ export class DirectiveProvider extends ResolvedProvider_ { // TODO(rado): benchmark and consider rolling in as ElementInjector fields. export class PreBuiltObjects { - nestedView: viewModule.AppView = null; - constructor(public viewManager: avmModule.AppViewManager, public view: viewModule.AppView, + nestedView: AppView = null; + constructor(public viewManager: avmModule.AppViewManager, public view: AppView, public elementRef: ElementRef, public templateRef: TemplateRef) {} } @@ -195,7 +195,7 @@ export class QueryMetadataWithSetter { export class EventEmitterAccessor { constructor(public eventName: string, public getter: Function) {} - subscribe(view: viewModule.AppView, boundElementIndex: number, directive: Object): Object { + subscribe(view: AppView, boundElementIndex: number, directive: Object): Object { var eventEmitter = this.getter(directive); return ObservableWrapper.subscribe( eventEmitter, @@ -235,7 +235,7 @@ function _createProtoQueryRefs(providers: ProviderWithVisibility[]): ProtoQueryR } export class ProtoElementInjector { - view: viewModule.AppView; + view: AppView; attributes: Map; eventEmitterAccessors: EventEmitterAccessor[][]; protoQueryRefs: ProtoQueryRef[]; @@ -451,9 +451,9 @@ export class ElementInjector extends TreeNode implements Depend return new ViewContainerRef_(this._preBuiltObjects.viewManager, this.getElementRef()); } - getNestedView(): viewModule.AppView { return this._preBuiltObjects.nestedView; } + getNestedView(): AppView { return this._preBuiltObjects.nestedView; } - getView(): viewModule.AppView { return this._preBuiltObjects.view; } + getView(): AppView { return this._preBuiltObjects.view; } directParent(): ElementInjector { return this._proto.distanceToParent < 2 ? this.parent : null; } @@ -1044,13 +1044,13 @@ export class QueryRef { } } - private _visitViewContainer(vc: viewModule.AppViewContainer, aggregator: any[]) { + private _visitViewContainer(vc: AppViewContainer, aggregator: any[]) { for (var j = 0; j < vc.views.length; j++) { this._visitView(vc.views[j], aggregator); } } - private _visitView(view: viewModule.AppView, aggregator: any[]) { + private _visitView(view: AppView, aggregator: any[]) { for (var i = view.elementOffset; i < view.elementOffset + view.ownBindersCount; i++) { var inj = view.elementInjectors[i]; if (isBlank(inj)) continue; diff --git a/tools/broccoli/angular_builder.ts b/tools/broccoli/angular_builder.ts index 699c3d6a02..0f35cc50d5 100644 --- a/tools/broccoli/angular_builder.ts +++ b/tools/broccoli/angular_builder.ts @@ -11,6 +11,13 @@ type ProjectMap = { [key: string]: boolean }; +type Options = { + projects: ProjectMap; +noTypeChecks: boolean; +generateEs6: boolean; +} +; + /** * BroccoliBuilder facade for all of our build pipelines. */ @@ -25,20 +32,20 @@ export class AngularBuilder { constructor(public options: AngularBuilderOptions) { this.outputPath = options.outputPath; } - public rebuildBrowserDevTree(projects: ProjectMap): Promise { - this.browserDevBuilder = this.browserDevBuilder || this.makeBrowserDevBuilder(projects); + public rebuildBrowserDevTree(opts: Options): Promise { + this.browserDevBuilder = this.browserDevBuilder || this.makeBrowserDevBuilder(opts); return this.rebuild(this.browserDevBuilder, 'js.dev'); } - public rebuildBrowserProdTree(projects: ProjectMap): Promise { - this.browserProdBuilder = this.browserProdBuilder || this.makeBrowserProdBuilder(projects); + public rebuildBrowserProdTree(opts: Options): Promise { + this.browserProdBuilder = this.browserProdBuilder || this.makeBrowserProdBuilder(opts); return this.rebuild(this.browserProdBuilder, 'js.prod'); } - public rebuildNodeTree(projects: ProjectMap): Promise { - this.nodeBuilder = this.nodeBuilder || this.makeNodeBuilder(projects); + public rebuildNodeTree(opts: Options): Promise { + this.nodeBuilder = this.nodeBuilder || this.makeNodeBuilder(opts.projects); return this.rebuild(this.nodeBuilder, 'js.cjs'); } @@ -58,16 +65,30 @@ export class AngularBuilder { } - private makeBrowserDevBuilder(projects: ProjectMap): BroccoliBuilder { - let tree = makeBrowserTree({name: 'dev', typeAssertions: true, projects: projects}, - path.join(this.outputPath, 'js', 'dev')); + private makeBrowserDevBuilder(opts: Options): BroccoliBuilder { + let tree = makeBrowserTree( + { + name: 'dev', + typeAssertions: true, + projects: opts.projects, + noTypeChecks: opts.noTypeChecks, + generateEs6: opts.generateEs6 + }, + path.join(this.outputPath, 'js', 'dev')); return new broccoli.Builder(tree); } - private makeBrowserProdBuilder(projects: ProjectMap): BroccoliBuilder { - let tree = makeBrowserTree({name: 'prod', typeAssertions: false, projects: projects}, - path.join(this.outputPath, 'js', 'prod')); + private makeBrowserProdBuilder(opts: Options): BroccoliBuilder { + let tree = makeBrowserTree( + { + name: 'prod', + typeAssertions: false, + projects: opts.projects, + noTypeChecks: opts.noTypeChecks, + generateEs6: opts.generateEs6 + }, + path.join(this.outputPath, 'js', 'prod')); return new broccoli.Builder(tree); } @@ -128,11 +149,14 @@ function broccoliNodeToBuildNode(broccoliNode) { return new BuildNode(tree.description || tree.constructor.name, tree.inputPath ? [tree.inputPath] : tree.inputPaths, tree.cachePath, - tree.outputPath, broccoliNode.subtrees.map(broccoliNodeToBuildNode)); + tree.outputPath, broccoliNode.selfTime / (1000 * 1000 * 1000), + broccoliNode.totalTime / (1000 * 1000 * 1000), + broccoliNode.subtrees.map(broccoliNodeToBuildNode)); } class BuildNode { constructor(public pluginName: string, public inputPaths: string[], public cachePath: string, - public outputPath: string, public inputNodes: BroccoliNode[]) {} + public outputPath: string, public selfTime: number, public totalTime: number, + public inputNodes: BroccoliNode[]) {} } diff --git a/tools/broccoli/trees/browser_tree.ts b/tools/broccoli/trees/browser_tree.ts index 2685d0fd1e..c72665954b 100644 --- a/tools/broccoli/trees/browser_tree.ts +++ b/tools/broccoli/trees/browser_tree.ts @@ -70,7 +70,9 @@ const kServedPaths = [ module.exports = function makeBrowserTree(options, destinationPath) { - var modules = options.projects; + const modules = options.projects; + const noTypeChecks = options.noTypeChecks; + const generateEs6 = options.generateEs6; if (modules.angular2) { var angular2Tree = new Funnel('modules/angular2', { @@ -110,9 +112,6 @@ module.exports = function makeBrowserTree(options, destinationPath) { var modulesTree = mergeTrees( [angular2Tree, angular2MaterialTree, benchmarksTree, benchmarksExternalTree, playgroundTree]); - var clientModules = new Funnel( - 'node_modules', {include: ['@reactivex/**/**', 'parse5/**/**', 'css/**/**'], destDir: '/'}); - var es6PolyfillTypings = new Funnel('modules', {include: ['angular2/typings/es6-*/**'], destDir: '/'}); @@ -139,20 +138,6 @@ module.exports = function makeBrowserTree(options, destinationPath) { patterns: [{match: /\$SCRIPTS\$/, replacement: jsReplace('SCRIPTS')}] }); - // Use TypeScript to transpile the *.ts files to ES6 - var es6Tree = compileWithTypescript(modulesTree, { - declaration: false, - emitDecoratorMetadata: true, - experimentalDecorators: true, - mapRoot: '', // force sourcemaps to use relative path - noEmitOnError: false, - rootDir: './', - rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'], - sourceMap: true, - sourceRoot: '.', - target: 'es6' - }); - // Use TypeScript to transpile the *.ts files to ES5 var es5Tree = compileWithTypescript(es5ModulesTree, { declaration: false, @@ -161,7 +146,7 @@ module.exports = function makeBrowserTree(options, destinationPath) { mapRoot: '', // force sourcemaps to use relative path module: 'commonjs', moduleResolution: 'classic', - noEmitOnError: true, + noEmitOnError: !noTypeChecks, rootDir: './', rootFilePaths: ['angular2/manual_typings/globals.d.ts'], sourceMap: true, @@ -274,10 +259,32 @@ module.exports = function makeBrowserTree(options, destinationPath) { htmlTree = mergeTrees([htmlTree, scripts, polymer, react]); } - es5Tree = mergeTrees([es5Tree, htmlTree, assetsTree, clientModules]); - es6Tree = mergeTrees([es6Tree, htmlTree, assetsTree, clientModules]); + // this is needed only for creating a bundle + // typescript resolves dependencies automatically + if (modules.bundle_deps) { + var nodeModules = new Funnel( + 'node_modules', {include: ['@reactivex/**/**', 'parse5/**/**', 'css/**/**'], destDir: '/'}); + } - var mergedTree = mergeTrees([stew.mv(es6Tree, '/es6'), stew.mv(es5Tree, '/es5')]); + if (generateEs6) { + // Use TypeScript to transpile the *.ts files to ES6 + var es6Tree = compileWithTypescript(modulesTree, { + declaration: false, + emitDecoratorMetadata: true, + experimentalDecorators: true, + mapRoot: '', // force sourcemaps to use relative path + noEmitOnError: false, + rootDir: './', + rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'], + sourceMap: true, + sourceRoot: '.', + target: 'es6' + }); + es6Tree = stew.mv(mergeTrees([es6Tree, htmlTree, assetsTree, nodeModules]), '/es6'); + } + es5Tree = stew.mv(mergeTrees([es5Tree, htmlTree, assetsTree, nodeModules]), '/es5'); + + var mergedTree = mergeTrees([es6Tree, es5Tree]); return destCopy(mergedTree, destinationPath); };