From 4bdbedaeecdbff84a2bfdfc1df1d16faf66e8bd7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 28 Feb 2020 00:05:22 +0100 Subject: [PATCH] packages/cli: use react-dev-utils to select port and open browser + bit of refactor --- frontend/packages/cli/package.json | 1 + .../packages/cli/src/commands/serve/index.ts | 32 ++----------- .../packages/cli/src/commands/serve/server.ts | 43 +++++++++++++++++ frontend/yarn.lock | 48 +++++++++++++++++++ 4 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 frontend/packages/cli/src/commands/serve/server.ts diff --git a/frontend/packages/cli/package.json b/frontend/packages/cli/package.json index 2e353b478a..91e39380ed 100644 --- a/frontend/packages/cli/package.json +++ b/frontend/packages/cli/package.json @@ -36,6 +36,7 @@ "handlebars": "^4.7.3", "html-webpack-plugin": "^3.2.0", "inquirer": "^7.0.4", + "react-dev-utils": "^10.2.0", "recursive-readdir": "^2.2.2", "replace-in-file": "^5.0.2", "ts-loader": "^6.2.1", diff --git a/frontend/packages/cli/src/commands/serve/index.ts b/frontend/packages/cli/src/commands/serve/index.ts index c199107a2b..c67a375d72 100644 --- a/frontend/packages/cli/src/commands/serve/index.ts +++ b/frontend/packages/cli/src/commands/serve/index.ts @@ -1,35 +1,9 @@ -import webpack from 'webpack'; import chalk from 'chalk'; -import WebpackDevServer from 'webpack-dev-server'; -import { getPaths } from './paths'; -import { createConfig } from './config'; +import { startDevServer } from './server'; -function startDevServer(options: { host?: string; port?: number }) { - const host = options.host ?? process.env.HOST ?? '0.0.0.0'; - const port = options.port ?? (parseInt(process.env.PORT ?? '', 10) || 3000); - - const paths = getPaths(); - const config = createConfig(paths); - const compiler = webpack(config); - const server = new WebpackDevServer(compiler, { - hot: true, - publicPath: '/', - quiet: true, - host, - port, - }); - - server.listen(port, host, (err?: Error) => { - if (err) { - console.error(chalk.red(err.message)); - process.exit(1); - } - }); -} - -export default () => { +export default async () => { try { - startDevServer({}); + await startDevServer(); } catch (error) { console.error(chalk.red(error.message)); process.exit(1); diff --git a/frontend/packages/cli/src/commands/serve/server.ts b/frontend/packages/cli/src/commands/serve/server.ts new file mode 100644 index 0000000000..8ff0ced072 --- /dev/null +++ b/frontend/packages/cli/src/commands/serve/server.ts @@ -0,0 +1,43 @@ +import webpack from 'webpack'; +import WebpackDevServer from 'webpack-dev-server'; +import openBrowser from 'react-dev-utils/openBrowser'; +import { choosePort, prepareUrls } from 'react-dev-utils/WebpackDevServerUtils'; +import { getPaths } from './paths'; +import { createConfig } from './config'; + +export async function startDevServer() { + const host = process.env.HOST ?? '0.0.0.0'; + const defaultPort = parseInt(process.env.PORT ?? '', 10) || 3000; + + const port = await choosePort(host, defaultPort); + if (!port) { + return; + } + + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; + const urls = prepareUrls(protocol, host, port); + + const paths = getPaths(); + const config = createConfig(paths); + const compiler = webpack(config); + const server = new WebpackDevServer(compiler, { + hot: true, + publicPath: '/', + quiet: true, + https: protocol === 'https', + host, + port, + }); + + await new Promise((resolve, reject) => { + server.listen(port, host, (err?: Error) => { + if (err) { + reject(err); + return; + } + + openBrowser(urls.localUrlForBrowser); + resolve(); + }); + }); +} diff --git a/frontend/yarn.lock b/frontend/yarn.lock index cfe1d07341..5767a28686 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8783,6 +8783,11 @@ is-directory@^0.3.1: resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= +is-docker@^2.0.0: + version "2.0.0" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" + integrity sha1-LLDfDnXi0GT+GGTDfN6st7Lc8ls= + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -12137,6 +12142,14 @@ open@^6.4.0: dependencies: is-wsl "^1.1.0" +open@^7.0.2: + version "7.0.2" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/open/-/open-7.0.2.tgz#fb3681f11f157f2361d2392307548ca1792960e8" + integrity sha1-+zaB8R8VfyNh0jkjB1SMoXkpYOg= + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + opener@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" @@ -13814,6 +13827,36 @@ react-dev-utils@^10.0.0: strip-ansi "6.0.0" text-table "0.2.0" +react-dev-utils@^10.2.0: + version "10.2.0" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/react-dev-utils/-/react-dev-utils-10.2.0.tgz#b11cc48aa2be2502fb3c27a50d1dfa95cfa9dfe0" + integrity sha1-sRzEiqK+JQL7PCelDR36lc+p3+A= + dependencies: + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.8.6" + chalk "2.4.2" + cross-spawn "7.0.1" + detect-port-alt "1.1.6" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" + global-modules "2.0.0" + globby "8.0.2" + gzip-size "5.1.1" + immer "1.10.0" + inquirer "7.0.4" + is-root "2.1.0" + loader-utils "1.2.3" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.6" + recursive-readdir "2.2.2" + shell-quote "1.7.2" + strip-ansi "6.0.0" + text-table "0.2.0" + react-dom@^16.12.0: version "16.12.0" resolved "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" @@ -13829,6 +13872,11 @@ react-error-overlay@^6.0.5: resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.5.tgz#55d59c2a3810e8b41922e0b4e5f85dcf239bd533" integrity sha512-+DMR2k5c6BqMDSMF8hLH0vYKtKTeikiFW+fj0LClN+XZg4N9b8QUAdHC62CGWNLTi/gnuuemNcNcTFrCvK1f+A== +react-error-overlay@^6.0.6: + version "6.0.6" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/react-error-overlay/-/react-error-overlay-6.0.6.tgz#ac4d9dc4c1b5c536c2c312bf66aa2b09bfa384e2" + integrity sha1-rE2dxMG1xTbCwxK/ZqorCb+jhOI= + react-fast-compare@^2.0.1, react-fast-compare@^2.0.2, react-fast-compare@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"