diff --git a/src/common/library.ts b/src/common/library.ts index 6a74a3708b..7cfac4eb9d 100644 --- a/src/common/library.ts +++ b/src/common/library.ts @@ -3,7 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import applicationInformationToken from "./vars/application-information-token.injectable"; +import type { ApplicationInformation } from "./vars/application-information-token.injectable"; export { applicationInformationToken, + ApplicationInformation, }; diff --git a/src/common/vars/application-information-token.injectable.ts b/src/common/vars/application-information-token.injectable.ts index dcd56a3146..816472831d 100644 --- a/src/common/vars/application-information-token.injectable.ts +++ b/src/common/vars/application-information-token.injectable.ts @@ -6,8 +6,9 @@ import { getInjectionToken } from "@ogre-tools/injectable"; import type packageJson from "../../../package.json"; -export type ApplicationInformation = Pick & { +export type ApplicationInformation = Pick & { build: Partial & { publish?: unknown[] }; + config: typeof packageJson["config"] & { extensions?: string[] }; }; const applicationInformationToken = getInjectionToken({ diff --git a/src/extensions/extension-discovery/bundled-extensions.injectable.ts b/src/extensions/extension-discovery/bundled-extensions.injectable.ts new file mode 100644 index 0000000000..f7ff14eb6b --- /dev/null +++ b/src/extensions/extension-discovery/bundled-extensions.injectable.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import type { InstalledExtension } from "./extension-discovery"; + +const bundledExtensionsInjectable = getInjectable({ + id: "bundled-extensions", + instantiate: (): InstalledExtension[] => [], +}); + +export default bundledExtensionsInjectable; diff --git a/src/extensions/extension-discovery/extension-discovery.injectable.ts b/src/extensions/extension-discovery/extension-discovery.injectable.ts index eeb0a99df0..ad586c8120 100644 --- a/src/extensions/extension-discovery/extension-discovery.injectable.ts +++ b/src/extensions/extension-discovery/extension-discovery.injectable.ts @@ -29,6 +29,7 @@ import removePathInjectable from "../../common/fs/remove-path.injectable"; import homeDirectoryPathInjectable from "../../common/os/home-directory-path.injectable"; import applicationInformationToken from "../../common/vars/application-information-token.injectable"; import lensResourcesDirInjectable from "../../common/vars/lens-resources-dir.injectable"; +import bundledExtensionsInjectable from "./bundled-extensions.injectable"; const extensionDiscoveryInjectable = getInjectable({ id: "extension-discovery", @@ -59,6 +60,7 @@ const extensionDiscoveryInjectable = getInjectable({ joinPaths: di.inject(joinPathsInjectable), homeDirectoryPath: di.inject(homeDirectoryPathInjectable), applicationInformation: di.inject(applicationInformationToken), + bundledExtensions: di.inject(bundledExtensionsInjectable), }), }); diff --git a/src/extensions/extension-discovery/extension-discovery.ts b/src/extensions/extension-discovery/extension-discovery.ts index 8c96159bd6..d6cdc4c5eb 100644 --- a/src/extensions/extension-discovery/extension-discovery.ts +++ b/src/extensions/extension-discovery/extension-discovery.ts @@ -37,6 +37,7 @@ interface Dependencies { readonly extensionsStore: ExtensionsStore; readonly extensionInstallationStateStore: ExtensionInstallationStateStore; readonly extensionPackageRootDirectory: string; + readonly bundledExtensions: InstalledExtension[]; readonly resourcesDirectory: string; readonly logger: Logger; readonly isProduction: boolean; @@ -384,32 +385,13 @@ export class ExtensionDiscovery { } async ensureExtensions(): Promise> { - const bundledExtensions = await this.loadBundledExtensions(); + const bundledExtensions = this.dependencies.bundledExtensions; const userExtensions = await this.loadFromFolder(this.localFolderPath, bundledExtensions.map((extension) => extension.manifest.name)); const extensions = bundledExtensions.concat(userExtensions); return this.extensions = new Map(extensions.map(extension => [extension.id, extension])); } - async loadBundledExtensions(): Promise { - const extensions: InstalledExtension[] = []; - const extensionNames = this.dependencies.applicationInformation.config.extensions || []; - - for (const dirName of extensionNames) { - const absPath = this.dependencies.joinPaths(__dirname, "..", "..", "node_modules", dirName); - const extension = await this.loadExtensionFromFolder(absPath, { isBundled: true }); - - if (!extension) { - throw new Error(`Couldn't load bundled extension: ${dirName}`); - } - - extensions.push(extension); - } - this.dependencies.logger.debug(`${logModule}: ${extensions.length} extensions loaded`, { extensions }); - - return extensions; - } - async loadFromFolder(folderPath: string, bundledExtensions: string[]): Promise { const extensions: InstalledExtension[] = []; const paths = await this.dependencies.readDirectory(folderPath); diff --git a/src/extensions/extension-loader/extension-loader.ts b/src/extensions/extension-loader/extension-loader.ts index c00414e88d..b85c63e369 100644 --- a/src/extensions/extension-loader/extension-loader.ts +++ b/src/extensions/extension-loader/extension-loader.ts @@ -344,7 +344,7 @@ export class ExtensionLoader { const extAbsolutePath = this.dependencies.joinPaths(this.dependencies.getDirnameOfPath(extension.manifestPath), extRelativePath); try { - return __non_webpack_require__(extAbsolutePath).default; + return require(/* webpackIgnore: true */ extAbsolutePath).default; } catch (error) { const message = (error instanceof Error ? error.stack : undefined) || error; diff --git a/src/main/index.ts b/src/main/index.ts index 66820207ff..26fe9eccfb 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -13,6 +13,7 @@ const di = getDi(); startApp({ di, + extensions: [], }); export { Mobx, LensExtensions, Pty }; diff --git a/src/main/start-app.ts b/src/main/start-app.ts index d293c7a320..b1398cefaa 100644 --- a/src/main/start-app.ts +++ b/src/main/start-app.ts @@ -5,13 +5,38 @@ import type { DiContainer } from "@ogre-tools/injectable"; import startMainApplicationInjectable from "./start-main-application/start-main-application.injectable"; +import readJsonFileInjectable from "../common/fs/read-json-file.injectable"; +import joinPathsInjectable from "../common/path/join-paths.injectable"; +import type { LensExtensionManifest } from "../extensions/lens-extension"; +import bundledExtensionsInjectable from "../extensions/extension-discovery/bundled-extensions.injectable"; interface AppConfig { di: DiContainer; + extensions: { path: string }[]; } -export function startApp(conf: AppConfig) { - const { di } = conf; +export async function startApp(conf: AppConfig) { + const { di, extensions } = conf; - return di.inject(startMainApplicationInjectable); + const bundledExtensions = di.inject(bundledExtensionsInjectable); + const readJson = di.inject(readJsonFileInjectable); + const joinPaths = di.inject(joinPathsInjectable); + + for (const extension of extensions) { + const manifestPath = joinPaths(extension.path, "package.json"); + + bundledExtensions.push({ + id: manifestPath, + manifest: (await readJson(manifestPath)) as unknown as LensExtensionManifest, + manifestPath, + absolutePath: extension.path, + isCompatible: true, + isBundled: true, + isEnabled: true, + }); + } + + await di.inject(startMainApplicationInjectable); + + return di; } diff --git a/webpack/library-bundle.ts b/webpack/library-bundle.ts index fb6b90e4cd..a821e511f2 100644 --- a/webpack/library-bundle.ts +++ b/webpack/library-bundle.ts @@ -6,9 +6,12 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin"; import nodeExternals from "webpack-node-externals"; import { platform } from "os"; import path from "path"; +import type { WebpackPluginInstance } from "webpack"; import { DefinePlugin, optimize } from "webpack"; import { main, renderer } from "./library"; import { buildDir } from "./vars"; +import CircularDependencyPlugin from "circular-dependency-plugin"; +import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; const config = [ { @@ -30,6 +33,12 @@ const config = [ CONTEXT_MATCHER_FOR_NON_FEATURES: `/\\.injectable(\\.${platform})?\\.tsx?$/`, CONTEXT_MATCHER_FOR_FEATURES: `/\\/(main|common)\\/.+\\.injectable(\\.${platform})?\\.tsx?$/`, }), + new ForkTsCheckerPlugin(), + new CircularDependencyPlugin({ + cwd: __dirname, + exclude: /node_modules/, + failOnError: true, + }) as unknown as WebpackPluginInstance, ], }, { @@ -49,7 +58,14 @@ const config = [ externals: [ nodeExternals(), ], - plugins: [], + plugins: [ + new ForkTsCheckerPlugin(), + new CircularDependencyPlugin({ + cwd: __dirname, + exclude: /node_modules/, + failOnError: true, + }) as unknown as WebpackPluginInstance, + ], }, { ...renderer, @@ -81,6 +97,12 @@ const config = [ new optimize.LimitChunkCountPlugin({ maxChunks: 1, }), + new ForkTsCheckerPlugin(), + new CircularDependencyPlugin({ + cwd: __dirname, + exclude: /node_modules/, + failOnError: true, + }) as unknown as WebpackPluginInstance, ], }, ]; diff --git a/webpack/library.ts b/webpack/library.ts index b9eaf990a0..164d521275 100644 --- a/webpack/library.ts +++ b/webpack/library.ts @@ -13,8 +13,10 @@ import { assetsFolderName, buildDir, htmlTemplate, isDevelopment, mainDir, publi import HtmlWebpackPlugin from "html-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; +const defaultRendererConfig = rendererConfig({ showVars: false }); + const renderer: webpack.Configuration = ({ - ...rendererConfig({ showVars: false }), + ...defaultRendererConfig, plugins: [ // see also: https://github.com/Microsoft/monaco-editor-webpack-plugin#options new MonacoWebpackPlugin({ @@ -52,6 +54,9 @@ const main: webpack.Configuration = ({ libraryTarget: "global", path: buildDir, }, + optimization: { + minimize: false, + }, resolve: { extensions: [".json", ".js", ".ts"], }, @@ -59,6 +64,11 @@ const main: webpack.Configuration = ({ nodeExternals(), ], module: { + parser: { + javascript: { + commonjsMagicComments: true, + }, + }, rules: [ { test: /\.node$/, diff --git a/webpack/main.ts b/webpack/main.ts index 84efd63f22..1c92fba748 100755 --- a/webpack/main.ts +++ b/webpack/main.ts @@ -45,6 +45,11 @@ configs.push((): webpack.Configuration => { nodeExternals(), ], module: { + parser: { + javascript: { + commonjsMagicComments: true, + }, + }, rules: [ { test: /\.node$/, diff --git a/webpack/renderer.ts b/webpack/renderer.ts index 6545a74ee0..b481e33586 100755 --- a/webpack/renderer.ts +++ b/webpack/renderer.ts @@ -71,6 +71,11 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura minimize: false, }, module: { + parser: { + javascript: { + commonjsMagicComments: true, + }, + }, rules: [ { test: /\.node$/,