Skip to content

Commit 9c9ccc0

Browse files
Charles Lydingfilipesilva
Charles Lyding
authored andcommitted
fix(serve): implement relevant live-reload options
1 parent 862c163 commit 9c9ccc0

File tree

3 files changed

+60
-94
lines changed

3 files changed

+60
-94
lines changed

docs/documentation/serve.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@
1414

1515
`--live-reload` (`-lr`) flag to turn off live reloading
1616

17-
`--live-reload-host` (`-lrh`) specify the host for live reloading
18-
19-
`--live-reload-base-url` (`-lrbu`) specify the base URL for live reloading
20-
21-
`--live-reload-port` (`-lrp`) port for live reloading
22-
23-
`--live-reload-live-css` flag to live reload CSS
17+
`--live-reload-client` specify the URL that the live reload browser client will use
2418

2519
`--ssl` flag to turn on SSL
2620

packages/@angular/cli/commands/serve.ts

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,19 @@ import { ServeTaskOptions } from './serve';
88
const SilentError = require('silent-error');
99
const PortFinder = require('portfinder');
1010
const Command = require('../ember-cli/lib/models/command');
11-
const getPort = <any>denodeify(PortFinder.getPort);
12-
13-
PortFinder.basePort = 49152;
11+
const getPort = denodeify<{host: string, port: number}, number>(PortFinder.getPort);
1412

1513
const config = CliConfig.fromProject() || CliConfig.fromGlobal();
1614
const defaultPort = process.env.PORT || config.get('defaults.serve.port');
1715
const defaultHost = config.get('defaults.serve.host');
16+
PortFinder.basePort = defaultPort;
1817

