Skip to content

Commit

Permalink
build: use webpack for building apps.
Browse files Browse the repository at this point in the history
This pull request replaces the underlying broccoli build system and then
replaces it with webpack as the build and bundler.

This will affect the following commands (however the user-level)
functionality should go unchanged (besides unimplemented flags which
will come after this PR.):

ng build (with --env flag and --watch flag supported)
ng serve (with --port flag supported)
ng test / ng e2e

The webpack configuration is blackboxed, and therefore users will not
see a webpack.config.js file in their repository.

Also this PR will bump the typescript version to 2.0 (beta).

Fixes angular#909 angular#1155 angular#882
  • Loading branch information
TheLarkInn authored and johannes.werner committed Aug 15, 2016
1 parent 504a497 commit 5f6c86d
Show file tree
Hide file tree
Showing 16 changed files with 1,213 additions and 12 deletions.
16 changes: 8 additions & 8 deletions addon/ng2/blueprints/mobile/files/__path__/main-app-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import 'angular2-universal-polyfills';
import { provide } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { APP_SHELL_BUILD_PROVIDERS } from '@angular/app-shell';
import {
REQUEST_URL,
ORIGIN_URL,
Bootloader,
BootloaderConfig,
AppConfig
import {
REQUEST_URL,
ORIGIN_URL,
Bootloader,
BootloaderConfig,
AppConfig
} from 'angular2-universal';
import { AppComponent } from './app/';

Expand Down Expand Up @@ -39,9 +39,9 @@ export function getBootloader() : Bootloader {
return new Bootloader(bootloaderConfig);
}

// The build system will call this function with the bootloader from
// The build system will call this function with the bootloader from
// getBootloader and the contents of the index page
export function serialize(bootloader: Bootloader, template: string) : string {
appConfig.template = template;
return bootloader.serializeApplication(appConfig);
}
}
17 changes: 17 additions & 0 deletions addon/ng2/blueprints/ng2/files/__path__/vendor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Typescript emit helpers polyfill
import 'ts-helpers';

import '@angular/core';
import '@angular/common';
import '@angular/compiler';
import '@angular/http';
import '@angular/router';
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';

<% if(isMobile) { %>
import '@angular/app-shell';
<% } %>

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
2 changes: 1 addition & 1 deletion addon/ng2/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports = Command.extend({
}
if (commandOptions.target === 'production') {
commandOptions.environment = 'prod';
}
}
}

var project = this.project;
Expand Down
3 changes: 2 additions & 1 deletion addon/ng2/commands/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var GitInit = require('../tasks/git-init');
var LinkCli = require('../tasks/link-cli');
var NpmInstall = require('../tasks/npm-install');


module.exports = Command.extend({
name: 'init',
description: 'Creates a new angular-cli project in the current folder.',
Expand Down Expand Up @@ -94,7 +95,7 @@ module.exports = Command.extend({

return Promise.reject(new SilentError(message));
}

var blueprintOpts = {
dryRun: commandOptions.dryRun,
blueprint: commandOptions.blueprint || this._defaultBlueprint(),
Expand Down
Empty file added addon/ng2/commands/test.js
Empty file.
161 changes: 161 additions & 0 deletions addon/ng2/models/builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
const fs = require('fs-extra');
const existsSync = require('exists-sync');
const path = require('path');
const Promise = require('ember-cli/lib/ext/promise');
const Task = require('ember-cli/lib/models/task');
const SilentError = require('silent-error');
const chalk = require('chalk');
const attemptNeverIndex = require('ember-cli/lib/utilities/attempt-never-index');
const findBuildFile = require('ember-cli/lib/utilities/find-build-file');
const viz = require('broccoli-viz');
const FSMonitor = require('fs-monitor-stack');
const Sync = require('tree-sync');
const mkdirp = require('mkdirp');

let resolve = null;
let promise = new Promise((r) => resolve = r);




var signalsTrapped = false;
var buildCount = 0;

function outputViz(count, result, monitor) {
var processed = viz.process(result.graph);

processed.forEach(function(node) {
node.stats.fs = monitor.statsFor(node);
});

fs.writeFileSync('graph.' + count + '.dot', viz.dot(processed));
fs.writeFileSync('graph.' + count + '.json', JSON.stringify({
summary: {
buildCount: count,
output: result.directory,
totalTime: result.totalTime,
totalNodes: processed.length,
stats: {
fs: monitor.totalStats()
}
},
nodes: processed
}));
}

module.exports = Task.extend({
setupBuilder: function() {
this.environment = this.environment || 'development';
process.env.ANGULAR_ENV = process.env.ANGULAR_ENV || process.env.EMBER_CLI || this.environment;
process.env.EMBER_ENV = process.env.ANGULAR_ENV;

var buildFile = findBuildFile('angular-cli-build.js');
this.tree = buildFile({ project: this.project });

if (webpack) {
console.log('webpack');
} else {
var broccoli = require('ember-cli-broccoli');
this.builder = new broccoli.Builder(this.tree);
}
},

trapSignals: function() {
if (!signalsTrapped) {
process.on('SIGINT', this.onSIGINT.bind(this));
process.on('SIGTERM', this.onSIGTERM.bind(this));
process.on('message', this.onMessage.bind(this));
signalsTrapped = true;
}
},

init: function() {
this.setupBuilder();
this.trapSignals();
},

/**
Determine whether the output path is safe to delete. If the outputPath
appears anywhere in the parents of the project root, the build would
delete the project directory. In this case return `false`, otherwise
return `true`.
*/
canDeleteOutputPath: function(outputPath) {
var rootPathParents = [this.project.root];
var dir = path.dirname(this.project.root);
rootPathParents.push(dir);
while (dir !== path.dirname(dir)) {
dir = path.dirname(dir);
rootPathParents.push(dir);
}
return rootPathParents.indexOf(outputPath) === -1;
},

copyToOutputPath: function(inputPath) {
var outputPath = this.outputPath;

mkdirp.sync(outputPath);

if (!this.canDeleteOutputPath(outputPath)) {
throw new SilentError('Using a build destination path of `' + outputPath + '` is not supported.');
}

var sync = this._sync;
if (sync === undefined) {
this._sync = sync = new Sync(inputPath, path.resolve(this.outputPath));
}

sync.sync();
},

build: function(...args: any[]) {
attemptNeverIndex('tmp');
return promise;
// return Promise.resolve();
// if (this.webpack) {
// console.log(1, process.cwd());
// return new Promise((resolve, reject) => {
// this.webpack.run((err, stats) => {
// console.log(!!err, stats);
// if (err) {
// reject(err);
// }
// resolve();
// });
// });
// }
// return this.builder.build(...args);
},

cleanup: function() {
var ui = this.ui;

// if (this.webpack) {
// this.webpack.cleanupAndExit();
return Promise.resolve();
// } else {
// return this.builder.cleanup().catch(function (err) {
// ui.writeLine(chalk.red('Cleanup error.'));
// ui.writeError(err);
// });
// }
},

cleanupAndExit: function() {
this.cleanup().finally(function() {
process.exit(1);
});
},

onSIGINT: function() {
this.cleanupAndExit();
},
onSIGTERM: function() {
this.cleanupAndExit();
},
onMessage: function(message) {
if (message.kill) {
this.cleanupAndExit();
}
}
});
Loading

0 comments on commit 5f6c86d

Please sign in to comment.