Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-35928: Improve control over PatternFly shared modules used in Console plugins #13992

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as fs from 'fs';
import * as path from 'path';
import {
DynamicRemotePlugin,
Expand Down Expand Up @@ -50,18 +51,35 @@ const getPackageDependencies = (pkg: readPkg.PackageJson) => ({
const getPluginSDKPackageDependencies = () =>
loadVendorPackageJSON('@openshift-console/dynamic-plugin-sdk').dependencies;

const getPatternFlyMajorVersion = (pkg: ConsolePluginPackageJSON) => {
const pluginDeps = getPackageDependencies(pkg);
const pfCoreVersionRange = pluginDeps['@patternfly/react-core'];

return semver.validRange(pfCoreVersionRange)
? semver.minVersion(pfCoreVersionRange)?.major
: undefined;
};

const getPatternFlyStyles = (baseDir: string) =>
glob.sync(`${baseDir}/node_modules/@patternfly/react-styles/**/*.css`);

// https://webpack.js.org/plugins/module-federation-plugin/#sharing-hints
const getWebpackSharedModules = () => {
const getWebpackSharedModules = (pkg: ConsolePluginPackageJSON) => {
const pfMajorVersion = getPatternFlyMajorVersion(pkg);
const sdkPkgDeps = getPluginSDKPackageDependencies();

return sharedPluginModules.reduce<WebpackSharedObject>((acc, moduleName) => {
const { singleton, allowFallback } = getSharedModuleMetadata(moduleName);
const providedVersionRange = sdkPkgDeps[moduleName];
const moduleConfig: WebpackSharedConfig = { singleton };

// Console provides PatternFly 4 shared modules to its plugins for backwards compatibility.
// Plugins using PatternFly 5 and higher share the PatternFly code bits via dynamic modules.
// TODO(vojtech): remove this code when Console drops support for PatternFly 4
if (moduleName.startsWith('@patternfly/') && pfMajorVersion > 4) {
return acc;
}

if (!allowFallback) {
moduleConfig.import = false;
}
Expand Down Expand Up @@ -229,6 +247,18 @@ export type ConsoleRemotePluginOptions = Partial<{
* (such as `@patternfly/react-core`) that pulls in all of its code.
*/
sharedDynamicModuleSettings: Partial<{
/**
* Paths to `node_modules` directories to search when parsing dynamic modules.
*
* Paths listed here _must_ be absolute.
*
* If not specified, the list will contain a single entry:
* ```ts
* path.resolve(process.cwd(), 'node_modules')
* ```
*/
modulePaths: string[];

/**
* Attempt to parse dynamic modules for these packages.
*
Expand Down Expand Up @@ -299,21 +329,26 @@ export class ConsoleRemotePlugin implements webpack.WebpackPluginInstance {
validateConsoleProvidedSharedModules(this.pkg).report();
}

const resolvedModulePaths = this.adaptedOptions.sharedDynamicModuleSettings.modulePaths ?? [
path.resolve(process.cwd(), 'node_modules'),
];

this.sharedDynamicModuleMaps = Object.entries(
this.adaptedOptions.sharedDynamicModuleSettings.packageSpecs ?? {
'@patternfly/react-core': {},
'@patternfly/react-icons': {},
'@patternfly/react-table': {},
},
).reduce<Record<string, DynamicModuleMap>>(
(acc, [pkgName, { indexModule = 'dist/esm/index.js', resolutionField = 'module' }]) => ({
...acc,
[pkgName]: getDynamicModuleMap(
path.resolve(this.baseDir, 'node_modules', pkgName),
indexModule,
resolutionField,
),
}),
(acc, [pkgName, { indexModule = 'dist/esm/index.js', resolutionField = 'module' }]) => {
const basePath = resolvedModulePaths
.map((p) => path.resolve(p, pkgName))
.find((p) => fs.existsSync(p) && fs.statSync(p).isDirectory());

return basePath
? { ...acc, [pkgName]: getDynamicModuleMap(basePath, indexModule, resolutionField) }
: acc;
},
{},
);
}
Expand Down Expand Up @@ -358,7 +393,9 @@ export class ConsoleRemotePlugin implements webpack.WebpackPluginInstance {
}
});

const allSharedDynamicModules = Object.entries(this.sharedDynamicModuleMaps).reduce<
const consoleProvidedSharedModules = getWebpackSharedModules(this.pkg);

const sharedDynamicModules = Object.entries(this.sharedDynamicModuleMaps).reduce<
WebpackSharedObject
>(
(acc, [moduleName, dynamicModuleMap]) => ({
Expand All @@ -379,7 +416,7 @@ export class ConsoleRemotePlugin implements webpack.WebpackPluginInstance {
exposedModules,
},
extensions,
sharedModules: { ...getWebpackSharedModules(), ...allSharedDynamicModules },
sharedModules: { ...consoleProvidedSharedModules, ...sharedDynamicModules },
entryCallbackSettings: {
name: 'loadPluginEntry',
pluginID: `${name}@${version}`,
Expand Down