refactor(build): simplify and modularize

simplify:
- use same html file for dart and JS
- build benchmarks automatically when doing `gulp build`
- centralize configuration

modularize:
- move all build tasks into separate node.js modules under
  `tools/build`.

changes:
- the `build` folder is now the `dist` folder

Closes #284
This commit is contained in:
Tobias Bosch 2014-12-05 16:26:30 -08:00
parent e32ddcc7eb
commit 8db77f2405
75 changed files with 710 additions and 848 deletions

6
.gitignore vendored
View File

@ -1,10 +1,8 @@
# Dont commit the following directories created by pub. # Dont commit the following directories created by pub.
build/ /dist/
benchpress-build/
packages/ packages/
.buildlog .buildlog
node_modules node_modules
packages
.pub .pub
.DS_STORE .DS_STORE
@ -21,4 +19,4 @@ pubspec.lock
.idea/ .idea/
docs/bower_components/ /docs/bower_components/

View File

@ -25,13 +25,13 @@
### Build: ### Build:
1. `gulp build` -> result is in `build` folder 1. `gulp build` -> result is in `dist` folder
* will also run `pub get` for the subfolders in `modules` * will also run `pub get` for the subfolders in `modules`
and run `dartanalyzer` for every file that matches and run `dartanalyzer` for every file that matches
`<module>/src/<module>.dart`, e.g. `di/src/di.dart` `<module>/src/<module>.dart`, e.g. `di/src/di.dart`
2. `gulp clean` -> cleans the `build` folder 2. `gulp clean` -> cleans the `dist` folder
### Tests: ### Tests:
@ -45,13 +45,6 @@ the transpiler is reloaded. With that it is possible to make changes
to the preprocessor and run the tests without exiting karma to the preprocessor and run the tests without exiting karma
(just touch a test file that you would like to run). (just touch a test file that you would like to run).
Restriction for Dart tests (for now):
* Due to a bug `karma-dart` plugin,
this will use the files in the `build` folder for resolving
`package:` dependencies (created e.g. for `import ... from 'di:di'`).
So you need to execute `gulp build` before this.
### Examples: ### Examples:
To see the examples, first build the project as described above. To see the examples, first build the project as described above.
@ -59,11 +52,11 @@ To see the examples, first build the project as described above.
#### Hello World Example #### Hello World Example
This example consists of three basic pieces - a component, a decorator and a service. This example consists of three basic pieces - a component, a decorator and a service.
They are all constructed via injection. For more information see the comments in the They are all constructed via injection. For more information see the comments in the
source `modules/examples/src/hello_world/app.js`. source `modules/examples/src/hello_world/index.js`.
You can build this example as either JS or Dart app: You can build this example as either JS or Dart app:
* (JS) `gulp serve` and open `localhost:8000/js/examples/lib/hello_world/` in Chrome. * (JS) `gulp serve.js.dev` and open `localhost:8000/examples/web/hello_world/` in Chrome.
* (Dart) `gulp examples/pub.serve` and open `localhost:8080` in Chrome(for dart2js) or dartium(for dart vm). * (Dart) `gulp serve/examples.dart` and open `localhost:8080` in Chrome(for dart2js) or dartium(for dart vm).
## Debug the transpiler ## Debug the transpiler

View File

@ -45,7 +45,7 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
// Configure file writing // Configure file writing
.config(function(writeFilesProcessor) { .config(function(writeFilesProcessor) {
writeFilesProcessor.outputFolder = 'build/docs'; writeFilesProcessor.outputFolder = 'dist/docs';
}) })

View File

@ -1,6 +1,6 @@
var traceur = require('traceur/src/node/traceur.js'); var traceur = require('traceur/src/node/traceur.js');
var ParseTreeVisitor = System.get(System.map.traceur + '/src/syntax/ParseTreeVisitor').ParseTreeVisitor; var ParseTreeVisitor = System.get(System.map.traceur + '/src/syntax/ParseTreeVisitor').ParseTreeVisitor;
var file2modulename = require('../../../file2modulename'); var file2modulename = require('../../../tools/build/file2modulename');
/** /**
* Wrapper around traceur that can parse the contents of a file * Wrapper around traceur that can parse the contents of a file
*/ */

View File

