mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add webpack hot-reload/cache plugins to improve Lens DX (#1250)
* Add webpack-dev-server (for hot module replacement) to serve statics, add HardSourceWebpackPlugin to improve re-compiling speed * Serve statics using webpack-dev-server instead of lens-proxy, redirect request of Lens.html/Lens.js to webpack-dev-server * Add react-refresh-webpack-plugin and its dep for hot-reload * Add hot-reload plugin, and make proxy redirects requests to webpackdevserver * Add hard-source webpack plugin to main process * Remove parameter 'path' of handleStaticFile * Upgarde webpack to v4 latest stable * Fix build error: plugins shouldnt be null Signed-off-by: Hung-Han (Henry) Chen <1474479+chenhunghan@users.noreply.github.com>
This commit is contained in:
parent
531e445981
commit
85f0ef8c2e
11
package.json
11
package.json
@ -15,7 +15,7 @@
|
|||||||
"dev-build": "concurrently yarn:compile:*",
|
"dev-build": "concurrently yarn:compile:*",
|
||||||
"dev-run": "nodemon --watch static/build/main.js --exec \"electron --inspect .\"",
|
"dev-run": "nodemon --watch static/build/main.js --exec \"electron --inspect .\"",
|
||||||
"dev:main": "yarn compile:main --watch",
|
"dev:main": "yarn compile:main --watch",
|
||||||
"dev:renderer": "yarn compile:renderer --watch",
|
"dev:renderer": "yarn webpack-dev-server --config webpack.renderer.ts",
|
||||||
"dev:extension-types": "yarn compile:extension-types --watch",
|
"dev:extension-types": "yarn compile:extension-types --watch",
|
||||||
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
|
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
|
||||||
"compile:main": "webpack --config webpack.main.ts",
|
"compile:main": "webpack --config webpack.main.ts",
|
||||||
@ -268,6 +268,7 @@
|
|||||||
"@lingui/macro": "^3.0.0-13",
|
"@lingui/macro": "^3.0.0-13",
|
||||||
"@lingui/react": "^3.0.0-13",
|
"@lingui/react": "^3.0.0-13",
|
||||||
"@material-ui/core": "^4.10.1",
|
"@material-ui/core": "^4.10.1",
|
||||||
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@testing-library/jest-dom": "^5.11.5",
|
"@testing-library/jest-dom": "^5.11.5",
|
||||||
"@testing-library/react": "^11.1.0",
|
"@testing-library/react": "^11.1.0",
|
||||||
@ -279,6 +280,7 @@
|
|||||||
"@types/electron-window-state": "^2.0.34",
|
"@types/electron-window-state": "^2.0.34",
|
||||||
"@types/fs-extra": "^9.0.1",
|
"@types/fs-extra": "^9.0.1",
|
||||||
"@types/hapi": "^18.0.3",
|
"@types/hapi": "^18.0.3",
|
||||||
|
"@types/hard-source-webpack-plugin": "^1.0.1",
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
"@types/html-webpack-plugin": "^3.2.3",
|
"@types/html-webpack-plugin": "^3.2.3",
|
||||||
"@types/http-proxy": "^1.17.4",
|
"@types/http-proxy": "^1.17.4",
|
||||||
@ -315,6 +317,7 @@
|
|||||||
"@types/uuid": "^8.0.0",
|
"@types/uuid": "^8.0.0",
|
||||||
"@types/webdriverio": "^4.13.0",
|
"@types/webdriverio": "^4.13.0",
|
||||||
"@types/webpack": "^4.41.17",
|
"@types/webpack": "^4.41.17",
|
||||||
|
"@types/webpack-dev-server": "^3.11.1",
|
||||||
"@types/webpack-env": "^1.15.2",
|
"@types/webpack-env": "^1.15.2",
|
||||||
"@types/webpack-node-externals": "^1.7.1",
|
"@types/webpack-node-externals": "^1.7.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
||||||
@ -339,6 +342,7 @@
|
|||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
"flex.box": "^3.4.4",
|
"flex.box": "^3.4.4",
|
||||||
"fork-ts-checker-webpack-plugin": "^5.0.0",
|
"fork-ts-checker-webpack-plugin": "^5.0.0",
|
||||||
|
"hard-source-webpack-plugin": "^0.13.1",
|
||||||
"hoist-non-react-statics": "^3.3.2",
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
"html-webpack-plugin": "^4.3.0",
|
"html-webpack-plugin": "^4.3.0",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
@ -360,6 +364,7 @@
|
|||||||
"react": "^16.14.0",
|
"react": "^16.14.0",
|
||||||
"react-beautiful-dnd": "^13.0.0",
|
"react-beautiful-dnd": "^13.0.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
"react-refresh": "^0.9.0",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-select": "^3.1.0",
|
"react-select": "^3.1.0",
|
||||||
@ -376,11 +381,13 @@
|
|||||||
"ts-jest": "^26.1.0",
|
"ts-jest": "^26.1.0",
|
||||||
"ts-loader": "^7.0.5",
|
"ts-loader": "^7.0.5",
|
||||||
"ts-node": "^8.10.2",
|
"ts-node": "^8.10.2",
|
||||||
|
"type-fest": "^0.18.0",
|
||||||
"typeface-roboto": "^0.0.75",
|
"typeface-roboto": "^0.0.75",
|
||||||
"typescript": "^4.0.2",
|
"typescript": "^4.0.2",
|
||||||
"url-loader": "^4.1.0",
|
"url-loader": "^4.1.0",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.44.2",
|
||||||
"webpack-cli": "^3.3.11",
|
"webpack-cli": "^3.3.11",
|
||||||
|
"webpack-dev-server": "^3.11.0",
|
||||||
"webpack-node-externals": "^1.7.2",
|
"webpack-node-externals": "^1.7.2",
|
||||||
"xterm": "^4.6.0",
|
"xterm": "^4.6.0",
|
||||||
"xterm-addon-fit": "^0.4.0"
|
"xterm-addon-fit": "^0.4.0"
|
||||||
|
|||||||
@ -22,6 +22,7 @@ export const mainDir = path.join(contextDir, "src/main");
|
|||||||
export const rendererDir = path.join(contextDir, "src/renderer");
|
export const rendererDir = path.join(contextDir, "src/renderer");
|
||||||
export const htmlTemplate = path.resolve(rendererDir, "template.html");
|
export const htmlTemplate = path.resolve(rendererDir, "template.html");
|
||||||
export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss");
|
export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss");
|
||||||
|
export const webpackDevServerPort = 9009
|
||||||
|
|
||||||
// Special runtime paths
|
// Special runtime paths
|
||||||
defineGlobal("__static", {
|
defineGlobal("__static", {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import http from "http"
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import { readFile } from "fs-extra"
|
import { readFile } from "fs-extra"
|
||||||
import { Cluster } from "./cluster"
|
import { Cluster } from "./cluster"
|
||||||
import { apiPrefix, appName, publicPath } from "../common/vars";
|
import { apiPrefix, appName, publicPath, isDevelopment, webpackDevServerPort } from "../common/vars";
|
||||||
import { helmRoute, kubeconfigRoute, metricsRoute, portForwardRoute, resourceApplierRoute, watchRoute } from "./routes";
|
import { helmRoute, kubeconfigRoute, metricsRoute, portForwardRoute, resourceApplierRoute, watchRoute } from "./routes";
|
||||||
|
|
||||||
export interface RouterRequestOpts {
|
export interface RouterRequestOpts {
|
||||||
@ -94,23 +94,35 @@ export class Router {
|
|||||||
return mimeTypes[path.extname(filename).slice(1)] || "text/plain"
|
return mimeTypes[path.extname(filename).slice(1)] || "text/plain"
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleStaticFile(filePath: string, res: http.ServerResponse) {
|
async handleStaticFile(filePath: string, res: http.ServerResponse, req: http.IncomingMessage) {
|
||||||
const asset = path.join(__static, filePath);
|
const asset = path.join(__static, filePath);
|
||||||
try {
|
try {
|
||||||
|
const filename = path.basename(req.url);
|
||||||
|
// redirect requests to [appName].js, [appName].html /sockjs-node/ to webpack-dev-server (for hot-reload support)
|
||||||
|
const toWebpackDevServer = filename.includes(appName) || filename.includes('hot-update') || req.url.includes('sockjs-node');
|
||||||
|
if (isDevelopment && toWebpackDevServer) {
|
||||||
|
const redirectLocation = `http://localhost:${webpackDevServerPort}` + req.url;
|
||||||
|
res.statusCode = 307;
|
||||||
|
res.setHeader('Location', redirectLocation);
|
||||||
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const data = await readFile(asset);
|
const data = await readFile(asset);
|
||||||
res.setHeader("Content-Type", this.getMimeType(asset));
|
res.setHeader("Content-Type", this.getMimeType(asset));
|
||||||
res.write(data)
|
res.write(data);
|
||||||
res.end()
|
res.end();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.handleStaticFile(`${publicPath}/${appName}.html`, res);
|
this.handleStaticFile(`${publicPath}/${appName}.html`, res, req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected addRoutes() {
|
protected addRoutes() {
|
||||||
// Static assets
|
// Static assets
|
||||||
this.router.add({ method: 'get', path: '/{path*}' }, ({ params, response }: LensApiRequest) => {
|
this.router.add(
|
||||||
this.handleStaticFile(params.path, response);
|
{ method: 'get', path: '/{path*}' },
|
||||||
});
|
({ params, response, path, raw: { req }}: LensApiRequest) => {
|
||||||
|
this.handleStaticFile(params.path, response, req);
|
||||||
|
});
|
||||||
|
|
||||||
this.router.add({ method: "get", path: `${apiPrefix}/kubeconfig/service-account/{namespace}/{account}` }, kubeconfigRoute.routeServiceAccountRoute.bind(kubeconfigRoute))
|
this.router.add({ method: "get", path: `${apiPrefix}/kubeconfig/service-account/{namespace}/{account}` }, kubeconfigRoute.routeServiceAccountRoute.bind(kubeconfigRoute))
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"
|
|||||||
import { isDevelopment, isProduction, mainDir, buildDir } from "./src/common/vars";
|
import { isDevelopment, isProduction, mainDir, buildDir } from "./src/common/vars";
|
||||||
import nodeExternals from "webpack-node-externals";
|
import nodeExternals from "webpack-node-externals";
|
||||||
import ProgressBarPlugin from "progress-bar-webpack-plugin";
|
import ProgressBarPlugin from "progress-bar-webpack-plugin";
|
||||||
|
import HardSourceWebpackPlugin from 'hard-source-webpack-plugin';
|
||||||
|
|
||||||
export default function (): webpack.Configuration {
|
export default function (): webpack.Configuration {
|
||||||
console.info('WEBPACK:main', require("./src/common/vars"))
|
console.info('WEBPACK:main', require("./src/common/vars"))
|
||||||
@ -47,6 +48,7 @@ export default function (): webpack.Configuration {
|
|||||||
plugins: [
|
plugins: [
|
||||||
new ProgressBarPlugin(),
|
new ProgressBarPlugin(),
|
||||||
new ForkTsCheckerPlugin(),
|
new ForkTsCheckerPlugin(),
|
||||||
]
|
isDevelopment && new HardSourceWebpackPlugin(),
|
||||||
|
].filter(Boolean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { appName, buildDir, htmlTemplate, isDevelopment, isProduction, publicPath, rendererDir, sassCommonVars } from "./src/common/vars";
|
import { appName, buildDir, htmlTemplate, isDevelopment, isProduction, publicPath, rendererDir, sassCommonVars, webpackDevServerPort } from "./src/common/vars";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import webpack from "webpack";
|
import webpack from "webpack";
|
||||||
import HtmlWebpackPlugin from "html-webpack-plugin";
|
import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||||
@ -6,6 +6,8 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|||||||
import TerserPlugin from "terser-webpack-plugin";
|
import TerserPlugin from "terser-webpack-plugin";
|
||||||
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"
|
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"
|
||||||
import ProgressBarPlugin from "progress-bar-webpack-plugin";
|
import ProgressBarPlugin from "progress-bar-webpack-plugin";
|
||||||
|
import HardSourceWebpackPlugin from 'hard-source-webpack-plugin';
|
||||||
|
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
webpackLensRenderer
|
webpackLensRenderer
|
||||||
@ -19,6 +21,15 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
|
|||||||
context: __dirname,
|
context: __dirname,
|
||||||
target: "electron-renderer",
|
target: "electron-renderer",
|
||||||
devtool: "source-map", // todo: optimize in dev-mode with webpack.SourceMapDevToolPlugin
|
devtool: "source-map", // todo: optimize in dev-mode with webpack.SourceMapDevToolPlugin
|
||||||
|
devServer: {
|
||||||
|
contentBase: buildDir,
|
||||||
|
port: webpackDevServerPort,
|
||||||
|
host: "localhost",
|
||||||
|
hot: true,
|
||||||
|
// to avoid cors errors when requests is from iframes
|
||||||
|
disableHostCheck: true,
|
||||||
|
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||||
|
},
|
||||||
name: "lens-app",
|
name: "lens-app",
|
||||||
mode: isProduction ? "production" : "development",
|
mode: isProduction ? "production" : "development",
|
||||||
cache: isDevelopment,
|
cache: isDevelopment,
|
||||||
@ -79,7 +90,10 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
|
|||||||
["@babel/preset-env", {
|
["@babel/preset-env", {
|
||||||
modules: "commonjs" // ling-ui
|
modules: "commonjs" // ling-ui
|
||||||
}],
|
}],
|
||||||
]
|
],
|
||||||
|
plugins: [
|
||||||
|
isDevelopment && require.resolve('react-refresh/babel'),
|
||||||
|
].filter(Boolean),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -172,6 +186,11 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
|
|||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: "[name].css",
|
filename: "[name].css",
|
||||||
}),
|
}),
|
||||||
],
|
|
||||||
|
isDevelopment && new HardSourceWebpackPlugin(),
|
||||||
|
isDevelopment && new webpack.HotModuleReplacementPlugin(),
|
||||||
|
isDevelopment && new ReactRefreshWebpackPlugin(),
|
||||||
|
|
||||||
|
].filter(Boolean),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user