Skip to content
This repository was archived by the owner on Jun 3, 2019. It is now read-only.

Commit 5dc8d52

Browse files
committed
react-tree-walker, detect ports
1 parent 0f0ca7d commit 5dc8d52

File tree

6 files changed

+81
-8105
lines changed

6 files changed

+81
-8105
lines changed

internal/development/hotClientServer.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import ListenerManager from './listenerManager';
55
import { log } from '../utils';
66

77
class HotClientServer {
8-
constructor(compiler) {
8+
constructor(port, compiler) {
99
const app = express();
1010

1111
const httpPathRegex = /^https?:\/\/(.*):([\d]{1,5})/i;
@@ -16,9 +16,6 @@ class HotClientServer {
1616
);
1717
}
1818

19-
// eslint-disable-next-line no-unused-vars
20-
const [_, host, port] = httpPathRegex.exec(httpPath);
21-
2219
this.webpackDevMiddleware = createWebpackMiddleware(compiler, {
2320
quiet: true,
2421
noInfo: true,

internal/development/hotDevelopment.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import HotClientServer from './hotClientServer';
77
import createVendorDLL from './createVendorDLL';
88
import webpackConfigFactory from '../webpack/configFactory';
99
import config from '../../config';
10+
import values from '../../config/values';
1011

1112
const usesDevVendorDLL = bundleConfig =>
1213
bundleConfig.devVendorDLL != null && bundleConfig.devVendorDLL.enabled;
@@ -63,10 +64,17 @@ const initializeBundle = (name, bundleConfig) => {
6364
};
6465

6566
class HotDevelopment {
66-
constructor() {
67+
constructor(port, clientPort) {
6768
this.hotClientServer = null;
6869
this.hotNodeServers = [];
6970

71+
// Update devServerPort to absolute port
72+
// TODO: Refactor HotXServer's and their webpack config to
73+
// use passed down props internally.
74+
values.clientDevServerPort = clientPort;
75+
process.env.PORT = port;
76+
process.env.CLIENT_DEV_PORT = clientPort;
77+
7078
const clientBundle = initializeBundle('client', config('bundles.client'));
7179

7280
const nodeBundles = [
@@ -94,7 +102,7 @@ class HotDevelopment {
94102
resolve(compiler);
95103
}
96104
});
97-
this.hotClientServer = new HotClientServer(compiler);
105+
this.hotClientServer = new HotClientServer(clientPort, compiler);
98106
}),
99107
vendorDLLsFailed,
100108
)
@@ -103,7 +111,7 @@ class HotDevelopment {
103111
this.hotNodeServers = nodeBundles.map(
104112
({ name, createCompiler }) =>
105113
// $FlowFixMe
106-
new HotNodeServer(name, createCompiler(), clientCompiler),
114+
new HotNodeServer(port, name, createCompiler(), clientCompiler),
107115
);
108116
});
109117
}

internal/development/hotNodeServer.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { spawn } from 'child_process';
44
import { log } from '../utils';
55

66
class HotNodeServer {
7-
constructor(name, compiler, clientCompiler) {
7+
constructor(port, name, compiler, clientCompiler) {
88
const compiledEntryFile = path.resolve(
99
appRootDir.get(),
1010
compiler.options.output.path,
@@ -22,7 +22,9 @@ class HotNodeServer {
2222
});
2323
}
2424

25-
const newServer = spawn('node', [compiledEntryFile, '--color']);
25+
// Start on correct port
26+
const env = Object.assign(process.env, { PORT: port });
27+
const newServer = spawn('node', [compiledEntryFile, '--color', { env }]);
2628

2729
log({
2830
title: name,

internal/development/index.js

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
import http from 'http';
22
import openBrowser from 'react-dev-utils/openBrowser';
3+
import { choosePort } from 'react-dev-utils/WebpackDevServerUtils';
4+
import detect from 'detect-port-alt';
35
import chokidar from 'chokidar';
46
import { resolve as pathResolve } from 'path';
57
import appRootDir from 'app-root-dir';
6-
import config from '../../config/values';
8+
import config from '../../config';
79
import { log } from '../utils';
810

9-
let HotDevelopment = require('./hotDevelopment').default;
10-
let devServer = new HotDevelopment();
11-
12-
// Any changes to our webpack bundleConfigs should restart the development devServer.
13-
const watcher = chokidar.watch([
14-
pathResolve(appRootDir.get(), 'internal'),
15-
pathResolve(appRootDir.get(), 'config'),
16-
]);
17-
18-
// Wait until specific endpoint becomes responsive, then fire callback.
11+
const host = config('host');
1912
const onResponsive = (hostname, port, cb) =>
2013
setTimeout(
2114
() =>
@@ -25,42 +18,63 @@ const onResponsive = (hostname, port, cb) =>
2518
1000,
2619
);
2720

28-
// Get host and port
29-
const host = config('host');
30-
const port = config('port');
21+
// Prompt the user to select port if it's already taken.
22+
// Resolves with newly selected port or null if cancelled.
23+
choosePort(host, config('port'))
24+
.then(port =>
25+
detect(config('clientDevServerPort')).then(clientPort => [
26+
port,
27+
clientPort,
28+
]),
29+
)
30+
.then(([port, clientPort]) => {
31+
if (!port || !clientPort) {
32+
console.error('User cancelled');
33+
return;
34+
}
3135

32-
watcher.on('ready', () => {
33-
watcher.on('change', () => {
34-
log({
35-
title: 'webpack',
36-
level: 'warn',
37-
message:
38-
'Project build configuration has changed. Restarting the development devServer...',
39-
});
40-
devServer.dispose().then(() => {
41-
// Make sure our new webpack bundleConfigs aren't in the module cache.
42-
Object.keys(require.cache).forEach(modulePath => {
43-
if (modulePath.indexOf('config') !== -1) {
44-
delete require.cache[modulePath];
45-
} else if (modulePath.indexOf('internal') !== -1) {
46-
delete require.cache[modulePath];
47-
}
48-
});
36+
let HotDevelopment = require('./hotDevelopment').default;
37+
let devServer = new HotDevelopment(port, clientPort);
4938

50-
// Re-require the development devServer so that all new configs are used.
51-
HotDevelopment = require('./hotDevelopment').default;
39+
// Any changes to our webpack bundleConfigs should restart the development devServer.
40+
const watcher = chokidar.watch([
41+
pathResolve(appRootDir.get(), 'internal'),
42+
pathResolve(appRootDir.get(), 'config'),
43+
]);
5244

53-
// Create a new development devServer.
54-
devServer = new HotDevelopment();
55-
});
56-
});
45+
watcher.on('ready', () => {
46+
watcher.on('change', () => {
47+
log({
48+
title: 'webpack',
49+
level: 'warn',
50+
message:
51+
'Project build configuration has changed. Restarting the development devServer...',
52+
});
53+
devServer.dispose().then(() => {
54+
// Make sure our new webpack bundleConfigs aren't in the module cache.
55+
Object.keys(require.cache).forEach(modulePath => {
56+
if (modulePath.indexOf('config') !== -1) {
57+
delete require.cache[modulePath];
58+
} else if (modulePath.indexOf('internal') !== -1) {
59+
delete require.cache[modulePath];
60+
}
61+
});
62+
63+
// Re-require the development devServer so that all new configs are used.
64+
HotDevelopment = require('./hotDevelopment').default;
65+
66+
// Create a new development devServer.
67+
devServer = new HotDevelopment(port, clientPort);
68+
});
69+
});
5770

58-
// Wait until devServer is started.
59-
onResponsive(host, port, () => openBrowser(`http://${host}:${port}`));
60-
});
71+
// Wait until devServer is started to open browser
72+
onResponsive(host, port, () => openBrowser(`http://${host}:${port}`));
73+
});
6174

62-
// If we receive a kill cmd then we will first try to dispose our listeners.
63-
process.on(
64-
'SIGTERM',
65-
() => devServer && devServer.dispose().then(() => process.exit(0)),
66-
);
75+
// If we receive a kill cmd then we will first try to dispose our listeners.
76+
process.on(
77+
'SIGTERM',
78+
() => devServer && devServer.dispose().then(() => process.exit(0)),
79+
);
80+
});

0 commit comments

Comments
 (0)