From 92479396aff47ef5ead4bacc1d4cabf8295dfee9 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Mon, 7 Mar 2022 19:41:36 +0200 Subject: [PATCH] tweak webpack-dev-server config Signed-off-by: Jari Kolehmainen --- Makefile | 6 ++--- package.json | 5 ++--- src/main/index.ts | 15 +++---------- src/main/lens-proxy.ts | 12 +++++----- src/main/router.ts | 21 +++++++++++++++--- src/main/router/router.injectable.ts | 14 +++++++++--- webpack.dev-server.ts | 33 ++++++++++++++++------------ webpack.main.ts | 3 +-- webpack.renderer.ts | 2 +- 9 files changed, 63 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 3f77546354..ad0c76e9d2 100644 --- a/Makefile +++ b/Makefile @@ -23,16 +23,14 @@ node_modules: yarn.lock binaries/client: node_modules yarn download-bins -static/build/LensDev.html: node_modules - yarn compile:renderer - .PHONY: compile-dev compile-dev: node_modules yarn compile:main --cache yarn compile:renderer --cache .PHONY: dev -dev: binaries/client build-extensions static/build/LensDev.html +dev: binaries/client build-extensions + rm -rf static/build/ yarn dev .PHONY: lint diff --git a/package.json b/package.json index e2471a172c..acf1262f03 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,9 @@ "dev": "concurrently -i -k \"yarn run dev-run -C\" yarn:dev:*", "dev-build": "concurrently yarn:compile:*", "debug-build": "concurrently yarn:compile:main yarn:compile:extension-types", - "dev-run": "nodemon --watch static/build/main.js --exec \"electron --remote-debugging-port=9223 --inspect .\"", + "dev-run": "nodemon --watch ./static/build/main.js --exec \"electron --remote-debugging-port=9223 --inspect .\"", "dev:main": "yarn run compile:main --watch --progress", - "dev:renderer": "yarn run compile:renderer --watch --progress", - "dev:extension-types": "yarn run compile:extension-types --watch --progress", + "dev:renderer": "yarn run ts-node webpack.dev-server.ts", "compile": "env NODE_ENV=production concurrently yarn:compile:*", "compile:main": "yarn run webpack --config webpack.main.ts", "compile:renderer": "yarn run webpack --config webpack.renderer.ts", diff --git a/src/main/index.ts b/src/main/index.ts index bbd8e73599..cf7dc47c65 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -7,10 +7,11 @@ import { injectSystemCAs } from "../common/system-ca"; import * as Mobx from "mobx"; +import httpProxy from "http-proxy"; import * as LensExtensionsCommonApi from "../extensions/common-api"; import * as LensExtensionsMainApi from "../extensions/main-api"; import { app, autoUpdater, dialog, powerMonitor } from "electron"; -import { appName, isIntegrationTesting, isMac, isWindows, productName, isDevelopment } from "../common/vars"; +import { appName, isIntegrationTesting, isMac, isWindows, productName } from "../common/vars"; import { LensProxy } from "./lens-proxy"; import { WindowManager } from "./window-manager"; import { ClusterManager } from "./cluster-manager"; @@ -164,7 +165,7 @@ di.runSetups().then(() => { const router = di.inject(routerInjectable); const shellApiRequest = di.inject(shellApiRequestInjectable); - const lensProxy = LensProxy.createInstance(router, { + const lensProxy = LensProxy.createInstance(router, httpProxy.createProxy(), { getClusterForRequest: (req) => ClusterManager.getInstance().getClusterForRequest(req), kubeApiRequest, shellApiRequest, @@ -227,16 +228,6 @@ di.runSetups().then(() => { logger.info("🖥️ Starting WindowManager"); const windowManager = WindowManager.createInstance(); - - // Override main content view url to local webpack-dev-server to support HMR / live-reload - if (isDevelopment) { - const { createDevServer } = await import("../../webpack.dev-server"); - const devServer = createDevServer(lensProxy.port); - - await devServer.start(); - windowManager.mainContentUrl = `http://localhost:${devServer.options.port}`; - } - const menuItems = di.inject(electronMenuItemsInjectable); const trayMenuItems = di.inject(trayMenuItemsInjectable); diff --git a/src/main/lens-proxy.ts b/src/main/lens-proxy.ts index a37c6d01e0..fa9d0ff56d 100644 --- a/src/main/lens-proxy.ts +++ b/src/main/lens-proxy.ts @@ -6,7 +6,7 @@ import type net from "net"; import type http from "http"; import spdy from "spdy"; -import httpProxy from "http-proxy"; +import type httpProxy from "http-proxy"; import { apiPrefix, apiKubePrefix } from "../common/vars"; import type { Router } from "./router"; import type { ContextHandler } from "./context-handler/context-handler"; @@ -57,14 +57,15 @@ export class LensProxy extends Singleton { protected proxyServer: http.Server; protected closed = false; protected retryCounters = new Map(); - protected proxy = this.createProxy(); protected getClusterForRequest: GetClusterForRequest; public port: number; - constructor(protected router: Router, { shellApiRequest, kubeApiRequest, getClusterForRequest }: LensProxyFunctions) { + constructor(protected router: Router, protected proxy: httpProxy, { shellApiRequest, kubeApiRequest, getClusterForRequest }: LensProxyFunctions) { super(); + this.configureProxy(proxy); + this.getClusterForRequest = getClusterForRequest; this.proxyServer = spdy.createServer({ @@ -78,6 +79,7 @@ export class LensProxy extends Singleton { this.proxyServer .on("upgrade", (req: http.IncomingMessage, socket: net.Socket, head: Buffer) => { + console.log("upgrade", req.url); const isInternal = req.url.startsWith(`${apiPrefix}?`); const cluster = getClusterForRequest(req); @@ -163,9 +165,7 @@ export class LensProxy extends Singleton { this.closed = true; } - protected createProxy(): httpProxy { - const proxy = httpProxy.createProxyServer(); - + protected configureProxy(proxy: httpProxy): httpProxy { proxy.on("proxyRes", (proxyRes, req, res) => { const retryCounterId = this.getRequestId(req); diff --git a/src/main/router.ts b/src/main/router.ts index 8ce17090a5..53551b2624 100644 --- a/src/main/router.ts +++ b/src/main/router.ts @@ -6,6 +6,7 @@ import Call from "@hapi/call"; import Subtext from "@hapi/subtext"; import type http from "http"; +import type httpProxy from "http-proxy"; import path from "path"; import { readFile } from "fs-extra"; import type { Cluster } from "../common/cluster/cluster"; @@ -40,6 +41,7 @@ export interface LensApiRequest

{ query: URLSearchParams; raw: { req: http.IncomingMessage; + res: http.ServerResponse; }; } @@ -62,6 +64,7 @@ function getMimeType(filename: string) { interface Dependencies { routePortForward: (request: LensApiRequest) => Promise; + httpProxy?: httpProxy; } export class Router { @@ -101,7 +104,7 @@ export class Router { cluster, path: url.pathname, raw: { - req, + req, res, }, response: res, query: url.searchParams, @@ -140,12 +143,24 @@ export class Router { filePath = `${publicPath}/${appName}.html`; } } - } protected addRoutes() { // Static assets - this.router.add({ method: "get", path: "/{path*}" }, Router.handleStaticFile); + if (this.dependencies.httpProxy) { + this.router.add({ method: "get", path: "/{path*}" }, (apiReq: LensApiRequest) => { + const { req, res } = apiReq.raw; + + if (req.url === "/" || !req.url.startsWith("/build/")) req.url = "/build/OpenLensDev.html"; + + this.dependencies.httpProxy.web(req, res, { + target: "http://127.0.0.1:8080", + }); + }); + } else { + this.router.add({ method: "get", path: "/{path*}" }, Router.handleStaticFile); + } + this.router.add({ method: "get", path: "/version" }, VersionRoute.getVersion); this.router.add({ method: "get", path: `${apiPrefix}/kubeconfig/service-account/{namespace}/{account}` }, KubeconfigRoute.routeServiceAccountRoute); diff --git a/src/main/router/router.injectable.ts b/src/main/router/router.injectable.ts index d7372824b4..ce27c27995 100644 --- a/src/main/router/router.injectable.ts +++ b/src/main/router/router.injectable.ts @@ -3,6 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import isDevelopmentInjectable from "../../common/vars/is-development.injectable"; +import httpProxy from "http-proxy"; import { Router } from "../router"; import routePortForwardInjectable from "../routes/port-forward/route-port-forward/route-port-forward.injectable"; @@ -10,9 +12,15 @@ import routePortForwardInjectable const routerInjectable = getInjectable({ id: "router", - instantiate: (di) => new Router({ - routePortForward: di.inject(routePortForwardInjectable), - }), + instantiate: (di) => { + const isDevelopment = di.inject(isDevelopmentInjectable); + const proxy = isDevelopment ? httpProxy.createProxy() : undefined; + + return new Router({ + routePortForward: di.inject(routePortForwardInjectable), + httpProxy: proxy, + }); + }, }); export default routerInjectable; diff --git a/webpack.dev-server.ts b/webpack.dev-server.ts index 7ea97afed0..16863b18d9 100644 --- a/webpack.dev-server.ts +++ b/webpack.dev-server.ts @@ -9,16 +9,13 @@ import { webpackLensRenderer } from "./webpack.renderer"; import { buildDir } from "./src/common/vars"; import logger from "./src/common/logger"; -export interface DevServer extends WebpackDevServer { -} - /** * Creates `webpack-dev-server` * API docs: * @url https://webpack.js.org/configuration/dev-server/ * @url https://github.com/chimurai/http-proxy-middleware */ -export function createDevServer(lensProxyPort: number): DevServer { +function createDevServer(): WebpackDevServer { const config = webpackLensRenderer({ showVars: false }); const compiler = Webpack(config); @@ -31,17 +28,13 @@ export function createDevServer(lensProxyPort: number): DevServer { static: buildDir, // aka `devServer.contentBase` in webpack@4 hot: "only", // use HMR only without errors liveReload: false, + devMiddleware: { + writeToDisk: false, + index: "OpenLensDev.html", + publicPath: "/build", + }, proxy: { - "*": { - router(req) { - logger.silly(`[WEBPACK-DEV-SERVER]: proxy path ${req.path}`, req.headers); - - return `http://localhost:${lensProxyPort}`; - }, - secure: false, // allow http connections - ws: true, // proxy websockets, e.g. terminal - logLevel: "error", - }, + "^/$": "/build/", }, client: { overlay: false, // don't show warnings and errors on top of rendered app view @@ -53,3 +46,15 @@ export function createDevServer(lensProxyPort: number): DevServer { return server; } + +const server = createDevServer(); + +server.start(); + +process.once("SIGTERM", () => { + server.stop().then(() => process.exit(0)); +}); + +process.once("SIGINT", () => { + server.stop().then(() => process.exit(0)); +}); diff --git a/webpack.main.ts b/webpack.main.ts index cfd426e8c2..9097be0fbb 100755 --- a/webpack.main.ts +++ b/webpack.main.ts @@ -23,7 +23,7 @@ configs.push((): webpack.Configuration => { target: "electron-main", mode: isDevelopment ? "development" : "production", devtool: isDevelopment ? "cheap-module-source-map" : "source-map", - cache: isDevelopment, + cache: isDevelopment ? { type: "filesystem" } : false, entry: { main: path.resolve(mainDir, "index.ts"), }, @@ -49,7 +49,6 @@ configs.push((): webpack.Configuration => { }, plugins: [ new ForkTsCheckerPlugin(), - new CircularDependencyPlugin({ cwd: __dirname, exclude: /node_modules/, diff --git a/webpack.renderer.ts b/webpack.renderer.ts index f90f652c19..0910cabde6 100755 --- a/webpack.renderer.ts +++ b/webpack.renderer.ts @@ -28,7 +28,7 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura mode: isDevelopment ? "development" : "production", // https://webpack.js.org/configuration/devtool/ (see description of each option) devtool: isDevelopment ? "cheap-module-source-map" : "source-map", - cache: isDevelopment, + cache: isDevelopment ? { type: "filesystem" } : false, entry: { [appName]: path.resolve(rendererDir, "bootstrap.tsx"), },