build: serve benchmark tree examples with bazel (#28568)

PR Close #28568
This commit is contained in:
Paul Gschwendtner 2019-02-06 18:02:07 +01:00 committed by Miško Hevery
parent fed8c1d160
commit c916b360bf
30 changed files with 386 additions and 189 deletions

View File

@ -1,5 +1,10 @@
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])
exports_files([
"tsconfig-build.json",
"start-server.js",
])
filegroup( filegroup(
name = "favicon", name = "favicon",
srcs = [ srcs = [

View File

@ -0,0 +1,22 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_library(
name = "baseline",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/baseline/index",
index_html = "index.html",
port = 4200,
deps = [":baseline"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -21,11 +25,5 @@
<div> <div>
<tree id="root">Loading...</tree> <tree id="root">Loading...</tree>
</div> </div>
<script>
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|| '../../bootstrap_plain.js';
document.write('<script src="' + mainUrl + '">\u003c/script>');
</script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,26 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_library(
name = "incremental_dom",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
"@ngdeps//@types/node",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/incremental_dom/index",
index_html = "index.html",
port = 4200,
static_files = [
"@ngdeps//node_modules/incremental-dom:dist/incremental-dom.js",
],
deps = [":incremental_dom"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -21,7 +25,5 @@
<div> <div>
<tree id="root"></tree> <tree id="root"></tree>
</div> </div>
<script src="../../bootstrap_plain.js"></script>
</body> </body>
</html> </html>

View File

@ -9,26 +9,27 @@
import {bindAction, profile} from '../../util'; import {bindAction, profile} from '../../util';
import {buildTree, emptyTree} from '../util'; import {buildTree, emptyTree} from '../util';
import {TreeComponent} from './tree'; import {TreeComponent} from './tree';
const {patch} = require('incremental-dom');
export function main() { let tree: TreeComponent;
let tree: TreeComponent;
function destroyDom() { tree.data = emptyTree; } function destroyDom() {
tree.data = emptyTree;
function createDom() { tree.data = buildTree(); }
function noop() {}
function init() {
tree = new TreeComponent(document.querySelector('tree'));
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
}
init();
} }
function createDom() {
tree.data = buildTree();
}
function noop() {}
function init() {
tree = new TreeComponent(document.querySelector('tree'));
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
}
init();

View File

@ -7,8 +7,12 @@
*/ */
import {TreeNode} from '../util'; import {TreeNode} from '../util';
// We load "IncrementalDOM" as a AMD global because the "incremental-dom" NPM package does not
// come with a named UMD module, and it's easier to just import the AMD file and use it globally.
declare const IncrementalDOM: any;
const {patch, elementOpen, elementClose, elementOpenStart, elementOpenEnd, text, attr} = const {patch, elementOpen, elementClose, elementOpenStart, elementOpenEnd, text, attr} =
require('incremental-dom'); IncrementalDOM;
export class TreeComponent { export class TreeComponent {
constructor(private _rootEl: any) {} constructor(private _rootEl: any) {}

View File

@ -0,0 +1,10 @@
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_devserver(
name = "devserver",
index_html = "index.html",
port = 4200,
static_files = ["tree.js"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -24,7 +28,5 @@
Change detection runs:<span id="numberOfChecks"></span> Change detection runs:<span id="numberOfChecks"></span>
</div> </div>
<div id="root"></div> <div id="root"></div>
<script type="text/javascript" src="tree.js"></script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,25 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_library(
name = "ng1",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/ng1/index",
index_html = "index.html",
port = 4200,
static_files = [
"@ngdeps//node_modules/angular:angular.js",
],
deps = [":ng1"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -26,19 +30,5 @@
<div> <div>
<tree id="root" data="initData">Loading...</tree> <tree id="root" data="initData">Loading...</tree>
</div> </div>
<script>
var mainUrls = [
'/all/benchmarks/vendor/angular.js',
'../../bootstrap_plain.js'
];
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1];
if (mainUrl) {
mainUrls = [mainUrl];
}
mainUrls.forEach(function(mainUrl) {
document.write('<script src="' + mainUrl + '">\u003c/script>');
});
</script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,32 @@
load("//tools:defaults.bzl", "ng_module")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ng_module(
name = "ng2",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
# TODO: FW-1004 Type checking is currently not complete.
type_check = False,
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
"//packages/core",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/ng2/index",
index_html = "index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
static_files = [
"@ngdeps//node_modules/zone.js:dist/zone.js",
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
],
deps = [":ng2"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -26,11 +30,5 @@
<div> <div>
<tree id="root">Loading...</tree> <tree id="root">Loading...</tree>
</div> </div>
<script>
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|| '../../bootstrap_ng2.js';
document.write('<script src="' + mainUrl + '">\u003c/script>');
</script>
</body> </body>
</html> </html>

View File

@ -12,7 +12,5 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {init} from './init'; import {init} from './init';
import {AppModule} from './tree'; import {AppModule} from './tree';
export function main() { enableProdMode();
enableProdMode(); platformBrowserDynamic().bootstrapModule(AppModule).then(init);
platformBrowserDynamic().bootstrapModule(AppModule).then(init);
}

View File

@ -0,0 +1,26 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_library(
name = "ng2_next",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
"//packages/common",
"//packages/core",
"//packages/platform-browser",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/ng2_next/index",
index_html = "index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
deps = [":ng2_next"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -26,11 +30,5 @@
<div> <div>
<tree id="root">Loading...</tree> <tree id="root">Loading...</tree>
</div> </div>
<script>
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|| '../../bootstrap_ng2.js';
document.write('<script src="' + mainUrl + '">\u003c/script>');
</script>
</body> </body>
</html> </html>

View File

@ -13,42 +13,40 @@ import {buildTree, emptyTree} from '../util';
import {AppModule, TreeComponent} from './tree'; import {AppModule, TreeComponent} from './tree';
export function main() { let tree: TreeComponent;
let tree: TreeComponent; let appMod: AppModule;
let appMod: AppModule; let detectChangesRuns = 0;
let detectChangesRuns = 0;
function destroyDom() { function destroyDom() {
tree.data = emptyTree; tree.data = emptyTree;
appMod.tick(); appMod.tick();
}
function createDom() {
tree.data = buildTree();
appMod.tick();
}
function detectChanges() {
for (let i = 0; i < 10; i++) {
appMod.tick();
}
detectChangesRuns += 10;
numberOfChecksEl.textContent = `${detectChangesRuns}`;
}
function noop() {}
const numberOfChecksEl = document.getElementById('numberOfChecks');
enableProdMode();
appMod = new AppModule();
appMod.bootstrap();
tree = appMod.componentRef.instance;
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#detectChanges', detectChanges);
bindAction('#detectChangesProfile', profile(detectChanges, noop, 'detectChanges'));
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
} }
function createDom() {
tree.data = buildTree();
appMod.tick();
}
function detectChanges() {
for (let i = 0; i < 10; i++) {
appMod.tick();
}
detectChangesRuns += 10;
numberOfChecksEl.textContent = `${detectChangesRuns}`;
}
function noop() {}
const numberOfChecksEl = document.getElementById('numberOfChecks');
enableProdMode();
appMod = new AppModule();
appMod.bootstrap();
tree = appMod.componentRef.instance;
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#detectChanges', detectChanges);
bindAction('#detectChangesProfile', profile(detectChanges, noop, 'detectChanges'));
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));

View File

@ -0,0 +1,30 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ts_library(
name = "ng2_static",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
"//packages/core",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/ng2_static/index",
index_html = "index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
static_files = [
"@ngdeps//node_modules/zone.js:dist/zone.js",
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
],
deps = [":ng2_static"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
<form> <form>
@ -20,7 +24,5 @@
<div> <div>
<tree id="root"></tree> <tree id="root"></tree>
</div> </div>
<script src="../../bootstrap_ng2.js"></script>
</body> </body>
</html> </html>

View File

@ -14,35 +14,33 @@ import {buildTree, emptyTree} from '../util';
import {AppModule, RootTreeComponent} from './tree'; import {AppModule, RootTreeComponent} from './tree';
export function main() { let tree: RootTreeComponent;
let tree: RootTreeComponent; let appRef: ApplicationRef;
let appRef: ApplicationRef;
function destroyDom() { function destroyDom() {
tree.data = emptyTree; tree.data = emptyTree;
appRef.tick(); appRef.tick();
}
function createDom() {
tree.data = buildTree();
appRef.tick();
}
function noop() {}
function init() {
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule).then((ref) => {
const injector = ref.injector;
appRef = injector.get(ApplicationRef);
tree = appRef.components[0].instance;
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
});
}
init();
} }
function createDom() {
tree.data = buildTree();
appRef.tick();
}
function noop() {}
function init() {
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule).then((ref) => {
const injector = ref.injector;
appRef = injector.get(ApplicationRef);
tree = appRef.components[0].instance;
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
});
}
init();

View File

@ -0,0 +1,32 @@
load("//tools:defaults.bzl", "ng_module")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ng_module(
name = "ng2_switch",
srcs = glob(["*.ts"]),
tsconfig = "//modules/benchmarks:tsconfig-build.json",
# TODO: FW-1004 Type checking is currently not complete.
type_check = False,
deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib",
"//packages/core",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/ng2_switch/index",
index_html = "index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
static_files = [
"@ngdeps//node_modules/zone.js:dist/zone.js",
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
],
deps = [":ng2_switch"],
)

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -21,11 +25,5 @@
<div> <div>
<tree id="root">Loading...</tree> <tree id="root">Loading...</tree>
</div> </div>
<script>
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|| '../../bootstrap_ng2.js';
document.write('<script src="' + mainUrl + '">\u003c/script>');
</script>
</body> </body>
</html> </html>

View File

@ -12,7 +12,5 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {init} from './init'; import {init} from './init';
import {AppModule} from './tree'; import {AppModule} from './tree';
export function main() { enableProdMode();
enableProdMode(); platformBrowserDynamic().bootstrapModule(AppModule).then(init);
platformBrowserDynamic().bootstrapModule(AppModule).then(init);
}

View File

@ -1,4 +1,4 @@
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//modules/benchmarks:__subpackages__"])
load("//tools:defaults.bzl", "ng_module", "ng_rollup_bundle") load("//tools:defaults.bzl", "ng_module", "ng_rollup_bundle")
load("//packages/bazel:index.bzl", "protractor_web_test_suite") load("//packages/bazel:index.bzl", "protractor_web_test_suite")
@ -6,11 +6,7 @@ load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module( ng_module(
name = "tree_lib", name = "tree_lib",
srcs = glob( srcs = glob(["**/*.ts"]),
[
"**/*.ts",
],
),
tags = ["ivy-only"], tags = ["ivy-only"],
deps = [ deps = [
"//modules/benchmarks/src/tree:util_lib", "//modules/benchmarks/src/tree:util_lib",
@ -30,20 +26,12 @@ ng_rollup_bundle(
], ],
) )
genrule(
name = "favicon",
srcs = ["//modules/benchmarks:favicon"],
outs = ["favicon.ico"],
cmd = "cp $< $@",
)
ts_devserver( ts_devserver(
name = "devserver", name = "devserver",
static_files = [ static_files = [
":bundle.min_debug.js", ":bundle.min_debug.js",
":bundle.min.js", ":bundle.min.js",
"index.html", "index.html",
":favicon",
], ],
tags = ["ivy-only"], tags = ["ivy-only"],
) )

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>

View File

@ -1,19 +1,26 @@
package(default_visibility = ["//visibility:public"]) load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
load("//tools:defaults.bzl", "ts_library")
load("//tools:defaults.bzl", "ng_module") package(default_visibility = ["//modules/benchmarks:__subpackages__"])
ng_module( ts_library(
name = "render3_function_lib", name = "render3_function_lib",
srcs = glob( srcs = glob(["**/*.ts"]),
[
"**/*.ts",
],
),
deps = [ deps = [
"//modules/benchmarks/src:util_lib",
"//modules/benchmarks/src/tree:util_lib", "//modules/benchmarks/src/tree:util_lib",
"//modules/benchmarks/src/tree/render3:tree_lib", "//modules/benchmarks/src/tree/render3:tree_lib",
"//packages:types",
"//packages/core", "//packages/core",
"@rxjs", ],
)
ts_devserver(
name = "devserver",
entry_module = "angular/modules/benchmarks/src/tree/render3_function/index",
index_html = "index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
deps = [":render3_function_lib"],
)
], ],
) )

View File

@ -1,5 +1,9 @@
<!doctype html> <!doctype html>
<html> <html>
<head>
<!-- Prevent the browser from requesting any favicon. -->
<link rel="icon" href="data:,">
</head>
<body> <body>
<h2>Params</h2> <h2>Params</h2>
@ -30,9 +34,6 @@
<script> <script>
// TODO(mlaval): remove once we have a proper solution // TODO(mlaval): remove once we have a proper solution
ngDevMode = false; ngDevMode = false;
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|| '../../bootstrap_ng2.js';
document.write('<script src="' + mainUrl + '">\u003c/script>');
</script> </script>
</body> </body>
</html> </html>

View File

@ -14,23 +14,6 @@ import {TreeNode, emptyTree} from '../util';
function noop() {} function noop() {}
export function main() {
let component: TreeFunction;
if (typeof window !== 'undefined') {
component = renderComponent(TreeFunction);
bindAction('#createDom', () => createDom(component as any));
bindAction('#destroyDom', () => destroyDom(component as any));
bindAction('#detectChanges', () => detectChanges(component as any));
bindAction(
'#detectChangesProfile',
profile(() => detectChanges(component as any), noop, 'detectChanges'));
bindAction('#updateDomProfile', profile(() => createDom(component as any), noop, 'update'));
bindAction(
'#createDomProfile',
profile(() => createDom(component as any), () => destroyDom(component as any), 'create'));
}
}
export class TreeFunction { export class TreeFunction {
data: TreeNode = emptyTree; data: TreeNode = emptyTree;
@ -86,3 +69,18 @@ export function TreeTpl(rf: ɵRenderFlags, ctx: TreeNode) {
ɵcontainerRefreshEnd(); ɵcontainerRefreshEnd();
} }
} }
let component: TreeFunction;
if (typeof window !== 'undefined') {
component = renderComponent(TreeFunction);
bindAction('#createDom', () => createDom(component as any));
bindAction('#destroyDom', () => destroyDom(component as any));
bindAction('#detectChanges', () => detectChanges(component as any));
bindAction(
'#detectChangesProfile',
profile(() => detectChanges(component as any), noop, 'detectChanges'));
bindAction('#updateDomProfile', profile(() => createDom(component as any), noop, 'update'));
bindAction(
'#createDomProfile',
profile(() => createDom(component as any), () => destroyDom(component as any), 'create'));
}

View File

@ -0,0 +1,6 @@
{
"compilerOptions": {
"lib": ["dom", "es2015"],
"types": []
}
}

View File

@ -69,6 +69,7 @@
"domino": "2.1.0", "domino": "2.1.0",
"fs-extra": "4.0.2", "fs-extra": "4.0.2",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
"incremental-dom": "0.4.1",
"jasmine": "^3.1.0", "jasmine": "^3.1.0",
"jasmine-core": "^3.1.0", "jasmine-core": "^3.1.0",
"karma": "^3.1.4", "karma": "^3.1.4",
@ -125,7 +126,6 @@
"gulp-git": "^2.7.0", "gulp-git": "^2.7.0",
"gulp-tslint": "8.1.2", "gulp-tslint": "8.1.2",
"husky": "^0.14.3", "husky": "^0.14.3",
"incremental-dom": "0.4.1",
"jpm": "1.3.1", "jpm": "1.3.1",
"karma-browserstack-launcher": "^1.3.0", "karma-browserstack-launcher": "^1.3.0",
"karma-chrome-launcher": "^2.2.0", "karma-chrome-launcher": "^2.2.0",