@ -1,22 +1,23 @@
var benchpress = require('angular-benchpress/lib/cli');
var del = require('del');
var es = require('event-stream');
var file2moduleName = require('./file2modulename');
var fs = require('fs');
var glob = require('glob');
var gulp = require('gulp'); var gulp = require('gulp');
var $ = require('gulp-load-plugins')(); var gulpPlugins = require('gulp-load-plugins')();
var merge = require('merge');
var mergeStreams = require('event-stream').merge;
var path = require('path');
var Q = require('q');
var readline = require('readline');
var runSequence = require('run-sequence'); var runSequence = require('run-sequence');
var spawn = require('child_process').spawn; var merge = require('merge');
var through2 = require('through2'); var gulpTraceur = require('./tools/transpiler/gulp-traceur');
var which = require('which');
var js2es5Options = { var clean = require('./tools/build/clean');
var deps = require('./tools/build/deps');
var transpile = require('./tools/build/transpile');
var html = require('./tools/build/html');
var benchpress = require('./tools/build/benchpress');
var pubspec = require('./tools/build/pubspec');
var dartanalyzer = require('./tools/build/dartanalyzer');
var jsserve = require('./tools/build/jsserve');
var pubserve = require('./tools/build/pubserve');
var DART_SDK = require('./tools/build/dartdetect')(gulp);
// -----------------------
// configuration
var _COMPILER_CONFIG_JS_DEFAULT = {
sourceMaps: true, sourceMaps: true,
annotations: true, // parse annotations annotations: true, // parse annotations
types: true, // parse types types: true, // parse types
@ -25,388 +26,256 @@ var js2es5Options = {
modules: 'instantiate' modules: 'instantiate'
}; };
var js2es5OptionsProd = merge(true, js2es5Options, { var _HTLM_DEFAULT_SCRIPTS_JS = [
typeAssertions: false {src: '/deps/traceur-runtime.js', mimeType: 'text/javascript'},
}); {src: '/rtts_assert/lib/rtts_assert.js', mimeType: 'text/javascript'},
{src: '/deps/es6-module-loader-sans-promises.src.js', mimeType: 'text/javascript'},
var js2es5OptionsDev = merge(true, js2es5Options, { {src: '/deps/system.src.js', mimeType: 'text/javascript'},
typeAssertionModule: 'rtts_assert/rtts_assert', {src: '/deps/extension-register.js', mimeType: 'text/javascript'},
typeAssertions: true {src: '/deps/runtime_paths.js', mimeType: 'text/javascript'},
}); {
inline: 'System.import(\'$MODULENAME$\').then(function(m) { m.main(); }, console.log.bind(console))',
var js2dartOptions = { mimeType: 'text/javascript'
sourceMaps: true,
annotations: true, // parse annotations
types: true, // parse types
script: false, // parse as a module
memberVariables: true, // parse class fields
outputLanguage: 'dart'
};
var DART_SDK = false;
try {
which.sync('dart');
console.log('Dart SDK detected');
if (process.platform === 'win32') {
DART_SDK = {
PUB: 'pub.bat',
ANALYZER: 'dartanalyzer.bat'
};
} else {
DART_SDK = {
PUB: 'pub',
ANALYZER: 'dartanalyzer'
};
} }
} catch (e) { ];
console.log('Dart SDK is not available, Dart tasks will be skipped.');
var gulpTaskFn = gulp.task.bind(gulp);
gulp.task = function (name, deps, fn) {
if (name.indexOf('.dart') === -1) {
return gulpTaskFn(name, deps, fn);
} else {
return gulpTaskFn(name, function() {
console.log('Dart SDK is not available. Skipping task: ' + name);
});
}
};
}
var gulpTraceur = require('./tools/transpiler/gulp-traceur');
// --------- var CONFIG = {
// traceur runtime commands: {
pub: process.platform === 'win32' ? 'pub.bat' : 'pub',
gulp.task('jsRuntime/build', function() { dartanalyzer: process.platform === "win32" ? "dartanalyzer.bat" : "dartanalyzer"
var traceurRuntime = gulp.src([
gulpTraceur.RUNTIME_PATH,
"node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js",
"node_modules/systemjs/dist/system.src.js",
"node_modules/systemjs/lib/extension-register.js"
]).pipe(gulp.dest('build/js'));
return traceurRuntime;
});
// -----------------------
// modules
var sourceTypeConfigs = {
dart: {
transpileSrc: ['modules/**/*.js'],
// pub serve uses project_root/web for static serving.
htmlSrc: ['modules/*/src/**/*.html', 'modules/*/web/*.html'],
copySrc: ['modules/**/*.dart'],
outputDir: 'build/dart',
outputExt: 'dart',
mimeType: 'application/dart'
}, },
js: { dest: {
transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'], js: {
htmlSrc: ['modules/*/src/**/*.html'], all: 'dist/js',
copySrc: ['modules/**/*.es5'], dev: 'dist/js/dev',
outputDir: 'build/js', prod: 'dist/js/prod'
outputExt: 'js' },
dart: 'dist/dart'
},
srcFolderMapping: {
'default': 'lib',
// need a tmp folder as benchpress does not support
// inplace generation of the benchmarks...
'benchmark*/**': 'perf_tmp',
'example*/**': 'web'
},
deps: {
js: [
gulpTraceur.RUNTIME_PATH,
"node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js",
"node_modules/systemjs/dist/system.src.js",
"node_modules/systemjs/lib/extension-register.js",
"tools/build/runtime_paths.js",
"node_modules/angular/angular.js"
]
},
transpile: {
src: {
js: ['modules/**/*.js', 'modules/**/*.es6'],
dart: ['modules/**/*.js']
},
copy: {
js: ['modules/**/*.es5'],
dart: ['modules/**/*.dart']
},
options: {
js: {
dev: merge(true, _COMPILER_CONFIG_JS_DEFAULT, {
typeAssertionModule: 'rtts_assert/rtts_assert',
typeAssertions: true
}),
prod: merge(true, _COMPILER_CONFIG_JS_DEFAULT, {
typeAssertions: false
})
},
dart: {
sourceMaps: true,
annotations: true, // parse annotations
types: true, // parse types
script: false, // parse as a module
memberVariables: true, // parse class fields
outputLanguage: 'dart'
}
}
},
html: {
src: {
js: ['modules/*/src/**/*.html'],
dart: ['modules/*/src/**/*.html']
},
scriptsPerFolder: {
js: {
default: _HTLM_DEFAULT_SCRIPTS_JS,
'benchmarks_external/**':
[{ src: '/deps/angular.js', mimeType: 'text/javascript' }].concat(_HTLM_DEFAULT_SCRIPTS_JS)
},
dart: {
default: [
{src: '$MODULENAME_WITHOUT_PATH$.dart', mimeType: 'application/dart'},
{src: 'packages/browser/dart.js', mimeType: 'text/javascript'}
]
}
}
},
benchpress: {
configFile: {
content: 'module.exports=function(){};\n',
name: 'bp.conf.js'
},
mainHtmls: '*/perf_tmp/**/main.html',
outputFolderName: 'web'
},
pubspec: {
src: 'modules/*/pubspec.yaml'
} }
}; };
// ------------
// clean
gulp.task('modules/clean', function(cb) { gulp.task('build/clean.js', clean(gulp, gulpPlugins, {
del('build', cb); path: CONFIG.dest.js.all
}); }));
gulp.task('modules/build.dart/src', function() { gulp.task('build/clean.dart', clean(gulp, gulpPlugins, {
return createModuleTask(merge(sourceTypeConfigs.dart, {compilerOptions: js2dartOptions})); path: CONFIG.dest.dart
}); }));
gulp.task('modules/build.dart/pubspec', function() { // ------------
var outputDir = sourceTypeConfigs.dart.outputDir; // deps
var files = [];
var changedStream = gulp.src('modules/*/pubspec.yaml')
.pipe($.changed(outputDir)) // Only forward files that changed.
.pipe(through2.obj(function(file, enc, done) {
files.push(path.resolve(process.cwd(), outputDir, file.relative));
this.push(file);
done();
}))
.pipe(gulp.dest(outputDir));
// 1. We need to wait for all pubspecs to be present before executing
// `pub get` as it checks the folders of the dependencies!
// 2. We execute `pub get` commands sequentially to avoid race condition with pub cache
var promise = streamToPromise(changedStream).then(function() {
for (var i = 0; i < files.length; i++) {
(function (file) {
promise = promise.then(function() {
return processToPromise(spawn(DART_SDK.PUB, ['get'], {
stdio: 'inherit',
cwd: path.dirname(file)
}));
});
})(files[i]);
}
});
return promise; gulp.task('build/deps.js.dev', deps(gulp, gulpPlugins, {
src: CONFIG.deps.js,
dest: CONFIG.dest.js.dev
}));
}); gulp.task('build/deps.js.prod', deps(gulp, gulpPlugins, {
src: CONFIG.deps.js,
dest: CONFIG.dest.js.prod
}));
function processToPromise(process) { // ------------
var defer = Q.defer(); // transpile
process.on('close', function(code) {
if (code) {
defer.reject(code);
} else {
defer.resolve();
}
});
return defer.promise;
}
function streamToPromise(stream) { gulp.task('build/transpile.js.dev', transpile(gulp, gulpPlugins, {
var defer = Q.defer(); src: CONFIG.transpile.src.js,
stream.on('end', defer.resolve); copy: CONFIG.transpile.copy.js,
stream.on('error', defer.reject); dest: CONFIG.dest.js.dev,
return defer.promise; outputExt: 'js',
} options: CONFIG.transpile.options.js.dev,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.dart', ['modules/build.dart/src', 'modules/build.dart/pubspec']); gulp.task('build/transpile.js.prod', transpile(gulp, gulpPlugins, {
src: CONFIG.transpile.src.js,
copy: CONFIG.transpile.copy.js,
dest: CONFIG.dest.js.prod,
outputExt: 'js',
options: CONFIG.transpile.options.js.prod,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.dev.js', function() { gulp.task('build/transpile.dart', transpile(gulp, gulpPlugins, {
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsDev})); src: CONFIG.transpile.src.dart,
}); copy: CONFIG.transpile.copy.dart,
dest: CONFIG.dest.dart,
outputExt: 'dart',
options: CONFIG.transpile.options.dart,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.prod.js', function() { // ------------
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsProd})); // html
});
function renameSrcToLib(file) { gulp.task('build/html.js.dev', html(gulp, gulpPlugins, {
file.dirname = file.dirname.replace(/\bsrc\b/, 'lib'); src: CONFIG.html.src.js,
} dest: CONFIG.dest.js.dev,
srcFolderMapping: CONFIG.srcFolderMapping,
scriptsPerFolder: CONFIG.html.scriptsPerFolder.js
}));
function renameEs5ToJs(file) { gulp.task('build/html.js.prod', html(gulp, gulpPlugins, {
if (file.extname == '.es5') { src: CONFIG.html.src.js,
file.extname = '.js'; dest: CONFIG.dest.js.prod,
} srcFolderMapping: CONFIG.srcFolderMapping,
} scriptsPerFolder: CONFIG.html.scriptsPerFolder.js
}));
function createModuleTask(sourceTypeConfig) { gulp.task('build/html.dart', html(gulp, gulpPlugins, {
var transpile = gulp.src(sourceTypeConfig.transpileSrc) src: CONFIG.html.src.dart,
.pipe($.rename({extname: '.'+sourceTypeConfig.outputExt})) dest: CONFIG.dest.dart,
.pipe($.rename(renameSrcToLib)) srcFolderMapping: CONFIG.srcFolderMapping,
.pipe(gulpTraceur(sourceTypeConfig.compilerOptions, file2moduleName)) scriptsPerFolder: CONFIG.html.scriptsPerFolder.dart
.pipe(gulp.dest(sourceTypeConfig.outputDir)); }));
var copy = gulp.src(sourceTypeConfig.copySrc)
.pipe($.rename(renameSrcToLib))
.pipe($.rename(renameEs5ToJs))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
// TODO: provide the list of files to the template
// automatically!
var html = gulp.src(sourceTypeConfig.htmlSrc)
.pipe($.rename(renameSrcToLib))
.pipe($.ejs({
type: sourceTypeConfig.outputExt
}))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
return mergeStreams(transpile, copy, html); // ------------
} // benchpress
gulp.task('build/benchpress.js.dev', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.js.dev,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
gulp.task('build/benchpress.js.prod', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.js.prod,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
gulp.task('build/benchpress.dart', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.dart,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
// ------------
// pubspec
gulp.task('build/pubspec.dart', pubspec(gulp, gulpPlugins, {
src: CONFIG.pubspec.src,
dest: CONFIG.dest.dart,
command: DART_SDK.PUB
}));
// ------------
// pubspec
gulp.task('build/analyze.dart', dartanalyzer(gulp, gulpPlugins, {
dest: CONFIG.dest.dart,
command: DART_SDK.ANALYZER,
srcFolderMapping: CONFIG.srcFolderMapping
}));
// ------------------ // ------------------
// ANALYZE // web servers
gulp.task('serve.js.dev', jsserve(gulp, gulpPlugins, {
path: CONFIG.dest.js.dev
}));
gulp.task('analyze/analyzer.dart', function(done) { gulp.task('serve.js.prod', jsserve(gulp, gulpPlugins, {
var pubSpecs = [].slice.call(glob.sync('build/dart/*/pubspec.yaml', { path: CONFIG.dest.js.prod
cwd: __dirname }));
}));
var tempFile = '_analyzer.dart';
// analyze in parallel!
return Q.all(pubSpecs.map(function(pubSpecFile) {
var dir = path.dirname(pubSpecFile);
var srcFiles = [].slice.call(glob.sync('lib/**/*.dart', {
cwd: dir
}));
var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {
cwd: dir
}));
var analyzeFile = ['library _analyzer;'];
srcFiles.concat(testFiles).forEach(function(fileName, index) {
if (fileName !== tempFile) {
analyzeFile.push('import "./'+fileName+'" as mod'+index+';');
}
});
fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n'));
var defer = Q.defer();
analyze(dir, defer.makeNodeResolver());
return defer.promise;
}));
function analyze(dirName, done) { gulp.task('serve/examples.dart', pubserve(gulp, gulpPlugins, {
var stream = spawn(DART_SDK.ANALYZER, ['--fatal-warnings', tempFile], { command: DART_SDK.PUB,
// inherit stdin and stderr, but filter stdout path: CONFIG.dest.dart + '/examples'
stdio: [process.stdin, 'pipe', process.stderr], }));
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.stdout,
output: process.stdout,
terminal: false
});
var hintCount = 0;
rl.on('line', function(line) {
if (line.match(/Unused import/)) {
return;
}
if (line.match(/\[hint\]/)) {
hintCount++;
}
console.log(dirName + ':' + line);
});
stream.on('close', function(code) {
var error;
if (code !== 0) {
error = new Error('Dartanalyzer failed with exit code ' + code);
}
if (hintCount > 0) {
error = new Error('Dartanalyzer showed hints');
}
done(error);
});
}
});
gulp.task('serve/benchmarks.dart', pubserve(gulp, gulpPlugins, {
command: DART_SDK.PUB,
path: CONFIG.dest.dart + '/benchmarks'
}));
gulp.task('serve/benchmarks_external.dart', pubserve(gulp, gulpPlugins, {
// ------------------ command: DART_SDK.PUB,
// BENCHMARKS JS path: CONFIG.dest.dart + '/benchmarks_external'
}));
gulp.task('benchmarks/internal.benchpress.js', function () {
benchpress.build({
benchmarksPath: 'build/js/benchmarks/lib',
buildPath: 'build/benchpress/js'
})
});
gulp.task('benchmarks/external.benchpress.js', function () {
benchpress.build({
benchmarksPath: 'build/js/benchmarks_external/lib',
buildPath: 'build/benchpress/js'
})
});
gulp.task('benchmarks/internal.js', function() {
runSequence(
['jsRuntime/build', 'modules/build.prod.js'],
'benchmarks/internal.benchpress.js'
);
});
gulp.task('benchmarks/external.js', function() {
runSequence(
['jsRuntime/build', 'modules/build.prod.js'],
'benchmarks/external.benchpress.js'
);
});
// ------------------
// BENCHMARKS DART
function benchmarkDart2Js(buildPath, done) {
mergeStreams(dart2jsStream(), bpConfStream())
.on('end', function() {
runBenchpress();
done();
});
function dart2jsStream() {
return gulp.src([
buildPath+"/lib/**/benchmark.dart"
]).pipe($.shell(['dart2js --package-root="'+buildPath+'/packages" -o "<%= file.path %>.js" <%= file.path %>']));
}
function bpConfStream() {
var bpConfContent = "module.exports = function(c) {c.set({scripts: [{src: 'benchmark.dart.js'}]});}";
var createBpConfJs = es.map(function(file, cb) {
var dir = path.dirname(file.path);
fs.writeFileSync(path.join(dir, "bp.conf.js"), bpConfContent);
cb();
});
return gulp.src([
buildPath+"/lib/**/benchmark.dart"
]).pipe(createBpConfJs);
}
function runBenchpress() {
benchpress.build({
benchmarksPath: buildPath+'/lib',
buildPath: 'build/benchpress/dart'
});
}
}
gulp.task('benchmarks/internal.dart', ['modules/build.dart'], function(done) {
benchmarkDart2Js('build/dart/benchmarks', done);
});
gulp.task('benchmarks/external.dart', ['modules/build.dart'], function(done) {
benchmarkDart2Js('build/dart/benchmarks_external', done);
});
gulp.task('benchmarks/build.dart', ['benchmarks/internal.dart', 'benchmarks/external.dart']);
// ------------------
// WEB SERVERS
gulp.task('serve', function() {
$.connect.server({
root: [__dirname+'/build'],
port: 8000,
livereload: false,
open: false,
middleware: function() {
return [function(req, resp, next){
if (req.url.match(/\.dart$/)) {
resp.setHeader("Content-Type", "application/dart");
}
next();
}];
}
})();
});
gulp.task('examples/pub.serve', function(done) {
spawn(DART_SDK.PUB, ['serve'], {cwd: 'build/dart/examples', stdio: 'inherit'})
.on('done', done);
});
// --------------
// general targets
gulp.task('clean', ['modules/clean']);
gulp.task('build', function(done) {
runSequence(
// parallel
['jsRuntime/build', 'modules/build.dart', 'modules/build.dev.js'],
// sequential
'analyze/analyzer.dart'
);
});
gulp.task('analyze', function(done) {
runSequence('analyze/analyzer.dart');
});
// -------------- // --------------
// doc generation // doc generation
@ -435,12 +304,12 @@ gulp.task('docs/bower', function() {
gulp.task('docs/assets', ['docs/bower'], function() { gulp.task('docs/assets', ['docs/bower'], function() {
return gulp.src('docs/bower_components/**/*') return gulp.src('docs/bower_components/**/*')
.pipe(gulp.dest('build/docs/lib')); .pipe(gulp.dest('dist/docs/lib'));
}); });
gulp.task('docs/app', function() { gulp.task('docs/app', function() {
return gulp.src('docs/app/**/*') return gulp.src('docs/app/**/*')
.pipe(gulp.dest('build/docs')); .pipe(gulp.dest('dist/docs'));
}); });
gulp.task('docs', ['docs/assets', 'docs/app', 'docs/dgeni']); gulp.task('docs', ['docs/assets', 'docs/app', 'docs/dgeni']);
@ -456,8 +325,38 @@ gulp.task('docs/test', function () {
var webserver = require('gulp-webserver'); var webserver = require('gulp-webserver');
gulp.task('docs/serve', function() { gulp.task('docs/serve', function() {
gulp.src('build/docs/') gulp.src('dist/docs/')
.pipe(webserver({ .pipe(webserver({
fallback: 'index.html' fallback: 'index.html'
})); }));
}); });
// -----------------
// orchestrated targets
gulp.task('build.dart', function() {
return runSequence(
['build/transpile.dart', 'build/html.dart', 'build/pubspec.dart'],
'build/benchpress.dart',
'build/analyze.dart'
);
});
gulp.task('build.js.dev', function() {
return runSequence(
['build/deps.js.dev', 'build/transpile.js.dev', 'build/html.js.dev'],
'build/benchpress.js.dev'
);
});
gulp.task('build.js.prod', function() {
return runSequence(
['build/deps.js.prod', 'build/transpile.js.prod', 'build/html.js.prod'],
'build/benchpress.js.dev'
);
});
gulp.task('build.js', ['build.js.dev', 'build.js.prod']);
gulp.task('clean', ['build/clean.js', 'build/clean.dart']);
gulp.task('build', ['build.js', 'build.dart']);

View File

@ -1,6 +1,6 @@
// Karma configuration // Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT) // Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
var file2moduleName = require('./file2modulename'); var file2moduleName = require('./tools/build/file2modulename');
module.exports = function(config) { module.exports = function(config) {
config.set({ config.set({

View File

@ -1,6 +1,6 @@
// Karma configuration // Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT) // Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
var file2moduleName = require('./file2modulename'); var file2moduleName = require('./tools/build/file2modulename');
module.exports = function(config) { module.exports = function(config) {
config.set({ config.set({
@ -20,7 +20,7 @@ module.exports = function(config) {
'node_modules/systemjs/dist/system.src.js', 'node_modules/systemjs/dist/system.src.js',
'node_modules/systemjs/lib/extension-register.js', 'node_modules/systemjs/lib/extension-register.js',
'file2modulename.js', 'tools/build/file2modulename.js',
'test-main.js' 'test-main.js'
], ],

View File

@ -12,3 +12,6 @@ dependencies:
path: ../core path: ../core
change_detection: change_detection:
path: ../change_detection path: ../change_detection
benchpress:
path: ../benchpress
browser: '>=0.10.0 <0.11.0'

View File

@ -1,8 +0,0 @@
library benchmark;
import './change_detection_benchmark.dart' as cdb;
import 'dart:js' as js;
main () {
cdb.run();
}

View File

@ -1,3 +0,0 @@
System.import('benchmarks/change_detection/change_detection_benchmark').then(function (bm) {
bm.run();
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -3,7 +3,7 @@ import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer'; import {Lexer} from 'change_detection/parser/lexer';
import {reflector} from 'reflection/reflection'; import {reflector} from 'reflection/reflection';
import {isPresent} from 'facade/lang'; import {isPresent} from 'facade/lang';
import {benchmark, benchmarkStep} from '../benchpress'; import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import { import {
ChangeDetector, ChangeDetector,
@ -153,7 +153,7 @@ function setUpChangeDetection() {
return new ChangeDetector(parentRange); return new ChangeDetector(parentRange);
} }
export function run () { export function main () {
setUpReflector(); setUpReflector();
benchmark(`Baseline`, function () { benchmark(`Baseline`, function () {

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1 @@
export {main} from './change_detection_benchmark';

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,9 +0,0 @@
library compiler_benchmark;
import './selector_benchmark.dart' as sbm;
import './compiler_benchmark.dart' as cbm;
main () {
sbm.main();
cbm.main();
}

View File

@ -1,8 +0,0 @@
Promise.all([
System.import('benchmarks/compiler/selector_benchmark'),
System.import('benchmarks/compiler/compiler_benchmark')
]).then(function (benchmarks) {
benchmarks.forEach(function(bm) {
bm.main();
});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -1,7 +1,7 @@
import {benchmark, benchmarkStep} from '../benchpress'; import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import {DOM, document} from 'facade/dom'; import {DOM, document} from 'facade/dom';
import {isBlank} from 'facade/lang'; import {isBlank, Type} from 'facade/lang';
import {MapWrapper} from 'facade/collection'; import {MapWrapper} from 'facade/collection';
import {AnnotatedType} from 'core/compiler/annotated_type'; import {AnnotatedType} from 'core/compiler/annotated_type';
@ -61,7 +61,7 @@ function setup() {
}); });
reflector.registerGetters({ reflector.registerGetters({
"inter0": (a) => a.inter0, "inter1": (a) => a.inter1, "inter0": (a) => a.inter0, "inter1": (a) => a.inter1,
"inter2": (a) => a.inter2, "inter3": (a) => a.inter3, "inter4": (a) => a.inter4, "inter2": (a) => a.inter2, "inter3": (a) => a.inter3, "inter4": (a) => a.inter4,
"value0": (a) => a.value0, "value1": (a) => a.value1, "value0": (a) => a.value0, "value1": (a) => a.value1,
@ -111,7 +111,7 @@ export function main() {
benchmark(`instantiate 5*${COUNT} element with bindings`, function() { benchmark(`instantiate 5*${COUNT} element with bindings`, function() {
var template = loadTemplate('templateWithBindings', COUNT); var template = loadTemplate('templateWithBindings', COUNT);
var protoView = compiler.compileWithCache(null, annotatedComponent, template); var protoView = compiler.compileWithCache(null, annotatedComponent, template);
var rootRecordRange = new ProtoRecordRange().instantiate(null, new Object()); var rootRecordRange = new ProtoRecordRange().instantiate(null, null);
benchmarkStep('run', function() { benchmarkStep('run', function() {
var view = protoView.instantiate(null, null, null); var view = protoView.instantiate(null, null, null);

View File

@ -1,3 +1,5 @@
$SCRIPTS$
<template id="templateNoBindings"> <template id="templateNoBindings">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4"> <div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4"> <div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">

View File

@ -0,0 +1,7 @@
import * as sbm from './selector_benchmark';
import * as cbm from './compiler_benchmark';
export function main() {
sbm.main();
cbm.main();
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,4 +1,4 @@
import {benchmark, benchmarkStep} from '../benchpress'; import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import {SelectorMatcher} from "core/compiler/selector"; import {SelectorMatcher} from "core/compiler/selector";
import {CssSelector} from "core/compiler/selector"; import {CssSelector} from "core/compiler/selector";

View File

@ -1,11 +0,0 @@
library injector_get_benchmark;
import './injector_instantiate_benchmark.dart' as b;
import 'dart:js' as js;
main () {
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "Injector.instantiate",
"fn": new js.JsFunction.withThis((_) => b.run())
}));
}

View File

@ -1,15 +0,0 @@
System.import('benchmarks/di/injector_get_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (token)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_by_key_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (key)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_child_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (grand x 5 child)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_instantiate_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.instantiate', fn: bm.run});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1,24 @@
import * as injector_get_benchmark from './injector_get_benchmark';
import * as injector_get_by_key_benchmark from './injector_get_by_key_benchmark';
import * as injector_get_child_benchmark from './injector_get_child_benchmark';
import * as injector_instantiate_benchmark from './injector_instantiate_benchmark';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
export function main() {
benchmark(`Injector.get (token)`, function() {
benchmarkStep('run', injector_get_benchmark.run);
});
benchmark(`Injector.get (key)`, function() {
benchmarkStep('run', injector_get_by_key_benchmark.run);
});
benchmark(`Injector.get (grand x 5 child)`, function() {
benchmarkStep('run', injector_get_child_benchmark.run);
});
benchmark(`Injector.instantiate`, function() {
benchmarkStep('run', injector_instantiate_benchmark.run);
});
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,23 +0,0 @@
library element_injector_benchmark;
import './instantiate_benchmark.dart' as ib;
import './instantiate_benchmark_codegen.dart' as ibc;
import './instantiate_directive_benchmark.dart' as idb;
import 'dart:js' as js;
main () {
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiate + instantiateDirectives",
"fn": new js.JsFunction.withThis((_) => ib.run())
}));
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiateDirectives",
"fn": new js.JsFunction.withThis((_) => idb.run())
}));
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiate + instantiateDirectives (codegen)",
"fn": new js.JsFunction.withThis((_) => ibc.run())
}));
}

View File

@ -1,11 +0,0 @@
System.import('benchmarks/element_injector/instantiate_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiate + instantiateDirectives', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/element_injector/instantiate_directive_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiateDirectives', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/element_injector/instantiate_benchmark_codegen').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiate + instantiateDirectives (codegen)', fn: bm.run});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1,19 @@
import * as instantiate_benchmark from './instantiate_benchmark';
import * as instantiate_directive_benchmark from './instantiate_directive_benchmark';
import * as instantiate_benchmark_codegen from './instantiate_benchmark_codegen';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
export function main() {
benchmark(`ElementInjector.instantiate + instantiateDirectives`, function() {
benchmarkStep('run', instantiate_benchmark.run);
});
benchmark(`ElementInjector.instantiateDirectives`, function() {
benchmarkStep('run', instantiate_directive_benchmark.run);
});
benchmark(`ElementInjector.instantiate + instantiateDirectives (codegen)`, function() {
benchmarkStep('run', instantiate_benchmark_codegen.run);
});
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -3,3 +3,5 @@ environment:
sdk: '>=1.4.0' sdk: '>=1.4.0'
dependencies: dependencies:
angular: ">=1.0.0 <2.0.0" angular: ">=1.0.0 <2.0.0"
benchpress:
path: ../benchpress

View File

@ -1,63 +0,0 @@
library benchmarks.benchpress;
import 'dart:js' as js;
import 'dart:html';
import 'dart:async';
// TODO: move the functionality of this module into benchpress and replace this
// file with a Dart wrapper!
var _benchmarkNames = [];
_benchmarkId(index) {
return "benchmark${index}";
}
_useBenchmark(index) {
var search = window.location.search;
if (search.length > 0) {
search = search.substring(1);
}
if (search.length > 0) {
return search == _benchmarkId(index);
} else {
return true;
}
}
_onLoad(callback) {
var isReady = document.readyState == 'complete';
if (isReady) {
Timer.run(callback);
} else {
window.addEventListener('load', (event) => callback(), false);
}
}
_createBenchmarkMenu() {
var div = document.createElement('div');
div.innerHtml += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
for (var i=0; i<_benchmarkNames.length; i++) {
var activeClass = _useBenchmark(i) ? 'active' : '';
div.innerHtml += '<a class="btn btn-default ${activeClass}" href="?${_benchmarkId(i)}">${_benchmarkNames[i]}</a>';
}
document.body.insertBefore(div, document.body.childNodes[0]);
}
benchmark(name, stepsCreationCallback) {
_benchmarkNames.add(name);
if (_benchmarkNames.length == 2) {
_onLoad(_createBenchmarkMenu);
}
if (_useBenchmark(_benchmarkNames.length-1)) {
stepsCreationCallback();
}
}
benchmarkStep(name, callback) {
var benchmarkName = _benchmarkNames[_benchmarkNames.length-1];
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": benchmarkName + '#' + name,
"fn": new js.JsFunction.withThis((_) => callback())
}));
}

View File

@ -1,55 +0,0 @@
// TODO: move the functionality of this module into benchpress itself!
var benchmarkNames = [];
function benchmarkId(index) {
return 'benchmark' + index;
}
function useBenchmark(index) {
var search = window.location.search;
if (search.length > 0) {
search = search.substring(1);
}
if (search.length > 0) {
return search == benchmarkId(index);
} else {
return true;
}
}
function onLoad(callback) {
var isReady = document.readyState === 'complete';
if (isReady) {
window.setTimeout(callback);
} else {
window.addEventListener('load', callback, false);
}
}
function createBenchmarkMenu() {
var div = document.createElement('div');
div.innerHTML += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
for (var i=0; i<benchmarkNames.length; i++) {
var activeClass = useBenchmark(i) ? 'active' : '';
div.innerHTML += ('<a class="btn btn-default '+activeClass+'" href="?'+benchmarkId(i)+'">'+benchmarkNames[i]+'</a>');
}
document.body.insertBefore(div, document.body.childNodes[0]);
}
export function benchmark(name, stepsCreationCallback) {
benchmarkNames.push(name);
if (benchmarkNames.length === 2) {
onLoad(createBenchmarkMenu);
}
if (useBenchmark(benchmarkNames.length-1)) {
stepsCreationCallback();
}
}
export function benchmarkStep(name, callback) {
var benchmarkName = benchmarkNames[benchmarkNames.length-1];
window.benchmarkSteps.push({
name: benchmarkName + '#' + name, fn: callback
});
}

View File

@ -1,7 +0,0 @@
Promise.all([
System.import('benchmarks_external/compiler/compiler_benchmark_ng13')
]).then(function (benchmarks) {
benchmarks.forEach(function(bm) {
bm.main();
});
}, console.log.bind(console));

View File

@ -1,12 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -1,6 +1,6 @@
import 'package:angular/angular.dart'; import 'package:angular/angular.dart';
import 'package:angular/application_factory_static.dart'; import 'package:angular/application_factory_static.dart';
import '../benchpress.dart'; import 'package:benchpress/benchpress.dart';
import 'dart:html'; import 'dart:html';
var COUNT = 30; var COUNT = 30;

View File

@ -1,4 +1,4 @@
import {benchmark, benchmarkStep} from '../benchpress'; import {benchmark, benchmarkStep} from 'benchpress/benchpress';
var COUNT = 30; var COUNT = 30;
var $compile; var $compile;

View File

@ -0,0 +1 @@
export {main} from './compiler_benchmark_ng13';

View File

@ -1,3 +1,5 @@
$SCRIPTS$
<template id="templateNoBindings"> <template id="templateNoBindings">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4"> <div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4"> <div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks_external/*': '/js/benchmarks_external/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -0,0 +1,4 @@
name: benchpress
environment:
sdk: '>=1.4.0'
dependencies:

View File

@ -1,23 +1,11 @@
<!doctype html> <!doctype html>
<html> <html>
<title>Hello Angular 2.0 (JS)</title> <title>Hello Angular 2.0 (Reflection)</title>
<body> <body>
<hello-app> <hello-app>
Loading... Loading...
</hello-app> </hello-app>
<script src="../../../traceur-runtime.js"></script> $SCRIPTS$
<script src="../../../rtts_assert/lib/rtts_assert.js"></script>
<script src="../../../es6-module-loader-sans-promises.src.js"></script>
<script src="../../../system.src.js"></script>
<script src="../../../extension-register.js"></script>
<script src="main.js"></script>
</body> </body>
</html> </html>
<!-- to run do:
1) gulp build
2) gulp serve
3) open localhost:8000/js/examples/lib/hello_world/ in chrome.
TODO(rado): merge with Darts's index.html in ../../web/
-->

View File

@ -0,0 +1,11 @@
<!doctype html>
<html>
<title>Hello Angular 2.0 (Static)</title>
<body>
<hello-app>
Loading...
</hello-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,4 +1,4 @@
import * as app from './app'; import * as app from './index';
import {Component, Decorator, TemplateConfig, NgElement} from 'core/core'; import {Component, Decorator, TemplateConfig, NgElement} from 'core/core';
import {Parser} from 'change_detection/parser/parser'; import {Parser} from 'change_detection/parser/parser';

View File

@ -1,23 +0,0 @@
register(System);
System.baseURL = '../../../';
// So that we can import packages like `core/foo`, instead of `core/lib/foo`.
System.paths = {
'core/*': './core/lib/*.js',
'change_detection/*': './change_detection/lib/*.js',
'facade/*': './facade/lib/*.js',
'di/*': './di/lib/*.js',
'reflection/*': './reflection/lib/*.js',
'rtts_assert/*': './rtts_assert/lib/*.js',
'examples/*': './examples/lib/*.js'
};
// TODO(rado): templatize and make reusable for all examples
System.import('examples/hello_world/app').then(function(m) {
m.main();
}, function(e) {
console.error(e.stack || e);
});

View File

@ -1,20 +0,0 @@
<!doctype html>
<html>
<head>
<title>Hello Angular 2.0 (Dart)</title>
<script type="application/dart" src="main.dart"></script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<hello-app>
Loading...
</hello-app>
</body>
</html>
<!-- to run do:
1) gulp build
2) gulp examples/pub.serve
3) open localhost:8080 in dartium or chrome.
TODO(rado): merge with JS's index.html in ../src/hello_world/
-->

View File

@ -1,20 +0,0 @@
<!doctype html>
<html>
<head>
<title>Hello Angular 2.0 (Dart Static)</title>
<script type="application/dart" src="main_static.dart"></script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<hello-app>
Loading...
</hello-app>
</body>
</html>
<!-- to run do:
1) gulp build
2) gulp examples/pub.serve
3) open localhost:8080/index_static.html in dartium or chrome.
TODO(rado): merge with JS's index.html in ../src/hello_world/
-->

View File

@ -1,11 +0,0 @@
import 'package:examples/hello_world/app.dart' as HelloWorldApp;
import 'package:reflection/reflection_capabilities.dart';
import 'package:reflection/reflection.dart';
// TODO(rado): templatize and make reusable for all examples.
main() {
// enable mirrors and reflection.
// see static_app.js for an example of a static app.
reflector.reflectionCapabilities = new ReflectionCapabilities();
HelloWorldApp.main();
}

View File

@ -1,4 +0,0 @@
import 'packages/examples/hello_world/static_app.dart' as HelloWorldApp;
// TODO(rado): templatize and make reusable for all examples.
main() => HelloWorldApp.main();

View File

@ -1,12 +0,0 @@
/**
* This is a special facade used to bootstrap JS automatically.
* (In contrast to door wheere the user needs to explicitly call into angular.)
* This file is appened to AngularJS and needs to be written in ES5.
*/
(function(window, document) {
document.addEventListener('DOMContentLoaded', bootstrap, false);
function bootstrap() {
// TODO(misko): load application factory from the module system.
applicationFactory().run();
}
})(window, document);

View File

@ -40,6 +40,8 @@
"gulp-rename": "^1.2.0", "gulp-rename": "^1.2.0",
"gulp-shell": "^0.2.10", "gulp-shell": "^0.2.10",
"gulp-webserver": "^0.8.7", "gulp-webserver": "^0.8.7",
"angular": "1.3.5",
"minimatch": "^2.0.1",
"lodash": "^2.4.1" "lodash": "^2.4.1"
} }
} }

View File

@ -2,18 +2,6 @@ name: angular
environment: environment:
sdk: '>=1.4.0' sdk: '>=1.4.0'
dependencies: dependencies:
examples:
path: build/dart/examples
test_lib:
path: build/dart/test_lib
facade:
path: build/dart/facade
core:
path: build/dart/core
di:
path: build/dart/di
change_detection:
path: build/dart/change_detection
dev_dependencies: dev_dependencies:
guinness: ">=0.1.16 <0.2.0" guinness: ">=0.1.16 <0.2.0"

View File

@ -8,10 +8,6 @@ SCRIPT_DIR=$(dirname $0)
cd $SCRIPT_DIR/../.. cd $SCRIPT_DIR/../..
source ./scripts/env.sh source ./scripts/env.sh
# For some reason, this task fails on Travis when run as a part of the `gulp build`.
# It runs `pub get` which fails to read the `pubspec.yml` (created earlier by the task).
./node_modules/.bin/gulp modules/build.dart/pubspec
./node_modules/.bin/gulp build ./node_modules/.bin/gulp build
pub install pub install

39
tools/build/benchpress.js Normal file
View File

@ -0,0 +1,39 @@
var util = require('./util');
var path = require('path');
var benchpress = require('angular-benchpress/lib/cli');
var through2 = require('through2');
var Q = require('q');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
var benchmarkParentFolders = {};
var createBpConfStream = util.streamToPromise(
gulp.src(path.join(config.buildDir, config.mainHtmls))
.pipe(through2.obj(function(file, enc, done) {
file.path = path.join(path.dirname(file.path), config.configFile.name);
file.contents = new Buffer(config.configFile.content);
this.push(file);
benchmarkParentFolders[getParentFolder(file.path)] = true;
done();
}))
.pipe(gulp.dest(config.buildDir)));
return createBpConfStream.then(function() {
return Promise.all(Object.keys(benchmarkParentFolders).map(function(benchmarkParentPath) {
var defer = Q.defer();
benchpress.build({
benchmarksPath: benchmarkParentPath,
buildPath: path.join(benchmarkParentPath, path.join('../', config.outputFolderName))
}, defer.makeNodeResolver());
return defer.promise;
}));
});
};
};
function getParentFolder(file) {
var parts = path.dirname(file).split(path.sep);
parts.pop();
return parts.join(path.sep);
}

8
tools/build/clean.js Normal file
View File

@ -0,0 +1,8 @@
var del = require('del');
module.exports = function(gulp, plugins, config) {
return function(done) {
del(config.path, done);
};
};

View File

@ -0,0 +1,70 @@
var Q = require('q');
var readline = require('readline');
var spawn = require('child_process').spawn;
var path = require('path');
var glob = require('glob');
var fs = require('fs');
var util = require('./util');
module.exports = function(gulp, plugins, config) {
return function() {
var dartModuleFolders = [].slice.call(glob.sync(config.dest + '/*'));
var tempFile = '_analyzer.dart';
// analyze in parallel!
return Q.all(dartModuleFolders.map(function(dir) {
var srcFiles = [].slice.call(glob.sync(util.filterByFile(config.srcFolderMapping, dir) + '/**/*.dart', {
cwd: dir
}));
var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {
cwd: dir
}));
var analyzeFile = ['library _analyzer;'];
srcFiles.concat(testFiles).forEach(function(fileName, index) {
if (fileName !== tempFile) {
analyzeFile.push('import "./'+fileName+'" as mod'+index+';');
}
});
fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n'));
var defer = Q.defer();
analyze(dir, defer.makeNodeResolver());
return defer.promise;
}));
function analyze(dirName, done) {
var stream = spawn(config.command, ['--fatal-warnings', tempFile], {
// inherit stdin and stderr, but filter stdout
stdio: [process.stdin, 'pipe', process.stderr],
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.stdout,
output: process.stdout,
terminal: false
});
var hintCount = 0;
rl.on('line', function(line) {
if (line.match(/Unused import/)) {
return;
}
if (line.match(/\[hint\]/)) {
hintCount++;
}
console.log(dirName + ':' + line);
});
stream.on('close', function(code) {
var error;
if (code !== 0) {
error = new Error('Dartanalyzer failed with exit code ' + code);
}
if (hintCount > 0) {
error = new Error('Dartanalyzer showed hints');
}
done(error);
});
}
};
};

33
tools/build/dartdetect.js Normal file
View File

@ -0,0 +1,33 @@
var which = require('which');
module.exports = function(gulp) {
var DART_SDK = false;
try {
which.sync('dart');
console.log('Dart SDK detected');
if (process.platform === 'win32') {
DART_SDK = {
PUB: 'pub.bat',
ANALYZER: 'dartanalyzer.bat'
};
} else {
DART_SDK = {
PUB: 'pub',
ANALYZER: 'dartanalyzer'
};
}
} catch (e) {
console.log('Dart SDK is not available, Dart tasks will be skipped.');
var gulpTaskFn = gulp.task.bind(gulp);
gulp.task = function (name, deps, fn) {
if (name.indexOf('.dart') === -1) {
return gulpTaskFn(name, deps, fn);
} else {
return gulpTaskFn(name, function() {
console.log('Dart SDK is not available. Skipping task: ' + name);
});
}
};
}
return DART_SDK;
}

8
tools/build/deps.js Normal file
View File

@ -0,0 +1,8 @@
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
return gulp.src(config.src)
.pipe(gulp.dest(path.join(config.dest, 'deps')));
};
};

View File

@ -5,6 +5,8 @@ function file2moduleName(filePath) {
.replace(/.*\/tools\//, '') .replace(/.*\/tools\//, '')
// module name should not include `src`, `test`, `lib` // module name should not include `src`, `test`, `lib`
.replace(/\/src\//, '/') .replace(/\/src\//, '/')
.replace(/\/web\//, '/')
.replace(/\/perf_tmp\//, '/')
.replace(/\/lib\//, '/') .replace(/\/lib\//, '/')
// module name should not have a suffix // module name should not have a suffix
.replace(/\.\w*$/, ''); .replace(/\.\w*$/, '');

32
tools/build/html.js Normal file
View File

@ -0,0 +1,32 @@
var util = require('./util');
var file2moduleName = require('./file2modulename');
var through2 = require('through2');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
return gulp.src(config.src)
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(through2.obj(function(file, enc, done) {
var fileName = file.relative;
var moduleName = file2moduleName(fileName);
var moduleNameWithoutPath = path.basename(moduleName);
var scripts = util.filterByFile(config.scriptsPerFolder, fileName).map(function(script) {
var scriptTag;
if (script.src) {
scriptTag = '<script src="'+script.src+'" type="'+script.mimeType+'"></script>';
} else {
scriptTag = '<script type="'+script.mimeType+'">'+script.inline+'</script>';
}
return scriptTag
.replace('$MODULENAME_WITHOUT_PATH$', moduleNameWithoutPath)
.replace('$MODULENAME$', moduleName)
}).join('\n');
file.contents = new Buffer(file.contents.toString().replace('$SCRIPTS$', scripts));
this.push(file);
done();
}))
.pipe(gulp.dest(config.dest));
};
};

10
tools/build/jsserve.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = function(gulp, plugins, config) {
return function() {
plugins.connect.server({
root: [__dirname+'/../../'+config.path],
port: 8000,
livereload: false,
open: false
})();
};
};

11
tools/build/pubserve.js Normal file
View File

@ -0,0 +1,11 @@
var util = require('./util');
var spawn = require('child_process').spawn;
module.exports = function(gulp, plugins, config, module) {
return function() {
return util.streamToPromise(spawn(config.command, ['serve'], {
cwd: config.path, stdio: 'inherit'
}));
};
};

37
tools/build/pubspec.js Normal file
View File

@ -0,0 +1,37 @@
var util = require('./util');
var Q = require('q');
var spawn = require('child_process').spawn;
var through2 = require('through2');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
var files = [];
var pubSpecCopy = util.streamToPromise(gulp.src(config.src)
.pipe(plugins.changed(config.dest)) // Only forward files that changed.
.pipe(through2.obj(function(file, enc, done) {
files.push(path.resolve(process.cwd(), config.dest, file.relative));
this.push(file);
done();
}))
.pipe(gulp.dest(config.dest)));
// We need to wait for all pubspecs to be present before executing
// `pub get` as it checks the folders of the dependencies!
// We need to execute pubspec serially as otherwise we can get into trouble
// with the pub cache...
return pubSpecCopy.then(nextFile);
function nextFile() {
if (!files.length) {
return;
}
var file = files.shift();
return util.processToPromise(spawn(config.command, ['get'], {
stdio: 'inherit',
cwd: path.dirname(file)
})).then(nextFile);
}
};
};

View File

@ -0,0 +1,14 @@
System.paths = {
'core/*': '/core/lib/*.js',
'change_detection/*': '/change_detection/lib/*.js',
'facade/*': '/facade/lib/*.js',
'di/*': '/di/lib/*.js',
'rtts_assert/*': '/rtts_assert/lib/*.js',
'test_lib/*': '/test_lib/lib/*.js',
'reflection/*': '/reflection/lib/*.js',
'benchpress/*': '/benchpress/lib/*.js',
'examples/*': '/examples/web/*.js',
'benchmarks/*': '/benchmarks/web/*.js',
'benchmarks_external/*': '/benchmarks_external/web/*.js',
};
register(System);

24
tools/build/transpile.js Normal file
View File

@ -0,0 +1,24 @@
var util = require('./util');
var gulpTraceur = require('../transpiler/gulp-traceur');
var file2moduleName = require('./file2modulename');
var mergeStreams = require('event-stream').merge;
module.exports = function(gulp, plugins, config) {
return function() {
var transpile = gulp.src(config.src)
.pipe(plugins.rename({extname: '.'+config.outputExt}))
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(gulpTraceur(
config.options,
file2moduleName)
)
.pipe(gulp.dest(config.dest));
var copy = gulp.src(config.copy)
.pipe(plugins.rename({extname: '.'+config.outputExt}))
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(gulp.dest(config.dest));
return mergeStreams(transpile, copy);
};
};

45
tools/build/util.js Normal file
View File

@ -0,0 +1,45 @@
var Q = require('q');
var minimatch = require('minimatch');
module.exports = {
processToPromise: processToPromise,
streamToPromise: streamToPromise,
renameSrcFolder: renameSrcFolder,
filterByFile: filterByFile
};
function filterByFile(valuesWithPatterns, fileName) {
var match = null;
for (var pattern in valuesWithPatterns) {
if (pattern !== 'default' && minimatch(fileName, pattern)) {
match = valuesWithPatterns[pattern];
}
}
return match || valuesWithPatterns['default'];
}
function processToPromise(process) {
var defer = Q.defer();
process.on('close', function(code) {
if (code) {
defer.reject(code);
} else {
defer.resolve();
}
});
return defer.promise;
}
function streamToPromise(stream) {
var defer = Q.defer();
stream.on('end', defer.resolve);
stream.on('error', defer.reject);
return defer.promise;
}
function renameSrcFolder(plugins, srcFolderMapping) {
return plugins.rename(function(file) {
var srcOutputFolder = filterByFile(srcFolderMapping, file.dirname);
file.dirname = file.dirname.replace(/\bsrc\b/, srcOutputFolder);
});
}