1918
export interface ServeTaskOptions extends BuildOptions {
2019
port?: number;
2120
host?: string;
2221
proxyConfig?: string;
2322
liveReload?: boolean;
24-
liveReloadHost?: string;
25-
liveReloadPort?: number;
26-
liveReloadBaseUrl?: string;
27-
liveReloadLiveCss?: boolean;
23+
liveReloadClient?: string;
2824
ssl?: boolean;
2925
sslKey?: string;
3026
sslCert?: string;
@@ -63,28 +59,9 @@ const ServeCommand = Command.extend({
6359
availableOptions: baseServeCommandOptions.concat([
6460
{ name: 'live-reload', type: Boolean, default: true, aliases: ['lr'] },
6561
{
66-
name: 'live-reload-host',
62+
name: 'live-reload-client',
6763
type: String,
68-
aliases: ['lrh'],
69-
description: 'Defaults to host'
70-
},
71-
{
72-
name: 'live-reload-base-url',
73-
type: String,
74-
aliases: ['lrbu'],
75-
description: 'Defaults to baseURL'
76-
},
77-
{
78-
name: 'live-reload-port',
79-
type: Number,
80-
aliases: ['lrp'],
81-
description: '(Defaults to port number within [49152...65535])'
82-
},
83-
{
84-
name: 'live-reload-live-css',
85-
type: Boolean,
86-
default: true,
87-
description: 'Whether to live reload CSS (default true)'
64+
description: 'specify the URL that the live reload browser client will use'
8865
},
8966
{
9067
name: 'hmr',
@@ -98,10 +75,8 @@ const ServeCommand = Command.extend({
9875
const ServeTask = require('../tasks/serve').default;
9976

10077
Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
101-
commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host;
10278

10379
return checkExpressPort(commandOptions)
104-
.then(() => autoFindLiveReloadPort(commandOptions))
10580
.then((opts: ServeTaskOptions) => {
10681
const serve = new ServeTask({
10782
ui: this.ui,
@@ -130,26 +105,4 @@ function checkExpressPort(commandOptions: ServeTaskOptions) {
130105
});
131106
}
132107

133-
function autoFindLiveReloadPort(commandOptions: ServeTaskOptions) {
134-
return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost })
135-
.then((foundPort: number) => {
136-
137-
// if live reload port matches express port, try one higher
138-
if (foundPort === commandOptions.port) {
139-
commandOptions.liveReloadPort = foundPort + 1;
140-
return autoFindLiveReloadPort(commandOptions);
141-
}
142-
143-
// port was already open
144-
if (foundPort === commandOptions.liveReloadPort) {
145-
return commandOptions;
146-
}
147-
148-
// use found port as live reload port
149-
commandOptions.liveReloadPort = foundPort;
150-
return commandOptions;
151-
152-
});
153-
}
154-
155108
export default ServeCommand;

packages/@angular/cli/tasks/serve.ts

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,52 @@ export default Task.extend({
3838

3939
let webpackConfig = new NgCliWebpackConfig(serveTaskOptions).config;
4040

41-
// This allows for live reload of page when changes are made to repo.
42-
// https://webpack.github.io/docs/webpack-dev-server.html#inline-mode
43-
let entryPoints = [
44-
`webpack-dev-server/client?http://${serveTaskOptions.host}:${serveTaskOptions.port}/`
45-
];
46-
if (serveTaskOptions.hmr) {
47-
const webpackHmrLink = 'https://webpack.github.io/docs/hot-module-replacement.html';
48-
ui.writeLine(oneLine`
49-
${chalk.yellow('NOTICE')} Hot Module Replacement (HMR) is enabled for the dev server.
50-
`);
51-
ui.writeLine(' The project will still live reload when HMR is enabled,');
52-
ui.writeLine(' but to take advantage of HMR additional application code is required');
53-
ui.writeLine(' (not included in an Angular CLI project by default).');
54-
ui.writeLine(` See ${chalk.blue(webpackHmrLink)}`);
55-
ui.writeLine(' for information on working with HMR for Webpack.');
56-
entryPoints.push('webpack/hot/dev-server');
57-
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
58-
webpackConfig.plugins.push(new webpack.NamedModulesPlugin());
59-
if (serveTaskOptions.extractCss) {
41+
const serverAddress = url.format({
42+
protocol: serveTaskOptions.ssl ? 'https' : 'http',
43+
hostname: serveTaskOptions.host,
44+
port: serveTaskOptions.port.toString()
45+
});
46+
let clientAddress = serverAddress;
47+
if (serveTaskOptions.liveReloadClient) {
48+
const clientUrl = url.parse(serveTaskOptions.liveReloadClient);
49+
// very basic sanity check
50+
if (!clientUrl.host) {
51+
return Promise.reject(new SilentError(`'live-reload-client' must be a full URL.`));
52+
}
53+
clientAddress = clientUrl.href;
54+
}
55+
56+
if (serveTaskOptions.liveReload) {
57+
// This allows for live reload of page when changes are made to repo.
58+
// https://webpack.github.io/docs/webpack-dev-server.html#inline-mode
59+
let entryPoints = [
60+
`webpack-dev-server/client?${clientAddress}`
61+
];
62+
if (serveTaskOptions.hmr) {
63+
const webpackHmrLink = 'https://webpack.github.io/docs/hot-module-replacement.html';
6064
ui.writeLine(oneLine`
61-
${chalk.yellow('NOTICE')} (HMR) does not allow for CSS hot reload when used
62-
together with '--extract-css'.
65+
${chalk.yellow('NOTICE')} Hot Module Replacement (HMR) is enabled for the dev server.
6366
`);
67+
ui.writeLine(' The project will still live reload when HMR is enabled,');
68+
ui.writeLine(' but to take advantage of HMR additional application code is required');
69+
ui.writeLine(' (not included in an Angular CLI project by default).');
70+
ui.writeLine(` See ${chalk.blue(webpackHmrLink)}`);
71+
ui.writeLine(' for information on working with HMR for Webpack.');
72+
entryPoints.push('webpack/hot/dev-server');
73+
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
74+
webpackConfig.plugins.push(new webpack.NamedModulesPlugin());
75+
if (serveTaskOptions.extractCss) {
76+
ui.writeLine(oneLine`
77+
${chalk.yellow('NOTICE')} (HMR) does not allow for CSS hot reload when used
78+
together with '--extract-css'.
79+
`);
80+
}
6481
}
82+
if (!webpackConfig.entry.main) { webpackConfig.entry.main = []; }
83+
webpackConfig.entry.main.unshift(...entryPoints);
84+
} else if (serveTaskOptions.hmr) {
85+
ui.writeLine(chalk.yellow('Live reload is disabled. HMR option ignored.'));
6586
}
66-
if (!webpackConfig.entry.main) { webpackConfig.entry.main = []; }
67-
webpackConfig.entry.main.unshift(...entryPoints);
6887
webpackCompiler = webpack(webpackConfig);
6988

7089
if (rebuildDoneCb) {
@@ -135,26 +154,26 @@ export default Task.extend({
135154

136155
ui.writeLine(chalk.green(oneLine`
137156
**
138-
NG Live Development Server is running on
139-
http${serveTaskOptions.ssl ? 's' : ''}://${serveTaskOptions.host}:${serveTaskOptions.port}.
157+
NG Live Development Server is running on ${serverAddress}
140158
**
141159
`));
142160

143161
const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration);
144162
return new Promise((resolve, reject) => {
145-
server.listen(serveTaskOptions.port, `${serveTaskOptions.host}`, (err: any, stats: any) => {
163+
server.listen(serveTaskOptions.port, serveTaskOptions.host, (err: any, stats: any) => {
146164
if (err) {
147-
console.error(err.stack || err);
148-
if (err.details) { console.error(err.details); }
149-
reject(err.details);
150-
} else {
151-
const { open, ssl, host, port } = serveTaskOptions;
152-
if (open) {
153-
let protocol = ssl ? 'https' : 'http';
154-
opn(url.format({ protocol: protocol, hostname: host, port: port.toString() }));
155-
}
165+
return reject(err);
166+
}
167+
if (serveTaskOptions.open) {
168+
opn(serverAddress);
156169
}
157170
});
171+
})
172+
.catch((err: Error) => {
173+
if (err) {
174+
this.ui.writeError('\nAn error occured during the build:\n' + ((err && err.stack) || err));
175+
}
176+
throw err;
158177
});
159178
}
160179
});

0 commit comments

Comments
 (0)