angular-cn/tools/broccoli/trees/browser_tree.ts

326 lines
10 KiB
TypeScript

'use strict';
var Funnel = require('broccoli-funnel');
var htmlReplace = require('../html-replace');
var jsReplace = require('../js-replace');
var path = require('path');
var stew = require('broccoli-stew');
import compileWithTypescript from '../broccoli-typescript';
import destCopy from '../broccoli-dest-copy';
import flatten from '../broccoli-flatten';
import mergeTrees from '../broccoli-merge-trees';
import replace from '../broccoli-replace';
import checkImports from '../broccoli-check-imports';
const kServedPaths = [
// Relative (to /modules) paths to benchmark directories
'benchmarks/src',
'benchmarks/src/change_detection',
'benchmarks/src/compiler',
'benchmarks/src/costs',
'benchmarks/src/di',
'benchmarks/src/element_injector',
'benchmarks/src/largetable',
'benchmarks/src/naive_infinite_scroll',
'benchmarks/src/tree',
'benchmarks/src/static_tree',
// Relative (to /modules) paths to external benchmark directories
'benchmarks_external/src',
'benchmarks_external/src/compiler',
'benchmarks_external/src/largetable',
'benchmarks_external/src/naive_infinite_scroll',
'benchmarks_external/src/tree',
'benchmarks_external/src/tree/react',
'benchmarks_external/src/static_tree',
// Relative (to /modules) paths to example directories
'playground/src/animate',
'playground/src/benchpress',
'playground/src/model_driven_forms',
'playground/src/template_driven_forms',
'playground/src/person_management',
'playground/src/order_management',
'playground/src/gestures',
'playground/src/hash_routing',
'playground/src/hello_world',
'playground/src/http',
'playground/src/jsonp',
'playground/src/key_events',
'playground/src/relative_assets',
'playground/src/routing',
'playground/src/alt_routing',
'playground/src/sourcemap',
'playground/src/svg',
'playground/src/todo',
'playground/src/upgrade',
'playground/src/zippy_component',
'playground/src/async',
'playground/src/web_workers/kitchen_sink',
'playground/src/web_workers/todo',
'playground/src/web_workers/images',
'playground/src/web_workers/message_broker',
'playground/src/web_workers/router',
'playground/src/web_workers/input',
];
module.exports = function makeBrowserTree(options: any, destinationPath: string) {
// TODO: define an interface for the options
const modules = options.projects;
const noTypeChecks = options.noTypeChecks;
const generateEs6 = options.generateEs6;
const sourceMaps = options.sourceMaps;
const useBundles = options.useBundles;
if (modules.angular2) {
var angular2Tree = new Funnel('modules/angular2', {
include: ['**/**'],
exclude: [
// Exclude ES6 polyfill typings when tsc target=ES6
'typings/es6-*/**',
],
destDir: '/angular2/'
});
}
if (modules.benchmarks) {
var benchmarksTree = new Funnel(
'modules/benchmarks',
{include: ['**/**'], exclude: ['e2e_test/**'], destDir: '/benchmarks/'});
}
if (modules.benchmarks_external) {
var benchmarksExternalTree = new Funnel(
'modules/benchmarks_external',
{include: ['**/**'], exclude: ['e2e_test/**'], destDir: '/benchmarks_external/'});
}
if (modules.payload_tests) {
var payloadTestsTree = new Funnel(
'modules/payload_tests',
{include: ['**/ts/**'], exclude: ['e2e_test/**'], destDir: '/payload_tests/'});
}
if (modules.playground) {
var playgroundTree = new Funnel(
'modules/playground',
{include: ['**/**'], exclude: ['e2e_test/**'], destDir: '/playground/'});
}
if (modules.benchpress) {
var benchpressTree = new Funnel(
'modules/benchpress',
{include: ['**/**'], exclude: ['e2e_test/**'], destDir: '/benchpress/'});
}
let externalTypings =
new Funnel('node_modules', {include: ['rxjs/**/*.d.ts', 'zone.js/**/*.d.ts']});
var modulesTree = mergeTrees([
angular2Tree,
benchmarksTree,
benchmarksExternalTree,
payloadTestsTree,
playgroundTree,
benchpressTree,
externalTypings,
]);
var es6PolyfillTypings =
new Funnel('modules', {include: ['angular2/typings/es6-*/**'], destDir: '/'});
var es5ModulesTree = mergeTrees([modulesTree, es6PolyfillTypings]);
var scriptPathPatternReplacement = {
match: '@@PATH',
replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/');
return parts.splice(0, parts.length - 1).join('/');
}
};
var scriptFilePatternReplacement = {
match: '@@FILENAME',
replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/');
return parts[parts.length - 1].replace('html', 'js');
}
};
var useBundlesPatternReplacement = {
match: '@@USE_BUNDLES',
replacement: function(replacement: string, relativePath: string) { return useBundles; }
};
// Check that imports do not break barrel boundaries
modulesTree = checkImports(modulesTree);
modulesTree = replace(modulesTree, {
files: ['playground*/**/*.js'],
patterns: [{match: /\$SCRIPTS\$/, replacement: jsReplace('SCRIPTS')}]
});
let ambientTypings = [
'angular2/typings/hammerjs/hammerjs.d.ts',
'angular2/typings/node/node.d.ts',
'node_modules/zone.js/dist/zone.js.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,
emitDecoratorMetadata: true,
experimentalDecorators: true,
module: 'commonjs',
moduleResolution: 'classic',
noEmitOnError: !noTypeChecks,
rootDir: './',
rootFilePaths: ambientTypings,
inlineSourceMap: sourceMaps,
inlineSources: sourceMaps,
target: 'es5'
});
var vendorScriptsTree = flatten(new Funnel('.', {
files: [
'node_modules/es6-shim/es6-shim.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/systemjs/dist/system.src.js',
'node_modules/base64-js/lib/b64.js',
'node_modules/reflect-metadata/Reflect.js',
]
}));
var vendorScripts_benchmark =
new Funnel('tools/build/snippets', {files: ['url_params_to_form.js'], destDir: '/'});
var vendorScripts_benchmarks_external =
new Funnel('node_modules/angular', {files: ['angular.js'], destDir: '/'});
// Get scripts for each benchmark or example
let servingTrees = kServedPaths.reduce(getServedFunnels, []);
function getServedFunnels(funnels: BroccoliTree[], destDir: string) {
let options = {srcDir: '/', destDir: destDir};
funnels.push(new Funnel(vendorScriptsTree, options));
if (destDir.indexOf('benchmarks') > -1) {
funnels.push(new Funnel(vendorScripts_benchmark, options));
}
if (destDir.indexOf('benchmarks_external') > -1) {
funnels.push(new Funnel(vendorScripts_benchmarks_external, options));
}
return funnels;
}
if (modules.benchmarks || modules.benchmarks_external || modules.playground) {
var assetsTree = new Funnel(
modulesTree, {include: ['**/*'], exclude: ['**/*.{html,ts,dart}'], destDir: '/'});
}
var htmlTree = new Funnel(modulesTree, {
include: ['*/src/**/*.html', '**/playground/**/*.html', '**/payload_tests/**/ts/**/*.html'],
destDir: '/'
});
if (modules.playground) {
htmlTree = replace(htmlTree, {
files: ['playground*/**/*.html'],
patterns: [
{match: /\$SCRIPTS\$/, replacement: htmlReplace('SCRIPTS')}, scriptPathPatternReplacement,
scriptFilePatternReplacement, useBundlesPatternReplacement
]
});
}
if (modules.benchmarks) {
htmlTree = replace(htmlTree, {
files: ['benchmarks/**'],
patterns: [
{match: /\$SCRIPTS\$/, replacement: htmlReplace('SCRIPTS_benchmarks')},
scriptPathPatternReplacement, scriptFilePatternReplacement, useBundlesPatternReplacement
]
});
}
if (modules.benchmarks_external) {
htmlTree = replace(htmlTree, {
files: ['benchmarks_external/**'],
patterns: [
{match: /\$SCRIPTS\$/, replacement: htmlReplace('SCRIPTS_benchmarks_external')},
scriptPathPatternReplacement, scriptFilePatternReplacement, useBundlesPatternReplacement
]
});
}
if (modules.playground) {
// We need to replace the regular angular bundle with the web-worker bundle
// for web-worker e2e tests.
htmlTree = replace(htmlTree, {
files: ['playground*/**/web_workers/**/*.html'],
patterns: [{match: '/bundle/angular2.dev.js', replacement: '/bundle/web_worker/ui.dev.js'}]
});
}
if (modules.benchmarks || modules.benchmarks_external) {
var scripts = mergeTrees(servingTrees);
}
if (modules.benchmarks_external) {
var polymerFiles = new Funnel('.', {
files: [
'bower_components/polymer/polymer.html',
'bower_components/polymer/polymer-micro.html',
'bower_components/polymer/polymer-mini.html',
'tools/build/snippets/url_params_to_form.js',
]
});
var polymer = stew.mv(flatten(polymerFiles), 'benchmarks_external/src/tree/polymer');
var reactFiles = new Funnel('.', {files: ['node_modules/react/dist/react.min.js']});
var react = stew.mv(flatten(reactFiles), 'benchmarks_external/src/tree/react');
}
if (modules.benchmarks || modules.benchmarks_external || modules.playground) {
htmlTree = mergeTrees([htmlTree, scripts, polymer, react]);
}
// this is needed only for creating a bundle
// typescript resolves dependencies automatically
if (modules.bundle_deps) {
var nodeModules = new Funnel(
'node_modules', {include: ['rxjs/**/**', 'parse5/**/**', 'css/**/**'], destDir: '/'});
}
if (generateEs6) {
// Use TypeScript to transpile the *.ts files to ES6
var es6Tree = compileWithTypescript(modulesTree, {
declaration: false,
emitDecoratorMetadata: true,
experimentalDecorators: true,
noEmitOnError: false,
rootDir: './',
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'
});
es6Tree = stew.mv(mergeTrees([es6Tree, htmlTree, assetsTree, nodeModules]), '/es6');
}
es5Tree = stew.mv(mergeTrees([es5Tree, htmlTree, assetsTree, nodeModules]), '/es5');
var mergedTree = mergeTrees([es6Tree, es5Tree]);
return destCopy(mergedTree, destinationPath);
};