mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-25 00:31:36 +08:00
229 lines
5.5 KiB
JavaScript
229 lines
5.5 KiB
JavaScript
var path = require('path');
|
|
var configReplace = require('./broccoli-config-replace');
|
|
var compileWithTypescript = require('./broccoli-typescript');
|
|
var SwManifest = require('./service-worker-manifest').default;
|
|
var fs = require('fs');
|
|
var Funnel = require('broccoli-funnel');
|
|
var mergeTrees = require('broccoli-merge-trees');
|
|
var Project = require('ember-cli/lib/models/project');
|
|
|
|
module.exports = Angular2App;
|
|
|
|
function Angular2App(defaults, options) {
|
|
this._initProject();
|
|
this._notifyAddonIncluded();
|
|
this.options = options;
|
|
}
|
|
|
|
Angular2App.prototype.toTree = function () {
|
|
var sourceDir = 'src';
|
|
|
|
var sourceTree = new Funnel('src', {
|
|
include: ['*.ts', '**/*.ts', '**/*.d.ts'],
|
|
destDir: 'src'
|
|
});
|
|
|
|
var typingsTree = new Funnel('typings', {
|
|
include: ['browser.d.ts', 'browser/**'],
|
|
destDir: 'typings'
|
|
});
|
|
|
|
var vendorNpmFiles = [
|
|
'systemjs/dist/system-polyfills.js',
|
|
'systemjs/dist/system.src.js',
|
|
'es6-shim/es6-shim.js',
|
|
'angular2/bundles/angular2-polyfills.js',
|
|
'rxjs/bundles/Rx.js',
|
|
'angular2/bundles/angular2.dev.js',
|
|
'angular2/bundles/http.dev.js',
|
|
'angular2/bundles/router.dev.js',
|
|
'angular2/bundles/upgrade.dev.js'
|
|
];
|
|
|
|
if (this.options && this.options.vendorNpmFiles) {
|
|
vendorNpmFiles = vendorNpmFiles.concat(this.options.vendorNpmFiles);
|
|
}
|
|
|
|
var tsconfig = JSON.parse(fs.readFileSync('src/tsconfig.json', 'utf-8'));
|
|
// Add all spec files to files. We need this because spec files are their own entry
|
|
// point.
|
|
fs.readdirSync(sourceDir).forEach(function addPathRecursive(name) {
|
|
const filePath = path.join(sourceDir, name);
|
|
if (filePath.match(/\.spec\.[jt]s$/)) {
|
|
tsconfig.files.push(name);
|
|
} else if (fs.statSync(filePath).isDirectory()) {
|
|
// Recursively call this function with the full sub-path.
|
|
fs.readdirSync(filePath).forEach(function (n) {
|
|
addPathRecursive(path.join(name, n));
|
|
});
|
|
}
|
|
});
|
|
|
|
// Because the tsconfig does not include the source directory, add this as the first path
|
|
// element.
|
|
tsconfig.files = tsconfig.files.map(name => path.join(sourceDir, name));
|
|
|
|
var srcAndTypingsTree = mergeTrees([sourceTree, typingsTree]);
|
|
var tsTree = new compileWithTypescript(srcAndTypingsTree, tsconfig);
|
|
|
|
tsTree = new Funnel(tsTree, {
|
|
srcDir: 'src',
|
|
exclude: ['*.d.ts', 'tsconfig.json']
|
|
});
|
|
|
|
var jsTree = new Funnel(sourceDir, {
|
|
include: ['**/*.js'],
|
|
allowEmpty: true
|
|
});
|
|
|
|
var assetTree = new Funnel(sourceDir, {
|
|
include: ['**/*.*'],
|
|
exclude: ['**/*.ts', '**/*.js'],
|
|
allowEmpty: true
|
|
});
|
|
|
|
var vendorNpmTree = new Funnel('node_modules', {
|
|
include: vendorNpmFiles,
|
|
destDir: 'vendor'
|
|
});
|
|
|
|
var publicDirTree = new Funnel('public', {
|
|
allowEmpty: true
|
|
});
|
|
|
|
var merged = mergeTrees([
|
|
assetTree,
|
|
tsTree,
|
|
jsTree,
|
|
publicDirTree,
|
|
this.index(),
|
|
vendorNpmTree
|
|
], { overwrite: true });
|
|
|
|
return mergeTrees([merged, new SwManifest([merged])]);
|
|
};
|
|
|
|
/**
|
|
@private
|
|
@method _initProject
|
|
@param {Object} options
|
|
*/
|
|
Angular2App.prototype._initProject = function () {
|
|
this.project = Project.closestSync(process.cwd());
|
|
|
|
/*if (options.configPath) {
|
|
this.project.configPath = function() { return options.configPath; };
|
|
}*/
|
|
};
|
|
|
|
/**
|
|
@private
|
|
@method _notifyAddonIncluded
|
|
*/
|
|
Angular2App.prototype._notifyAddonIncluded = function () {
|
|
this.initializeAddons();
|
|
this.project.addons = this.project.addons.filter(function (addon) {
|
|
addon.app = this;
|
|
|
|
if (!addon.isEnabled || addon.isEnabled()) {
|
|
if (addon.included) {
|
|
addon.included(this);
|
|
}
|
|
|
|
return addon;
|
|
}
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
Loads and initializes addons for this project.
|
|
Calls initializeAddons on the Project.
|
|
|
|
@private
|
|
@method initializeAddons
|
|
*/
|
|
Angular2App.prototype.initializeAddons = function () {
|
|
this.project.initializeAddons();
|
|
};
|
|
|
|
/**
|
|
Returns the content for a specific type (section) for index.html.
|
|
|
|
Currently supported types:
|
|
- 'head'
|
|
//- 'config-module'
|
|
//- 'app'
|
|
//- 'head-footer'
|
|
//- 'test-header-footer'
|
|
//- 'body-footer'
|
|
//- 'test-body-footer'
|
|
|
|
Addons can also implement this method and could also define additional
|
|
types (eg. 'some-addon-section').
|
|
|
|
@private
|
|
@method contentFor
|
|
@param {RegExP} match Regular expression to match against
|
|
@param {String} type Type of content
|
|
@return {String} The content.
|
|
*/
|
|
Angular2App.prototype.contentFor = function (match, type) {
|
|
var content = [];
|
|
|
|
/*switch (type) {
|
|
case 'head': this._contentForHead(content, config); break;
|
|
case 'config-module': this._contentForConfigModule(content, config); break;
|
|
case 'app-boot': this._contentForAppBoot(content, config); break;
|
|
}*/
|
|
|
|
content = this.project.addons.reduce(function (content, addon) {
|
|
var addonContent = addon.contentFor ? addon.contentFor(type) : null;
|
|
if (addonContent) {
|
|
return content.concat(addonContent);
|
|
}
|
|
|
|
return content;
|
|
}, content);
|
|
|
|
|
|
return content.join('\n');
|
|
};
|
|
|
|
/**
|
|
@private
|
|
@method _configReplacePatterns
|
|
@return
|
|
*/
|
|
Angular2App.prototype._configReplacePatterns = function () {
|
|
return [{
|
|
match: /\{\{content-for ['"](.+)["']\}\}/g,
|
|
replacement: this.contentFor.bind(this)
|
|
}];
|
|
};
|
|
|
|
|
|
/**
|
|
Returns the tree for app/index.html
|
|
|
|
@private
|
|
@method index
|
|
@return {Tree} Tree for app/index.html
|
|
*/
|
|
Angular2App.prototype.index = function () {
|
|
var htmlName = 'index.html';
|
|
var files = [
|
|
'index.html'
|
|
];
|
|
|
|
var index = new Funnel('src', {
|
|
files: files,
|
|
description: 'Funnel: index.html'
|
|
});
|
|
|
|
|
|
return configReplace(index, {
|
|
files: [htmlName],
|
|
patterns: this._configReplacePatterns()
|
|
});
|
|
};
|