fix(typings): Don't expose typing dependencies to users.
This resolves Duplicate Identifier issues seen by many users, at the expense of more typings installation required in some cases. Removes the quickstart hack of placing all needed dependencies typings files in our distribution. Removes dependencies on nodejs from angular2/core. Fixes #5973 Fixes #5807 Fixes #6266 Angular now depends on es6-promise and es6-collections (and a handful of manual typings) rather than all of es6-shim. Fixes #5242 We previously had an undocumented breaking change, this is now documented in this commit. Fixes #6817 BREAKING CHANGE: Transitive typings are no longer included in the distribution. You may need to install typings in your project using http://github.com/typings/typings Users now must rely on getting typings from: - one of the peerDependencies, such as rxjs, which exposes typings via the moduleResolution=node mechanism. (see https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages) This happens automatically. - Using --target ES5 now requires manual installation of es6-promise and es6-collections typings. - Using some angular APIs may introduce a dependency on eg. nodejs or jasmine, and those typings need manual installation as well. Closes #6267
This commit is contained in:
parent
2f31c4c1c5
commit
2a70f4e4c7
|
@ -981,15 +981,16 @@ gulp.task('!pre.test.typings.layoutNodeModule', ['build.js.cjs'], function() {
|
|||
.pipe(gulp.dest(path.join(tmpdir, 'node_modules')));
|
||||
});
|
||||
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
|
||||
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(path.join(tmpdir)));
|
||||
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(tmpdir));
|
||||
});
|
||||
|
||||
gulp.task('test.typings',
|
||||
['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() {
|
||||
var tsc = require('gulp-typescript');
|
||||
|
||||
return gulp.src([tmpdir + '/**'])
|
||||
return gulp.src([tmpdir + '/*.ts'])
|
||||
.pipe(tsc({
|
||||
target: 'ES5',
|
||||
target: 'ES6',
|
||||
module: 'commonjs',
|
||||
experimentalDecorators: true,
|
||||
noImplicitAny: true,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
*/
|
||||
|
||||
/// <reference path="../typings/zone/zone.d.ts"/>
|
||||
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
|
||||
|
||||
// TODO: ideally the node.d.ts reference should be scoped only for files that need and not to all
|
||||
// the code including client code
|
||||
/// <reference path="../typings/node/node.d.ts" />
|
||||
|
||||
declare var assert: any;
|
||||
|
||||
|
||||
interface BrowserNodeGlobal {
|
||||
Object: typeof Object;
|
||||
Array: typeof Array;
|
||||
Map: typeof Map;
|
||||
Set: typeof Set;
|
||||
Date: typeof Date;
|
||||
RegExp: typeof RegExp;
|
||||
JSON: typeof JSON;
|
||||
Math: typeof Math;
|
||||
assert(condition: any): void;
|
||||
Reflect: any;
|
||||
zone: Zone;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
frameworkStabilizers: Array<Function>;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
clearInterval: Function;
|
||||
}
|
|
@ -1,7 +1,52 @@
|
|||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
* Subset of es6-shim typings.
|
||||
* Angular should not require use of ES6 runtime but some API usages are already present.
|
||||
* See https://github.com/angular/angular/issues/5242
|
||||
* TODO(alexeagle): remove methods below which may not be present in targeted browser
|
||||
*/
|
||||
/// <reference path="../typings/es6-shim/es6-shim.d.ts"/>
|
||||
/// <reference path="./globals-es6.d.ts"/>
|
||||
|
||||
declare type PromiseConstructor = typeof Promise;
|
||||
|
||||
interface String {
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* position. Otherwise returns false.
|
||||
*/
|
||||
startsWith(searchString: string, position?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* endPosition – length(this). Otherwise returns false.
|
||||
*/
|
||||
endsWith(searchString: string, endPosition?: number): boolean;
|
||||
}
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: T, start?: number, end?: number): T[];
|
||||
}
|
||||
interface NumberConstructor {
|
||||
/**
|
||||
* Returns true if the value passed is an integer, false otherwise.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isInteger(number: number): boolean;
|
||||
}
|
||||
|
|
|
@ -248,15 +248,12 @@ class _Scanner {
|
|||
}
|
||||
|
||||
scanCharacter(start: number, code: number): Token {
|
||||
assert(this.peek == code);
|
||||
this.advance();
|
||||
return newCharacterToken(start, code);
|
||||
}
|
||||
|
||||
|
||||
scanOperator(start: number, str: string): Token {
|
||||
assert(this.peek == StringWrapper.charCodeAt(str, 0));
|
||||
assert(SetWrapper.has(OPERATORS, str));
|
||||
this.advance();
|
||||
return newOperatorToken(start, str);
|
||||
}
|
||||
|
@ -274,7 +271,6 @@ class _Scanner {
|
|||
*/
|
||||
scanComplexOperator(start: number, one: string, twoCode: number, two: string, threeCode?: number,
|
||||
three?: string): Token {
|
||||
assert(this.peek == StringWrapper.charCodeAt(one, 0));
|
||||
this.advance();
|
||||
var str: string = one;
|
||||
if (this.peek == twoCode) {
|
||||
|
@ -285,12 +281,10 @@ class _Scanner {
|
|||
this.advance();
|
||||
str += three;
|
||||
}
|
||||
assert(SetWrapper.has(OPERATORS, str));
|
||||
return newOperatorToken(start, str);
|
||||
}
|
||||
|
||||
scanIdentifier(): Token {
|
||||
assert(isIdentifierStart(this.peek));
|
||||
var start: number = this.index;
|
||||
this.advance();
|
||||
while (isIdentifierPart(this.peek)) this.advance();
|
||||
|
@ -303,7 +297,6 @@ class _Scanner {
|
|||
}
|
||||
|
||||
scanNumber(start: number): Token {
|
||||
assert(isDigit(this.peek));
|
||||
var simple: boolean = (this.index === start);
|
||||
this.advance(); // Skip initial digit.
|
||||
while (true) {
|
||||
|
@ -329,7 +322,6 @@ class _Scanner {
|
|||
}
|
||||
|
||||
scanString(): Token {
|
||||
assert(this.peek == $SQ || this.peek == $DQ);
|
||||
var start: number = this.index;
|
||||
var quote: number = this.peek;
|
||||
this.advance(); // Skip initial quote.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {normalizeBlank, isPresent, global} from 'angular2/src/facade/lang';
|
||||
import {normalizeBlank, isPresent, global, ZoneLike} from 'angular2/src/facade/lang';
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
||||
import {wtfLeave, wtfCreateScope, WtfScopeFn} from '../profile/profile';
|
||||
|
||||
export interface NgZoneZone extends Zone {
|
||||
export interface NgZoneZone extends ZoneLike {
|
||||
/** @internal */
|
||||
_innerZone: boolean;
|
||||
}
|
||||
|
@ -348,8 +348,9 @@ export class NgZone {
|
|||
var errorHandling;
|
||||
|
||||
if (enableLongStackTrace) {
|
||||
errorHandling = StringMapWrapper.merge(
|
||||
Zone.longStackTraceZone, {onError: function(e) { ngZone._notifyOnError(this, e); }});
|
||||
errorHandling =
|
||||
StringMapWrapper.merge(global.Zone.longStackTraceZone,
|
||||
{onError: function(e) { ngZone._notifyOnError(this, e); }});
|
||||
} else {
|
||||
errorHandling = {onError: function(e) { ngZone._notifyOnError(this, e); }};
|
||||
}
|
||||
|
|
|
@ -15,20 +15,16 @@ import {toPromise} from 'rxjs/operator/toPromise';
|
|||
export {Observable} from 'rxjs/Observable';
|
||||
export {Subject} from 'rxjs/Subject';
|
||||
|
||||
export namespace NodeJS {
|
||||
export interface Timer {}
|
||||
}
|
||||
|
||||
export class TimerWrapper {
|
||||
static setTimeout(fn: (...args: any[]) => void, millis: number): NodeJS.Timer {
|
||||
static setTimeout(fn: (...args: any[]) => void, millis: number): number {
|
||||
return global.setTimeout(fn, millis);
|
||||
}
|
||||
static clearTimeout(id: NodeJS.Timer): void { global.clearTimeout(id); }
|
||||
static clearTimeout(id: number): void { global.clearTimeout(id); }
|
||||
|
||||
static setInterval(fn: (...args: any[]) => void, millis: number): NodeJS.Timer {
|
||||
static setInterval(fn: (...args: any[]) => void, millis: number): number {
|
||||
return global.setInterval(fn, millis);
|
||||
}
|
||||
static clearInterval(id: NodeJS.Timer): void { global.clearInterval(id); }
|
||||
static clearInterval(id: number): void { global.clearInterval(id); }
|
||||
}
|
||||
|
||||
export class ObservableWrapper {
|
||||
|
@ -161,4 +157,4 @@ export class EventEmitter<T> extends Subject<T> {
|
|||
|
||||
return super.subscribe(schedulerFn, errorFn, completeFn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,36 @@
|
|||
// Zones are TC-39 standards-track so users could choose a different implementation
|
||||
// Rather than import {Zone} from 'zone.js' we define an interface
|
||||
// so that any library that structurally matches may be used with Angular 2.
|
||||
export interface ZoneLike {
|
||||
fork(locals?: any): ZoneLike;
|
||||
run(fn: any, applyTo?: any, applyWith?: any): any;
|
||||
}
|
||||
export interface ZoneLikeConstructor {
|
||||
longStackTraceZone: { [key: string]: any; };
|
||||
}
|
||||
|
||||
export interface BrowserNodeGlobal {
|
||||
Object: typeof Object;
|
||||
Array: typeof Array;
|
||||
Map: typeof Map;
|
||||
Set: typeof Set;
|
||||
Date: DateConstructor;
|
||||
RegExp: RegExpConstructor;
|
||||
JSON: typeof JSON;
|
||||
Math: any; // typeof Math;
|
||||
assert(condition: any): void;
|
||||
Reflect: any;
|
||||
zone: ZoneLike;
|
||||
Zone: ZoneLikeConstructor;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
frameworkStabilizers: Array<Function>;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
clearInterval: Function;
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Load WorkerGlobalScope from lib.webworker.d.ts file #3492
|
||||
declare var WorkerGlobalScope;
|
||||
var globalScope: BrowserNodeGlobal;
|
||||
|
@ -10,7 +43,7 @@ if (typeof window === 'undefined') {
|
|||
}
|
||||
} else {
|
||||
globalScope = <any>window;
|
||||
};
|
||||
}
|
||||
|
||||
export const IS_DART = false;
|
||||
|
||||
|
@ -430,4 +463,4 @@ export function evalExpression(sourceUrl: string, expr: string, declarations: st
|
|||
|
||||
export function isPrimitive(obj: any): boolean {
|
||||
return !isJsObject(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,6 +171,14 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
patterns: [{match: /\$SCRIPTS\$/, replacement: jsReplace('SCRIPTS')}]
|
||||
});
|
||||
|
||||
let ambientTypings = [
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts',
|
||||
'angular2/typings/es6-collections/es6-collections.d.ts',
|
||||
'angular2/typings/es6-promise/es6-promise.d.ts'
|
||||
];
|
||||
|
||||
// Use TypeScript to transpile the *.ts files to ES5
|
||||
var es5Tree = compileWithTypescript(es5ModulesTree, {
|
||||
declaration: false,
|
||||
|
@ -180,7 +188,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
moduleResolution: 'classic',
|
||||
noEmitOnError: !noTypeChecks,
|
||||
rootDir: './',
|
||||
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
|
||||
rootFilePaths: ambientTypings,
|
||||
inlineSourceMap: sourceMaps,
|
||||
inlineSources: sourceMaps,
|
||||
target: 'es5'
|
||||
|
@ -311,7 +319,11 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||
experimentalDecorators: true,
|
||||
noEmitOnError: false,
|
||||
rootDir: './',
|
||||
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
|
||||
rootFilePaths: [
|
||||
'angular2/typings/zone.js/zone.js.d.ts',
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
],
|
||||
inlineSourceMap: sourceMaps,
|
||||
inlineSources: sourceMaps,
|
||||
target: 'es6'
|
||||
|
|
|
@ -32,9 +32,16 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
|||
]
|
||||
});
|
||||
|
||||
let ambientTypings = [
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts',
|
||||
'angular2/typings/es6-collections/es6-collections.d.ts',
|
||||
'angular2/typings/es6-promise/es6-promise.d.ts'
|
||||
];
|
||||
|
||||
// Compile the sources and generate the @internal .d.ts
|
||||
let compiledSrcTreeWithInternals =
|
||||
compileTree(srcTree, true, ['angular2/manual_typings/globals.d.ts']);
|
||||
let compiledSrcTreeWithInternals = compileTree(srcTree, true, ambientTypings);
|
||||
|
||||
var testTree = new Funnel('modules', {
|
||||
include: [
|
||||
|
@ -85,11 +92,10 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
|||
|
||||
testTree = mergeTrees([testTree, srcPrivateDeclarations]);
|
||||
|
||||
let compiledTestTree = compileTree(testTree, false, [
|
||||
let compiledTestTree = compileTree(testTree, false, ambientTypings.concat([
|
||||
'angular2/typings/jasmine/jasmine.d.ts',
|
||||
'angular2/typings/angular-protractor/angular-protractor.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts'
|
||||
]);
|
||||
]));
|
||||
|
||||
// Merge the compiled sources and tests
|
||||
let compiledSrcTree =
|
||||
|
@ -112,12 +118,7 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
|||
var srcPkgJsons = extractPkgJsons(srcTree, BASE_PACKAGE_JSON);
|
||||
var testPkgJsons = extractPkgJsons(testTree, BASE_PACKAGE_JSON);
|
||||
|
||||
var typingsTree = new Funnel(
|
||||
'modules',
|
||||
{include: ['angular2/typings/**/*.d.ts', 'angular2/manual_typings/*.d.ts'], destDir: '/'});
|
||||
|
||||
var nodeTree =
|
||||
mergeTrees([compiledTree, srcDocs, testDocs, srcPkgJsons, testPkgJsons, typingsTree]);
|
||||
var nodeTree = mergeTrees([compiledTree, srcDocs, testDocs, srcPkgJsons, testPkgJsons]);
|
||||
|
||||
// Transform all tests to make them runnable in node
|
||||
nodeTree = replace(nodeTree, {
|
||||
|
@ -139,22 +140,6 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
|||
nodeTree = replace(
|
||||
nodeTree, {files: ['**/*.js'], patterns: [{match: /^/, replacement: () => `'use strict';`}]});
|
||||
|
||||
// Add a line to the end of our top-level .d.ts file.
|
||||
// This HACK for transitive typings is a workaround for
|
||||
// https://github.com/Microsoft/TypeScript/issues/5097
|
||||
//
|
||||
// This allows users to get our top-level dependencies like zone.d.ts
|
||||
// to appear when they compile against angular2.
|
||||
//
|
||||
// This carries the risk that the user brings their own copy of that file
|
||||
// (or any other symbols exported here) and they will get a compiler error
|
||||
// because of the duplicate definitions.
|
||||
// TODO(alexeagle): remove this when typescript releases a fix
|
||||
nodeTree = replace(nodeTree, {
|
||||
files: ['angular2/core.d.ts'],
|
||||
patterns: [{match: /$/, replacement: 'import "./manual_typings/globals-es6.d.ts";\r\n'}]
|
||||
});
|
||||
|
||||
return destCopy(nodeTree, destinationPath);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue