Skip to content

Commit b087a10

Browse files
Charles Lydingfilipesilva
Charles Lyding
authored andcommitted
fix(serve): implement relevant live-reload options
1 parent cd1aa18 commit b087a10

File tree

3 files changed

+61
-96
lines changed

3 files changed

+61
-96
lines changed

docs/documentation/serve.md

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

1717
`--live-reload` (`-lr`) flag to turn off live reloading
1818

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

2721
`--ssl` flag to turn on SSL
2822

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

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,19 @@ import { overrideOptions } from '../utilities/override-options';
1010
const SilentError = require('silent-error');
1111
const PortFinder = require('portfinder');
1212
const Command = require('../ember-cli/lib/models/command');
13-
const getPort = <any>denodeify(PortFinder.getPort);
14-
15-
PortFinder.basePort = 49152;
13+
const getPort = denodeify<{ host: string, port: number }, number>(PortFinder.getPort);
1614

1715
const config = CliConfig.fromProject() || CliConfig.fromGlobal();
1816
const defaultPort = process.env.PORT || config.get('defaults.serve.port');
1917
const defaultHost = config.get('defaults.serve.host');
18+
PortFinder.basePort = defaultPort;
2019

2120
export interface ServeTaskOptions extends BuildOptions {
2221
port?: number;
2322
host?: string;
2423
proxyConfig?: string;
2524
liveReload?: boolean;
26-
liveReloadHost?: string;
27-
liveReloadPort?: number;
28-
liveReloadBaseUrl?: string;
29-
liveReloadLiveCss?: boolean;
25+
liveReloadClient?: string;
3026
ssl?: boolean;
3127
sslKey?: string;
3228
sslCert?: string;
@@ -66,28 +62,9 @@ const ServeCommand = Command.extend({
6662
baseServeCommandOptions.concat([
6763
{ name: 'live-reload', type: Boolean, default: true, aliases: ['lr'] },
6864
{
69-
name: 'live-reload-host',
65+
name: 'live-reload-client',
7066
type: String,
71-
aliases: ['lrh'],
72-
description: 'Defaults to host'
73-
},
74-
{
75-
name: 'live-reload-base-url',
76-
type: String,
77-
aliases: ['lrbu'],
78-
description: 'Defaults to baseURL'
79-
},
80-
{
81-
name: 'live-reload-port',
82-
type: Number,
83-
aliases: ['lrp'],
84-
description: '(Defaults to port number within [49152...65535])'
85-
},
86-
{
87-
name: 'live-reload-live-css',
88-
type: Boolean,
89-
default: true,
90-
description: 'Whether to live reload CSS (default true)'
67+
description: 'specify the URL that the live reload browser client will use'
9168
},
9269
{
9370
name: 'hmr',
@@ -104,11 +81,8 @@ const ServeCommand = Command.extend({
10481
const ServeTask = require('../tasks/serve').default;
10582

10683
Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
107-
commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host;
10884

109-
return checkPort(commandOptions.port, commandOptions.host)
110-
.then((port: number) => commandOptions.port = port)
111-
.then(() => autoFindLiveReloadPort(commandOptions))
85+
return checkExpressPort(commandOptions)
11286
.then((opts: ServeTaskOptions) => {
11387
const serve = new ServeTask({
11488
ui: this.ui,
@@ -137,26 +111,4 @@ function checkExpressPort(commandOptions: ServeTaskOptions) {
137111
});
138112
}
139113

140-
function autoFindLiveReloadPort(commandOptions: ServeTaskOptions) {
141-
return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost })
142-
.then((foundPort: number) => {
143-
144-
// if live reload port matches express port, try one higher
145-
if (foundPort === commandOptions.port) {
146-
commandOptions.liveReloadPort = foundPort + 1;
147-
return autoFindLiveReloadPort(commandOptions);
148-
}
149-
150-
// port was already open
151-
if (foundPort === commandOptions.liveReloadPort) {
152-
return commandOptions;
153-
}
154-
155-
// use found port as live reload port
156-
commandOptions.liveReloadPort = foundPort;
157-
return commandOptions;
158-
159-
});
160-
}
161-
162114
export default ServeCommand;

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

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

4242
let webpackConfig = new NgCliWebpackConfig(serveTaskOptions).config;
4343

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

7291
if (!serveTaskOptions.watch) {
7392
// There's no option to turn off file watching in webpack-dev-server, but
@@ -151,26 +170,26 @@ export default Task.extend({
151170

152171
ui.writeLine(chalk.green(oneLine`
153172
**
154-
NG Live Development Server is running on
155-
http${serveTaskOptions.ssl ? 's' : ''}://${serveTaskOptions.host}:${serveTaskOptions.port}.
173+
NG Live Development Server is running on ${serverAddress}
156174
**
157175
`));
158176

159177
const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration);
160178
return new Promise((resolve, reject) => {
161-
server.listen(serveTaskOptions.port, `${serveTaskOptions.host}`, (err: any, stats: any) => {
179+
server.listen(serveTaskOptions.port, serveTaskOptions.host, (err: any, stats: any) => {
162180
if (err) {
163-
console.error(err.stack || err);
164-
if (err.details) { console.error(err.details); }
165-
reject(err.details);
166-
} else {
167-
const { open, ssl, host, port } = serveTaskOptions;
168-
if (open) {
169-
let protocol = ssl ? 'https' : 'http';
170-
opn(url.format({ protocol: protocol, hostname: host, port: port.toString() }));
171-
}
181+
return reject(err);
182+
}
183+
if (serveTaskOptions.open) {
184+
opn(serverAddress);
172185
}
173186
});
187+
})
188+
.catch((err: Error) => {
189+
if (err) {
190+
this.ui.writeError('\nAn error occured during the build:\n' + ((err && err.stack) || err));
191+
}
192+
throw err;
174193
});
175194
}
176195
});

0 commit comments

Comments
 (0)