mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Auto open browser on server startup (#24843)
* Adds dev dependency on opn for opening browsers and other things. * Adds a --open option to cli to open browser window. * Removes unused variable in index. * Adds opn types to dev dependencies from definitely typed. * Adds open to the cliArgs type to allow for consistency. * Updates snapshots that require valid cliArgs types. * Moves opn to direct dependency since its used in cli. * [cli] move --open handling to cluster manager * Adds support for running --open with --no-base-path
This commit is contained in:
parent
c757990be1
commit
c2425c1cdd
12 changed files with 97 additions and 13 deletions
|
@ -150,6 +150,7 @@
|
|||
"ngreact": "0.5.1",
|
||||
"no-ui-slider": "1.2.0",
|
||||
"node-fetch": "1.3.2",
|
||||
"opn": "^5.4.0",
|
||||
"oppsy": "^2.0.0",
|
||||
"pegjs": "0.9.0",
|
||||
"postcss-loader": "2.0.6",
|
||||
|
@ -252,6 +253,7 @@
|
|||
"@types/moment-timezone": "^0.5.8",
|
||||
"@types/mustache": "^0.8.31",
|
||||
"@types/node": "^8.10.20",
|
||||
"@types/opn": "^5.1.0",
|
||||
"@types/prop-types": "^15.5.3",
|
||||
"@types/puppeteer": "^1.6.2",
|
||||
"@types/react": "16.3.14",
|
||||
|
|
|
@ -18,9 +18,12 @@
|
|||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
import { format as formatUrl } from 'url';
|
||||
import opn from 'opn';
|
||||
|
||||
import { debounce, invoke, bindAll, once, uniq } from 'lodash';
|
||||
import { fromEvent, race } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import * as Rx from 'rxjs';
|
||||
import { first, mapTo, filter, map, take } from 'rxjs/operators';
|
||||
|
||||
import Log from '../log';
|
||||
import Worker from './worker';
|
||||
|
@ -88,6 +91,15 @@ export default class ClusterManager {
|
|||
|
||||
bindAll(this, 'onWatcherAdd', 'onWatcherError', 'onWatcherChange');
|
||||
|
||||
if (opts.open) {
|
||||
this.setupOpen(formatUrl({
|
||||
protocol: config.get('server.ssl.enabled') ? 'https' : 'http',
|
||||
hostname: config.get('server.host'),
|
||||
port: config.get('server.port'),
|
||||
pathname: (this.basePathProxy ? this.basePathProxy.basePath : ''),
|
||||
}));
|
||||
}
|
||||
|
||||
if (opts.watch) {
|
||||
const pluginPaths = config.get('plugins.paths');
|
||||
const scanDirs = config.get('plugins.scanDirs');
|
||||
|
@ -124,6 +136,28 @@ export default class ClusterManager {
|
|||
}
|
||||
}
|
||||
|
||||
setupOpen(openUrl) {
|
||||
const serverListening$ = Rx.merge(
|
||||
Rx.fromEvent(this.server, 'listening')
|
||||
.pipe(mapTo(true)),
|
||||
Rx.fromEvent(this.server, 'fork:exit')
|
||||
.pipe(mapTo(false)),
|
||||
Rx.fromEvent(this.server, 'crashed')
|
||||
.pipe(mapTo(false))
|
||||
);
|
||||
|
||||
const optimizeSuccess$ = Rx.fromEvent(this.optimizer, 'optimizeStatus')
|
||||
.pipe(map(msg => !!msg.success));
|
||||
|
||||
Rx.combineLatest(serverListening$, optimizeSuccess$)
|
||||
.pipe(
|
||||
filter(([serverListening, optimizeSuccess]) => serverListening && optimizeSuccess),
|
||||
take(1),
|
||||
)
|
||||
.toPromise()
|
||||
.then(() => opn(openUrl));
|
||||
}
|
||||
|
||||
setupWatching(extraPaths, extraIgnores) {
|
||||
const chokidar = require('chokidar');
|
||||
const { fromRoot } = require('../../utils');
|
||||
|
@ -229,7 +263,10 @@ export default class ClusterManager {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return race(fromEvent(this.server, 'listening'), fromEvent(this.server, 'crashed'))
|
||||
return Rx.race(
|
||||
Rx.fromEvent(this.server, 'listening'),
|
||||
Rx.fromEvent(this.server, 'crashed')
|
||||
)
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
}
|
||||
|
|
|
@ -125,6 +125,9 @@ export default class Worker extends EventEmitter {
|
|||
case 'WORKER_BROADCAST':
|
||||
this.emit('broadcast', data);
|
||||
break;
|
||||
case 'OPTIMIZE_STATUS':
|
||||
this.emit('optimizeStatus', data);
|
||||
break;
|
||||
case 'WORKER_LISTENING':
|
||||
this.listening = true;
|
||||
this.emit('listening');
|
||||
|
|
|
@ -191,6 +191,7 @@ export default function (program) {
|
|||
if (CAN_CLUSTER) {
|
||||
command
|
||||
.option('--dev', 'Run the server with development mode defaults')
|
||||
.option('--open', 'Open a browser window to the base url after the server is started')
|
||||
.option('--ssl', 'Run the dev server using HTTPS')
|
||||
.option('--no-base-path', 'Don\'t put a proxy in front of the dev server, which adds a random basePath')
|
||||
.option('--no-watch', 'Prevents automatic restarts of the server in --dev mode');
|
||||
|
@ -214,6 +215,7 @@ export default function (program) {
|
|||
configs: [].concat(opts.config || []),
|
||||
cliArgs: {
|
||||
dev: !!opts.dev,
|
||||
open: !!opts.open,
|
||||
envName: unknownOptions.env ? unknownOptions.env.name : undefined,
|
||||
quiet: !!opts.quiet,
|
||||
silent: !!opts.silent,
|
||||
|
|
|
@ -30,6 +30,7 @@ export function getEnvOptions(options: DeepPartial<EnvOptions> = {}): EnvOptions
|
|||
configs: options.configs || [],
|
||||
cliArgs: {
|
||||
dev: true,
|
||||
open: false,
|
||||
quiet: false,
|
||||
silent: false,
|
||||
watch: false,
|
||||
|
|
|
@ -7,6 +7,7 @@ Env {
|
|||
"basePath": false,
|
||||
"dev": true,
|
||||
"envName": "development",
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
@ -42,6 +43,7 @@ Env {
|
|||
"basePath": false,
|
||||
"dev": false,
|
||||
"envName": "production",
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
@ -76,6 +78,7 @@ Env {
|
|||
"cliArgs": Object {
|
||||
"basePath": false,
|
||||
"dev": true,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
@ -110,6 +113,7 @@ Env {
|
|||
"cliArgs": Object {
|
||||
"basePath": false,
|
||||
"dev": false,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
@ -144,6 +148,7 @@ Env {
|
|||
"cliArgs": Object {
|
||||
"basePath": false,
|
||||
"dev": false,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
@ -178,6 +183,7 @@ Env {
|
|||
"cliArgs": Object {
|
||||
"basePath": false,
|
||||
"dev": false,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
|
|
@ -50,6 +50,7 @@ export interface CliArgs {
|
|||
repl: boolean;
|
||||
basePath: boolean;
|
||||
optimize: boolean;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
export class Env {
|
||||
|
|
|
@ -6,6 +6,7 @@ Array [
|
|||
Object {
|
||||
"basePath": true,
|
||||
"dev": true,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": true,
|
||||
"repl": false,
|
||||
|
@ -59,6 +60,7 @@ Array [
|
|||
Object {
|
||||
"basePath": false,
|
||||
"dev": true,
|
||||
"open": false,
|
||||
"optimize": false,
|
||||
"quiet": false,
|
||||
"repl": false,
|
||||
|
|
|
@ -18,23 +18,33 @@
|
|||
*/
|
||||
|
||||
import WatchServer from './watch_server';
|
||||
import WatchOptimizer from './watch_optimizer';
|
||||
import WatchOptimizer, { STATUS } from './watch_optimizer';
|
||||
|
||||
export default async (kbnServer, kibanaHapiServer, config) => {
|
||||
const watchOptimizer = new WatchOptimizer({
|
||||
log: (tags, data) => kibanaHapiServer.log(tags, data),
|
||||
uiBundles: kbnServer.uiBundles,
|
||||
profile: config.get('optimize.profile'),
|
||||
sourceMaps: config.get('optimize.sourceMaps'),
|
||||
prebuild: config.get('optimize.watchPrebuild'),
|
||||
unsafeCache: config.get('optimize.unsafeCache'),
|
||||
});
|
||||
|
||||
const server = new WatchServer(
|
||||
config.get('optimize.watchHost'),
|
||||
config.get('optimize.watchPort'),
|
||||
config.get('server.basePath'),
|
||||
new WatchOptimizer({
|
||||
log: (tags, data) => kibanaHapiServer.log(tags, data),
|
||||
uiBundles: kbnServer.uiBundles,
|
||||
profile: config.get('optimize.profile'),
|
||||
sourceMaps: config.get('optimize.sourceMaps'),
|
||||
prebuild: config.get('optimize.watchPrebuild'),
|
||||
unsafeCache: config.get('optimize.unsafeCache'),
|
||||
})
|
||||
watchOptimizer
|
||||
);
|
||||
|
||||
watchOptimizer.status$.subscribe({
|
||||
next(status) {
|
||||
process.send(['OPTIMIZE_STATUS', {
|
||||
success: status.type === STATUS.SUCCESS
|
||||
}]);
|
||||
}
|
||||
});
|
||||
|
||||
let ready = false;
|
||||
|
||||
const sendReady = () => {
|
||||
|
|
|
@ -24,7 +24,7 @@ import BaseOptimizer from '../base_optimizer';
|
|||
|
||||
import { createBundlesRoute } from '../bundles_route';
|
||||
|
||||
const STATUS = {
|
||||
export const STATUS = {
|
||||
RUNNING: 'optimizer running',
|
||||
SUCCESS: 'optimizer completed successfully',
|
||||
FAILURE: 'optimizer failed with stats',
|
||||
|
|
|
@ -57,6 +57,7 @@ export function createRootWithSettings(...settings: Array<Record<string, any>>)
|
|||
configs: [],
|
||||
cliArgs: {
|
||||
dev: false,
|
||||
open: false,
|
||||
quiet: false,
|
||||
silent: false,
|
||||
watch: false,
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -887,6 +887,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.21.tgz#12b3f2359b27aa05a45d886c8ba1eb8d1a77e285"
|
||||
integrity sha512-87XkD9qDXm8fIax+5y7drx84cXsu34ZZqfB7Cial3Q/2lxSoJ/+DRaWckkCbxP41wFSIrrb939VhzaNxj4eY1w==
|
||||
|
||||
"@types/opn@^5.1.0":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/opn/-/opn-5.1.0.tgz#bff7bc371677f4bdbb37884400e03fd81f743927"
|
||||
integrity sha512-TNPrB7Y1xl06zDI0aGyqkgxjhIev3oJ+cdqlZ52MTAHauWpEL/gIUdHebIfRHFZk9IqSBpE2ci1DT48iZH81yg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/p-cancelable@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/p-cancelable/-/p-cancelable-0.3.0.tgz#3e4fcc54a3dfd81d0f5b93546bb68d0df50553bb"
|
||||
|
@ -8977,6 +8984,11 @@ is-word-character@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb"
|
||||
integrity sha1-WgP6HqkazopusMfNdw64bWXIvvs=
|
||||
|
||||
is-wsl@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
|
||||
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
|
@ -11984,6 +11996,13 @@ onetime@^2.0.0:
|
|||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
opn@^5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035"
|
||||
integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==
|
||||
dependencies:
|
||||
is-wsl "^1.1.0"
|
||||
|
||||
oppsy@2.x.x, oppsy@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/oppsy/-/oppsy-2.0.0.tgz#3a194517adc24c3c61cdc56f35f4537e93a35e34"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue