Skip to content

Commit 31f85f0

Browse files
Tim Blasikegluneq
Tim Blasi
authored andcommitted
chore(analytics): Build hello_world, check constraints
Create gulp targets to build `hello_world` and check its gzipped size against size constraints. See angular#5312, angular#5314
1 parent 225b9d3 commit 31f85f0

File tree

7 files changed

+197
-24
lines changed

7 files changed

+197
-24
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ npm-debug.log
4545

4646
# build-analytics
4747
.build-analytics
48+
49+
# built dart payload tests
50+
/modules_dart/payload/**/build

gulpfile.js

+30-6
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,10 @@ gulp.task('build/check.apidocs.dart',
252252
// pubbuild
253253
// WARNING: this task is very slow (~15m as of July 2015)
254254

255-
gulp.task('build/pubbuild.dart',
256-
pubbuild(gulp, gulpPlugins,
257-
{src: CONFIG.dest.dart, dest: CONFIG.dest.js.dart2js, command: DART_SDK.PUB}));
255+
gulp.task(
256+
'build/pubbuild.dart',
257+
pubbuild.subdirs(gulp, gulpPlugins,
258+
{src: CONFIG.dest.dart, dest: CONFIG.dest.js.dart2js, command: DART_SDK.PUB}));
258259

259260
// ------------
260261
// formatting
@@ -584,6 +585,30 @@ gulp.task('test.unit.dart', function(done) {
584585
});
585586
});
586587

