Skip to content

Commit

Permalink
feat(@angular/cli): add watch flag to serve/e2e (#4749)
Browse files Browse the repository at this point in the history
This is useful when you don't want the server to rebuild in the middle of something.

A good example is when running e2e tests. Especially on larger suites, one would prefer to continue working while the build is tested without compromising tests.

This will break tests on #4744. They should be adjusted to add the `--watch` flag since they depend on the live reload behaviour during `ng e2e`.
  • Loading branch information
filipesilva authored and hansl committed Feb 17, 2017
1 parent 121c390 commit 9d29cbc
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/documentation/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ All builds make use of bundling, and using the `--prod` flag in `ng build --pro
or `ng serve --prod` will also make use of uglifying and tree-shaking functionality.

## Options
`--watch` (`-w`) flag to run builds when files change
`--watch` (`-w`) rebuild when files change

`--target` (`-t`) define the build target

Expand Down
2 changes: 2 additions & 0 deletions docs/documentation/serve.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
`ng serve` builds the application and starts a web server

## Options
`--watch` (`-w`) rebuild when files change

`--port` (`-p`) port to serve the application on

`--host` (`-H`) host where to listen
Expand Down
9 changes: 7 additions & 2 deletions packages/@angular/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const baseBuildCommandOptions: any = [
{ name: 'i18n-format', type: String },
{ name: 'locale', type: String },
{ name: 'extract-css', type: Boolean, aliases: ['ec'] },
{ name: 'watch', type: Boolean, aliases: ['w'] },
{
name: 'output-hashing',
type: String,
Expand All @@ -44,7 +45,6 @@ export const baseBuildCommandOptions: any = [
];

export interface BuildTaskOptions extends BuildOptions {
watch?: boolean;
statsJson?: boolean;
}

Expand All @@ -54,13 +54,18 @@ const BuildCommand = Command.extend({
aliases: ['b'],

availableOptions: baseBuildCommandOptions.concat([
{ name: 'watch', type: Boolean, default: false, aliases: ['w'] },
{ name: 'stats-json', type: Boolean, default: false }
]),

run: function (commandOptions: BuildTaskOptions) {
const project = this.project;

const additionalDefaults: any = {
watch: false
};

commandOptions = Object.assign({}, additionalDefaults, commandOptions);

// Check angular version.
Version.assertAngularVersionIs2_3_1OrHigher(project.root);

Expand Down
6 changes: 6 additions & 0 deletions packages/@angular/cli/commands/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ const E2eCommand = Command.extend({
const E2eTask = require('../tasks/e2e').E2eTask;
this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject();

const additionalDefaults: any = {
watch: false
};

commandOptions = Object.assign({}, additionalDefaults, commandOptions);

const e2eTask = new E2eTask({
ui: this.ui,
project: this.project
Expand Down
6 changes: 6 additions & 0 deletions packages/@angular/cli/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ const ServeCommand = Command.extend({
run: function (commandOptions: ServeTaskOptions) {
const ServeTask = require('../tasks/serve').default;

const additionalDefaults: any = {
watch: true
};

commandOptions = Object.assign({}, additionalDefaults, commandOptions);

Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host;

Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/models/build-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface BuildOptions {
i18nFormat?: string;
locale?: string;
extractCss?: boolean;
watch?: boolean;
outputHashing?: string;
poll?: number;
}
13 changes: 13 additions & 0 deletions packages/@angular/cli/tasks/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ export default Task.extend({
}
if (!webpackConfig.entry.main) { webpackConfig.entry.main = []; }
webpackConfig.entry.main.unshift(...entryPoints);

if (!serveTaskOptions.watch) {
// There's no option to turn off file watching in webpack-dev-server, but
// we can override the file watcher instead.
webpackConfig.plugins.unshift({
apply: (compiler: any) => {
compiler.plugin('after-environment', () => {
compiler.watchFileSystem = { watch: () => {} };
});
}
});
}

webpackCompiler = webpack(webpackConfig);

if (rebuildDoneCb) {
Expand Down
8 changes: 5 additions & 3 deletions packages/@ngtools/webpack/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,11 @@ export class AotPlugin implements Tapable {
this._firstRun = false;
this._diagnoseFiles = {};

compiler.watchFileSystem.watcher.once('aggregated', (changes: string[]) => {
changes.forEach((fileName: string) => this._compilerHost.invalidate(fileName));
});
if (compiler.watchFileSystem.watcher) {
compiler.watchFileSystem.watcher.once('aggregated', (changes: string[]) => {
changes.forEach((fileName: string) => this._compilerHost.invalidate(fileName));
});
}
});

// Add lazy modules to the context module for @angular/core/src/linker
Expand Down
33 changes: 33 additions & 0 deletions tests/e2e/tests/build/watch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
killAllProcesses,
exec,
waitForAnyProcessOutputToMatch,
silentExecAndWaitForOutputToMatch
} from '../../utils/process';
import { expectToFail } from '../../utils/utils';


const webpackGoodRegEx = /webpack: bundle is now VALID|webpack: Compiled successfully./;

export default function () {
if (process.platform.startsWith('win')) {
return Promise.resolve();
}

return silentExecAndWaitForOutputToMatch('ng', ['serve'], webpackGoodRegEx)
// Should trigger a rebuild.
.then(() => exec('touch', 'src/main.ts'))
.then(() => waitForAnyProcessOutputToMatch(webpackGoodRegEx, 5000))
.then(() => killAllProcesses(), (err: any) => {
killAllProcesses();
throw err;
})
.then(() => silentExecAndWaitForOutputToMatch('ng', ['serve', '--no-watch'], webpackGoodRegEx))
// Should not trigger a rebuild when not watching files.
.then(() => exec('touch', 'src/main.ts'))
.then(() => expectToFail(() => waitForAnyProcessOutputToMatch(webpackGoodRegEx, 5000)))
.then(() => killAllProcesses(), (err: any) => {
killAllProcesses();
throw err;
})
}

0 comments on commit 9d29cbc

Please sign in to comment.