From 98b516f2905787cf75cbb20f0fc581f1f715d978 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 1 Feb 2022 18:41:59 +0200 Subject: [PATCH] fix: loading svg icons inline as data-url (workaround for "?raw" as it fails in tests and "!!raw-loader!" seems doesn't work at all in webpack@5) Signed-off-by: Roman --- .../catalog-entities/kubernetes-cluster.ts | 3 +- .../components/hotbar/hotbar-menu.tsx | 1 + src/renderer/components/icon/icon.tsx | 5 ++- types/mocks.d.ts | 7 +-- webpack.extensions.ts | 11 ++--- webpack.main.ts | 8 ++-- webpack.renderer.ts | 45 ++++++++++--------- 7 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index b9d071a163..37c4efa399 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -11,6 +11,7 @@ import { app } from "electron"; import type { CatalogEntitySpec } from "../catalog/catalog-entity"; import { IpcRendererNavigationEvents } from "../../renderer/navigation/events"; import { requestClusterActivation, requestClusterDisconnection } from "../../renderer/ipc"; +import KubeClusterCategoryIcon from "./icons/kubernetes.svg"; export interface KubernetesClusterPrometheusMetrics { address?: { @@ -134,7 +135,7 @@ class KubernetesClusterCategory extends CatalogCategory { public readonly kind = "CatalogCategory"; public metadata = { name: "Clusters", - icon: require("./icons/kubernetes.svg?raw"), + icon: KubeClusterCategoryIcon, }; public spec: CatalogCategorySpec = { group: "entity.k8slens.dev", diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx index 4d6f57a89a..ed30b9f0d2 100644 --- a/src/renderer/components/hotbar/hotbar-menu.tsx +++ b/src/renderer/components/hotbar/hotbar-menu.tsx @@ -1,3 +1,4 @@ + /** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. diff --git a/src/renderer/components/icon/icon.tsx b/src/renderer/components/icon/icon.tsx index dc10de5fc2..d2166ea000 100644 --- a/src/renderer/components/icon/icon.tsx +++ b/src/renderer/components/icon/icon.tsx @@ -11,6 +11,7 @@ import type { LocationDescriptor } from "history"; import { boundMethod, cssNames } from "../../utils"; import { TooltipDecoratorProps, withTooltip } from "../tooltip"; import isNumber from "lodash/isNumber"; +import { decode } from "../../../common/utils/base64"; export interface IconProps extends React.HTMLAttributes, TooltipDecoratorProps { material?: string; // material-icon, see available names at https://material.io/icons/ @@ -98,7 +99,9 @@ export class Icon extends React.PureComponent { // render as inline svg-icon if (typeof svg === "string") { - const svgIconText = svg.includes("; } diff --git a/types/mocks.d.ts b/types/mocks.d.ts index 4842ebaaa1..cc260eacfd 100644 --- a/types/mocks.d.ts +++ b/types/mocks.d.ts @@ -27,12 +27,7 @@ declare module "*.scss" { } // Declare everything what's bundled as webpack's type="asset/resource" -declare module "*.svg?raw" { - export = ""; -} -declare module "*.svg" { - export = ""; -} +declare module "*.svg"; declare module "*.jpg"; declare module "*.png"; declare module "*.eot"; diff --git a/webpack.extensions.ts b/webpack.extensions.ts index 0af830b2dd..9cf8eb428c 100644 --- a/webpack.extensions.ts +++ b/webpack.extensions.ts @@ -7,11 +7,7 @@ import path from "path"; import type webpack from "webpack"; import * as vars from "./src/common/vars"; -import { - cssModulesWebpackRule, - filesAndIconsWebpackRule, - fontsLoaderWebpackRule, -} from "./webpack.renderer"; +import { cssModulesWebpackRule, fontsLoaderWebpackRules, iconsAndImagesWebpackRules } from "./webpack.renderer"; export default function generateExtensionTypes(): webpack.Configuration { const { isDevelopment, isProduction } = vars; @@ -58,10 +54,9 @@ export default function generateExtensionTypes(): webpack.Configuration { }, }, }, - fontsLoaderWebpackRule(), - filesAndIconsWebpackRule(), cssModulesWebpackRule({ styleLoader: "style-loader" }), - { resourceQuery: /raw/, type: "asset/source" }, + ...fontsLoaderWebpackRules(), + ...iconsAndImagesWebpackRules(), ], }, resolve: { diff --git a/webpack.main.ts b/webpack.main.ts index 6cf0cb29af..9f162f923e 100755 --- a/webpack.main.ts +++ b/webpack.main.ts @@ -10,6 +10,7 @@ import nodeExternals from "webpack-node-externals"; import * as vars from "./src/common/vars"; import getTSLoader from "./src/common/getTSLoader"; import CircularDependencyPlugin from "circular-dependency-plugin"; +import { iconsAndImagesWebpackRules } from "./webpack.renderer"; const configs: { (): webpack.Configuration }[] = []; @@ -21,7 +22,7 @@ configs.push((): webpack.Configuration => { context: __dirname, target: "electron-main", mode: isDevelopment ? "development" : "production", - devtool: isDevelopment ? "cheap-module-source-map" : "source-map", + devtool: isDevelopment ? "eval-cheap-source-map" : "source-map", cache: isDevelopment, entry: { main: path.resolve(mainDir, "index.ts"), @@ -43,10 +44,7 @@ configs.push((): webpack.Configuration => { use: "node-loader", }, getTSLoader({}, /\.ts$/), - { - resourceQuery: /raw/, // embed file as plain-text, e.g. require("./some-file.svg?raw") - type: "asset/source", - }, + ...iconsAndImagesWebpackRules(), ], }, plugins: [ diff --git a/webpack.renderer.ts b/webpack.renderer.ts index 0601c6cc75..9656b65979 100755 --- a/webpack.renderer.ts +++ b/webpack.renderer.ts @@ -30,7 +30,7 @@ export function webpackLensRenderer(): webpack.Configuration { target: "electron-renderer", name: "lens-app", mode: isDevelopment ? "development" : "production", - devtool: isDevelopment ? "cheap-module-source-map" : "source-map", + devtool: isDevelopment ? "eval-cheap-source-map" : "source-map", cache: isDevelopment, entry: { [appName]: path.resolve(rendererDir, "bootstrap.tsx"), @@ -68,14 +68,8 @@ export function webpackLensRenderer(): webpack.Configuration { }, getTSLoader(), cssModulesWebpackRule(), - filesAndIconsWebpackRule(), - fontsLoaderWebpackRule(), - { - // Allows to import/require() resource as plain text with suffix `?raw` - // To make it work must be listed in the end of `config.module.rules` - resourceQuery: /raw/, - type: "asset/source", - }, + ...iconsAndImagesWebpackRules(), + ...fontsLoaderWebpackRules(), ], }, @@ -111,23 +105,32 @@ export function webpackLensRenderer(): webpack.Configuration { } /** - * Import content of svg-icons, images and text files + * Import icons and image files. + * Read more about asset types: https://webpack.js.org/guides/asset-modules/ */ -export function filesAndIconsWebpackRule(): webpack.RuleSetRule { - return { - test: /\.(jpg|png|svg|map|ico)$/, - type: "asset/resource", // https://webpack.js.org/guides/asset-modules/ - }; +export function iconsAndImagesWebpackRules(): webpack.RuleSetRule[] { + return [ + { + test: /\.svg$/, + type: "asset/inline", // data:image/svg+xml;base64,... + }, + { + test: /\.(jpg|png|ico)$/, + type: "asset/resource", // path to file, e.g. "/static/assets/*" + }, + ]; } /** - * Import custom fonts as URL + * Import custom fonts as URL. */ -export function fontsLoaderWebpackRule(): webpack.RuleSetRule { - return { - test: /\.(ttf|eot|woff2?)$/, - type: "asset/resource", - }; +export function fontsLoaderWebpackRules(): webpack.RuleSetRule[] { + return [ + { + test: /\.(ttf|eot|woff2?)$/, + type: "asset/resource", + } + ]; } /**