588+
// Dart Payload Size Test
589+
// This test will fail if the size of our hello_world app goes beyond one of
590+
// these values when compressed at the specified level.
591+
// Measure in bytes.
592+
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 375 * 1024, 'gzip level=6': 105 * 1024};
593+
gulp.task('test.payload.dart/ci', function(done) {
594+
runSequence('build/packages.dart', '!pubget.payload.dart', '!pubbuild.payload.dart',
595+
'!checkAndReport.payload.dart', done);
596+
});
597+
598+
gulp.task('!pubget.payload.dart',
599+
pubget.dir(gulp, gulpPlugins,
600+
{dir: 'modules_dart/payload/hello_world', command: DART_SDK.PUB}));
601+
602+
gulp.task('!pubbuild.payload.dart',
603+
pubbuild.single(gulp, gulpPlugins,
604+
{command: DART_SDK.PUB, src: 'modules_dart/payload/hello_world'}));
605+
606+
gulp.task('!checkAndReport.payload.dart', function() {
607+
var reportSize = require('./tools/analytics/reportsize');
608+
return reportSize('modules_dart/payload/hello_world/build/web/*.dart.js',
609+
{failConditions: _DART_PAYLOAD_SIZE_LIMITS, prefix: 'hello_world'});
610+
});
611+
587612
gulp.task('watch.dart.dev', function(done) {
588613
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
589614
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
@@ -1053,10 +1078,9 @@ gulp.task('!bundle.copy', function() {
10531078
gulp.src('dist/js/bundle/**').pipe(gulp.dest('dist/js/dev/es5/bundle')));
10541079
});
10551080

1056-
gulp.task('!bundles.js.checksize', function() {
1081+
gulp.task('!bundles.js.checksize', function(done) {
10571082
var reportSize = require('./tools/analytics/reportsize');
1058-
return reportSize('dist/js/bundle/**', {printToConsole: false,
1059-
reportAnalytics: true});
1083+
return reportSize('dist/js/bundle/**', {printToConsole: ['gzip level=2']});
10601084
});
10611085

10621086
gulp.task('bundles.js',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: hello_world
2+
environment:
3+
sdk: '>=1.10.0 <2.0.0'
4+
dependencies:
5+
observe: '^0.13.1'
6+
angular2: any
7+
browser: '^0.10.0'
8+
dependency_overrides:
9+
angular2:
10+
path: ../../../dist/dart/angular2
11+
transformers:
12+
- angular2:
13+
platform_directives: 'package:angular2/src/common/directives.dart#CORE_DIRECTIVES'
14+
entry_points:
15+
- web/index.dart
16+
17+
- $dart2js:
18+
minify: true
19+
commandLineOptions:
20+
- --show-package-warnings
21+
- --trust-type-annotations
22+
- --trust-primitives
23+
# Uncomment to generate summaries from dart2js
24+
# - --dump-info
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
library hello_world.index;
2+
3+
import "package:angular2/bootstrap.dart" show bootstrap;
4+
import "package:angular2/core.dart"
5+
show ElementRef, Component, Directive, Injectable;
6+
import "package:angular2/render.dart" show Renderer;
7+
8+
main() {
9+
// Bootstrapping only requires specifying a root component.
10+
11+
// The boundary between the Angular application and the rest of the page is
12+
13+
// the shadowDom of this root component.
14+
15+
// The selector of the component passed in is used to find where to insert the
16+
17+
// application.
18+
19+
// You can use the light dom of the <hello-app> tag as temporary content (for
20+
21+
// example 'Loading...') before the application is ready.
22+
bootstrap(HelloCmp);
23+
}
24+
25+
// A service available to the Injector, used by the HelloCmp component.
26+
@Injectable()
27+
class GreetingService {
28+
String greeting = "hello";
29+
}
30+
// Directives are light-weight. They don't allow new
31+
32+
// expression contexts (use @Component for those needs).
33+
@Directive(selector: "[red]")
34+
class RedDec {
35+
// ElementRef is always injectable and it wraps the element on which the
36+
37+
// directive was found by the compiler.
38+
RedDec(ElementRef el, Renderer renderer) {
39+
renderer.setElementStyle(el, "color", "red");
40+
}
41+
}
42+
// Angular 2.0 supports 2 basic types of directives:
43+
44+
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
45+
46+
// ShadowDom.(http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
47+
48+
// - Directive - add behavior to existing elements.
49+
50+
// @Component is AtScript syntax to annotate the HelloCmp class as an Angular
51+
52+
// 2.0 component.
53+
@Component(
54+
selector: "hello-app",
55+
viewProviders: const [GreetingService],
56+
template:
57+
'''<div class="greeting">{{greeting}} <span red>world</span>!</div>
58+
<button class="changeButton" (click)="changeGreeting()">change greeting</button>''',
59+
directives: const [RedDec])
60+
class HelloCmp {
61+
String greeting;
62+
HelloCmp(GreetingService service) {
63+
this.greeting = service.greeting;
64+
}
65+
void changeGreeting() {
66+
this.greeting = "howdy";
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html>
3+
<title>Hello Angular 2.0</title>
4+
<body>
5+
<hello-app>
6+
Loading...
7+
</hello-app>
8+
9+
<script src="index.dart" type="application/dart"></script>
10+
<script src="packages/browser/dart.js" type="text/javascript"></script>
11+
</body>
12+
</html>

tools/analytics/reportsize.js

+29-10
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ const _gzipConfigs = {
2222

2323
const _defaultOptions = {
2424
// @type {Object<string, number>}
25-
// - Key(s) must match keys of `_gzipConfigs`.
25+
// - Key(s) must match one of `_gzipConfigs` keys.
2626
// - Values are the max size (in bytes) allowed for that configuration.
2727
failConditions: {},
2828
prefix: '',
29-
printToConsole: false,
29+
// @type {Array<string>|boolean}
30+
// Entries must match one of `_gzipConfigs` keys. These values will be
31+
// printed to the screen.
32+
// If this is the boolean value `true`, will print all to screen.
33+
printToConsole: ['gzip level=6'],
3034
reportAnalytics: true
3135
};
3236

@@ -41,7 +45,7 @@ function reportSize(glob, options) {
4145
options[key] = _defaultOptions[key];
4246
}
4347
}
44-
var errStream = _checkFailConditionConfig(options.failConditions);
48+
var errStream = _checkConfig(options);
4549
if (errStream) {
4650
return errStream;
4751
}
@@ -83,27 +87,29 @@ function reportSize(glob, options) {
8387
if (options.reportAnalytics) {
8488
analytics.bundleSize(filePath, fileLen, compressionLevel);
8589
}
86-
if (options.printToConsole) {
90+
if (_shouldPrint(options, compressionLevel)) {
8791
console.log(` ${filePath} => ${fileLen} bytes (${compressionLevel})`)
8892
}
8993
if (options.failConditions.hasOwnProperty(compressionLevel)) {
9094
if (options.failConditions[compressionLevel] < fileLen) {
9195
errs.push(`Max size for "${compressionLevel}" is ` +
9296
`${options.failConditions[compressionLevel]}, but the size is now ${fileLen}.`);
93-
if (options.printToConsole) {
94-
console.log(` !!! ${errs[errs.length - 1]}`);
95-
}
9697
}
9798
}
9899
}
99100
}
100101
}
101102

103+
function _shouldPrint(options, compressionLevel) {
104+
const printAll = typeof options.printToConsole == 'boolean' && options.printToConsole;
105+
return printAll || options.printToConsole.indexOf(compressionLevel) >= 0;
106+
}
107+
102108
// Returns an error stream if the fail conditions are not provided property.
103109
// Returns `null` if everything is fine.
104-
function _checkFailConditionConfig(failConditions) {
105-
for (const key in failConditions) {
106-
if (failConditions.hasOwnProperty(key)) {
110+
function _checkConfig(config) {
111+
for (const key in config.failConditions) {
112+
if (config.failConditions.hasOwnProperty(key)) {
107113
if (!_gzipConfigs.hasOwnProperty(key)) {
108114
var stream = new Stream();
109115
stream.emit(
@@ -114,6 +120,19 @@ function _checkFailConditionConfig(failConditions) {
114120
}
115121
}
116122
}
123+
if (typeof config.printToConsole != 'boolean') {
124+
for (var i = 0; i < config.printToConsole.length; ++i) {
125+
const key = config.printToConsole[i];
126+
if (!_gzipConfigs.hasOwnProperty(key)) {
127+
var stream = new Stream();
128+
stream.emit(
129+
'error',
130+
new Error(`Incorrect value "${key}" in printToConsole. Check _gzipConfigs.`));
131+
stream.emit('end');
132+
return stream;
133+
}
134+
}
135+
}
117136
return null;
118137
}
119138

tools/build/pubbuild.js

+31-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var path = require('path');
66
var glob = require('glob');
77
var fs = require('fs');
88

9-
module.exports = function(gulp, plugins, config) {
9+
function buildAllWebSubdirs(gulp, plugins, config) {
1010
return function() {
1111
var webFolders = [].slice.call(glob.sync(path.join(config.src, '*/web')));
1212
return nextFolder();
@@ -17,20 +17,34 @@ module.exports = function(gulp, plugins, config) {
1717
}
1818
var folder = path.resolve(path.join(webFolders.shift(), '..'));
1919
var destFolder = path.resolve(path.join(config.dest, path.basename(folder)));
20-
var pubMode = config.mode || 'release';
21-
var pubArgs = ['build', '--mode', pubMode, '-o', destFolder];
2220

23-
return util.processToPromise(spawn(config.command, pubArgs, {
24-
stdio: 'inherit',
25-
cwd: folder
26-
})).then(function() {
21+
const nextConfig = {
22+
command: config.command,
23+
dest: destFolder,
24+
mode: config.mode,
25+
src: folder
26+
};
27+
return single(nextConfig).then(function() {
2728
return replaceDartWithJsScripts(gulp, destFolder);
2829
}).then(function() {
2930
return removeWebFolder(gulp, destFolder);
3031
}).then(nextFolder);
3132
}
3233
};
33-
};
34+
}
35+
36+
function single(config) {
37+
var pubMode = config.mode || 'release';
38+
var pubArgs = ['build', '--mode', pubMode];
39+
if (config.dest) {
40+
pubArgs = pubArgs.concat(['-o', config.dest]);
41+
}
42+
43+
return util.processToPromise(spawn(config.command, pubArgs, {
44+
stdio: 'inherit',
45+
cwd: config.src
46+
}));
47+
}
3448

3549
function replaceDartWithJsScripts(gulp, folder) {
3650
return util.streamToPromise(gulp.src(path.join(folder, '**/*.html'))
@@ -45,6 +59,10 @@ function replaceDartWithJsScripts(gulp, folder) {
4559
.pipe(gulp.dest(folder)));
4660
}
4761

62+
function singleWrapper(gulp, plugins, config) {
63+
return function() { return single(config); };
64+
}
65+
4866
function removeWebFolder(gulp, folder) {
4967
var folders = [].slice.call(glob.sync(path.join(folder, 'web', '*')));
5068
folders.forEach(function(subFolder) {
@@ -53,3 +71,8 @@ function removeWebFolder(gulp, folder) {
5371
fs.rmdirSync(path.join(folder, 'web'));
5472
return Q.resolve();
5573
}
74+
75+
module.exports = {
76+
single: singleWrapper,
77+
subdirs: buildAllWebSubdirs
78+
};

0 commit comments

Comments
 (0)