diff --git a/packages/react-scripts/config/webpackDevServer.config.js b/packages/react-scripts/config/webpackDevServer.config.js index d8c1b885c25..a7a0f7b3284 100644 --- a/packages/react-scripts/config/webpackDevServer.config.js +++ b/packages/react-scripts/config/webpackDevServer.config.js @@ -17,7 +17,7 @@ const paths = require('./paths'); const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; const host = process.env.HOST || '0.0.0.0'; -module.exports = function(proxy) { +module.exports = function(proxy, allowedHost) { return { // Enable gzip compression of generated files. compress: true, @@ -67,6 +67,7 @@ module.exports = function(proxy) { // See https://github.com/facebookincubator/create-react-app/issues/387. disableDotRule: true, }, + public: allowedHost, proxy, setup(app) { // This lets us open files from the crash overlay. diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 9208b713878..eed8e4bc2ea 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -21,6 +21,8 @@ "react-scripts": "./bin/react-scripts.js" }, "dependencies": { + "@timer/detect-port": "1.1.2", + "address": "1.0.1", "autoprefixer": "6.7.7", "babel-core": "6.23.1", "babel-eslint": "7.1.1", @@ -33,7 +35,6 @@ "connect-history-api-fallback": "1.3.0", "cross-spawn": "4.0.2", "css-loader": "0.28.0", - "@timer/detect-port": "1.1.2", "dotenv": "2.0.0", "eslint": "3.16.1", "eslint-config-react-app": "^0.6.1", diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 0ea18e727cc..e5768fbbd12 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -22,6 +22,7 @@ process.env.NODE_ENV = 'development'; // Ensure environment variables are read. require('../config/env'); +const address = require('address'); const fs = require('fs'); const chalk = require('chalk'); const detect = require('@timer/detect-port'); @@ -53,25 +54,23 @@ const HOST = process.env.HOST || '0.0.0.0'; function run(port) { const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; - const formattedUrl = url.format({ - protocol, - hostname: HOST, - port, - pathname: '/', - }); - let prettyHost; - if (HOST === '0.0.0.0' || HOST === '::') { + const formatUrl = hostname => + url.format({ protocol, hostname, port, pathname: '/' }); + + const isUnspecifiedAddress = HOST === '0.0.0.0' || HOST === '::'; + let prettyHost, lanAddress; + if (isUnspecifiedAddress) { prettyHost = 'localhost'; + try { + lanAddress = address.ip(); + } catch (_e) { + // ignored + } } else { prettyHost = HOST; } - const prettyUrl = url.format({ - protocol, - hostname: prettyHost, - port, - pathname: '/', - }); + const prettyUrl = formatUrl(prettyHost); // Create a webpack compiler that is configured with custom messages. const compiler = createWebpackCompiler( @@ -81,9 +80,22 @@ function run(port) { return; } console.log(); - console.log('The app is running at:'); + console.log( + `You can now view ${chalk.bold(require(paths.appPackageJson).name)} in the browser.` + ); console.log(); - console.log(` ${chalk.cyan(formattedUrl)}`); + + if (isUnspecifiedAddress && lanAddress) { + console.log( + ` ${chalk.bold('Local:')} ${chalk.cyan(prettyUrl)}` + ); + console.log( + ` ${chalk.bold('On Your Network:')} ${chalk.cyan(formatUrl(lanAddress))}` + ); + } else { + console.log(` ${chalk.cyan(prettyUrl)}`); + } + console.log(); console.log('Note that the development build is not optimized.'); console.log( @@ -98,7 +110,7 @@ function run(port) { // Serve webpack assets generated by the compiler over a web sever. const devServer = new WebpackDevServer( compiler, - devServerConfig(prepareProxy(proxy)) + devServerConfig(prepareProxy(proxy), lanAddress) ); // Launch WebpackDevServer. @@ -113,7 +125,7 @@ function run(port) { console.log(chalk.cyan('Starting the development server...')); console.log(); - openBrowser(prettyUrl); + openBrowser(formatUrl(prettyHost)); }); }