Skip to content

Commit 9eede15

Browse files
author
Blake Holifield
authored
feat(core): allow directly using plugin manifest
1 parent 226a748 commit 9eede15

File tree

11 files changed

+219
-63
lines changed

11 files changed

+219
-63
lines changed

README.md

+34-23
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,23 @@ const moduleFederationPlugin = new ModuleFederationPlugin({
290290
name: 'host',
291291
filename: 'host.[contenthash].js',
292292
shared: [
293-
{'@openshift/dynamic-plugin-sdk': { singleton: true, requiredVersion: '*'} },
294-
{ '@scalprum/react-core': { singleton: true, requiredVersion: '*'} },
293+
{
294+
'@openshift/dynamic-plugin-sdk': {
295+
singleton: true,
296+
requiredVersion: '*',
297+
},
298+
},
299+
{
300+
'@scalprum/react-core': {
301+
singleton: true,
302+
requiredVersion: '*',
303+
},
304+
},
295305
{ react: { singleton: true, requiredVersion: '*' } },
296-
{ 'react-dom': { singleton: true, requiredVersion: '*' } },
306+
{ 'react-dom': { singleton: true, requiredVersion: '*'} },
297307
// any other packages you wish to share
298-
]
299-
})
308+
],
309+
});
300310
```
301311

302312
Note that for demo purposes, the `requiredVersion` for dependencies in this example is set to `*`, but you can update this to a version that suits your requirements.
@@ -329,23 +339,24 @@ This is a known issue that is being actively worked on.
329339
const { DynamicRemotePlugin } = require('@openshift/dynamic-plugin-sdk-webpack');
330340

331341
const sharedModules = {
332-
'@openshift/dynamic-plugin-sdk':( singleton: true},
333-
'@scalprum/react-core':( singleton: true},
334-
react: { singleton: true),
335-
'react-dom': ( singleton: true },
342+
'@openshift/dynamic-plugin-sdk': { singleton: true },
343+
'@scalprum/react-core': { singleton: true },
344+
react: { singleton: true },
345+
'react-dom': { singleton: true },
346+
};
336347

337348
const dynamicPlugin = new DynamicRemotePlugin({
349+
extensions: [],
350+
sharedModules,
351+
entryScriptfilename: 'remoteModule.[contenthash].js',
352+
pluginMetadata: {
353+
name: 'remoteModule',
354+
version: '1.0.0',
355+
exposedModules: {
356+
RemoteModuleComponent: './remoteModule/src/RemoteModuleComponent.tsx',
357+
},
338358
extensions: [],
339-
sharedModules,
340-
entryScriptfilename:'remoteModule.(contenthash].js',
341-
pluginMetadata: {
342-
name: "remoteModule",
343-
version: "1.0.0",
344-
exposedModules: {
345-
RemoteModuleComponent": "./remoteModule/src/RemoteModuleComponent.tsx"
346-
},
347-
extensions: []
348-
}
359+
},
349360
});
350361

351362
```
@@ -441,10 +452,10 @@ const moduleFederationPlugin = new ModuleFederationPlugin({
441452
filename: 'host.[contenthash].js',
442453
shared: [{
443454
// These packages has to be shared and has to be marked as singleton!
444-
{ '@openshift/dynamic-plugin-sdk', { singleton: true, eager: true}}
445-
{ '@scalprum/react-core': { singleton: true, eager: true} },
446-
{ react: { singleton: true, eager: true } },
447-
{ 'react-dom': { singleton: true, eager: true } },
455+
{ '@openshift/dynamic-plugin-sdk', { singleton: true, }}
456+
{ '@scalprum/react-core': { singleton: true, } },
457+
{ react: { singleton: true, } },
458+
{ 'react-dom': { singleton: true } },
448459
// any other packages you wish to share
449460
}]
450461
})
+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
22
import { defineConfig } from 'cypress';
33

4+
const nxe2eConfig = nxE2EPreset(__filename, { cypressDir: 'src' });
5+
6+
// Adds logging to terminal for debugging
7+
// https://docs.cypress.io/api/commands/task#Usage
8+
// Usage: `cy.task('log', 'my message');
49
export default defineConfig({
5-
e2e: nxE2EPreset(__filename, { cypressDir: 'src' }),
10+
e2e: {
11+
...nxe2eConfig,
12+
setupNodeEvents(on) {
13+
on('task', {
14+
log(message) {
15+
console.log(message);
16+
return null;
17+
},
18+
});
19+
},
20+
},
621
});

examples/test-app-e2e/src/e2e/test-app/sdk-plugin-loading.cy.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@ describe('SDK module loading', () => {
44
});
55
it('should show data from prefetch', () => {
66
cy.visit('http://localhost:4200/sdk');
7-
87
cy.get('div#sdk-module-item').contains('SDK Inbox').should('exist');
98
});
9+
10+
it('should render a slider from the pluginManifest', () => {
11+
cy.intercept('GET', '/full-manifest.js?cacheBuster=*').as('manifestRequest');
12+
cy.visit('http://localhost:4200/sdk');
13+
14+
cy.wait('@manifestRequest').then((interception) => {
15+
expect(interception.response.statusCode).to.eq(200);
16+
expect(interception.response.headers['content-type']).to.include('application/javascript');
17+
});
18+
cy.get(`[aria-label="Checked"]`).should('exist');
19+
cy.get('#plugin-manifest').should('exist');
20+
});
1021
});

examples/test-app/src/entry.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ const config: AppsConfig<{ assetsHost?: string }> = {
2121
assetsHost: 'http://127.0.0.1:8001',
2222
manifestLocation: 'http://127.0.0.1:8001/plugin-manifest.json',
2323
},
24+
'full-manifest': {
25+
name: 'full-manifest',
26+
assetsHost: 'http://127.0.0.1:8001',
27+
pluginManifest: {
28+
name: 'full-manifest',
29+
version: '1.0.0',
30+
extensions: [],
31+
registrationMethod: 'callback',
32+
baseURL: 'auto',
33+
loadScripts: ['full-manifest.js'],
34+
},
35+
},
2436
};
2537

2638
const Entry = () => {

examples/test-app/src/modules/SDKComponent.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ import Divider from '@mui/material/Divider';
1010
import Slider from '@mui/material/Slider';
1111
import InboxIcon from '@mui/icons-material/Inbox';
1212
import DraftsIcon from '@mui/icons-material/Drafts';
13+
import Checkbox from '@mui/material/Checkbox';
1314

1415
function valuetext(value: number) {
1516
return `${value}°C`;
1617
}
1718

19+
interface namedProps {
20+
name: string;
21+
}
22+
1823
export const NamedSDKComponent = () => {
1924
return (
2025
<Box sx={{ width: 300 }}>
@@ -23,6 +28,14 @@ export const NamedSDKComponent = () => {
2328
);
2429
};
2530

31+
export const PluginSDKComponent = (props: namedProps = { name: 'named' }) => {
32+
return (
33+
<Box sx={{ width: 300 }}>
34+
<Checkbox aria-label="Checked" id={props.name} defaultChecked />
35+
</Box>
36+
);
37+
};
38+
2639
const SDKComponent = () => {
2740
return (
2841
<Box sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>

examples/test-app/src/routes/SDKModules.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { ScalprumComponent } from '@scalprum/react-core';
33
import { Grid } from '@mui/material';
44

55
const SDKModules = () => {
6+
const props = {
7+
name: 'plugin-manifest',
8+
};
69
return (
710
<Grid container spacing={4}>
811
<Grid xs={12} md={6} item>
@@ -11,6 +14,9 @@ const SDKModules = () => {
1114
<Grid xs={12} md={6} item>
1215
<ScalprumComponent scope="sdk-plugin" module="./SDKComponent" importName="NamedSDKComponent" />
1316
</Grid>
17+
<Grid xs={12} md={6} item>
18+
<ScalprumComponent scope="full-manifest" module="./SDKComponent" importName="PluginSDKComponent" {...props} />
19+
</Grid>
1420
</Grid>
1521
);
1622
};

federation-cdn-mock/src/modules/SDKComponent.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ import ListItemIcon from '@mui/material/ListItemIcon';
88
import ListItemText from '@mui/material/ListItemText';
99
import Divider from '@mui/material/Divider';
1010
import Slider from '@mui/material/Slider';
11+
import Checkbox from '@mui/material/Checkbox';
1112
import InboxIcon from '@mui/icons-material/Inbox';
1213
import DraftsIcon from '@mui/icons-material/Drafts';
1314

15+
interface namedProps {
16+
name: string;
17+
}
18+
1419
function valuetext(value: number) {
1520
return `${value}°C`;
1621
}
@@ -23,6 +28,14 @@ export const NamedSDKComponent = () => {
2328
);
2429
};
2530

31+
export const PluginSDKComponent = (props: namedProps = { name: 'named' }) => {
32+
return (
33+
<Box sx={{ width: 300 }}>
34+
<Checkbox aria-label="Checked" id={props.name} defaultChecked />
35+
</Box>
36+
);
37+
};
38+
2639
const SDKComponent = () => {
2740
return (
2841
<Box sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>

federation-cdn-mock/webpack.config.js

+26-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const { resolve } = require('path');
22
const { ModuleFederationPlugin, ContainerPlugin } = require('@module-federation/enhanced');
33
const { DynamicRemotePlugin } = require('@openshift/dynamic-plugin-sdk-webpack');
44

5-
console.log("Entry tests:", resolve(__dirname, './src/modules/moduleOne.tsx'))
5+
console.log('Entry tests:', resolve(__dirname, './src/modules/moduleOne.tsx'));
66

77
const sharedModules = {
88
react: {
@@ -25,7 +25,7 @@ const sharedModules = {
2525
},
2626
};
2727

28-
const TestSDKPLugin = new DynamicRemotePlugin({
28+
const TestSDKPlugin = new DynamicRemotePlugin({
2929
extensions: [],
3030
sharedModules,
3131
entryScriptFilename: 'sdk-plugin.[contenthash].js',
@@ -34,7 +34,7 @@ const TestSDKPLugin = new DynamicRemotePlugin({
3434
pluginOverride: {
3535
ModuleFederationPlugin,
3636
ContainerPlugin,
37-
}
37+
},
3838
},
3939
pluginMetadata: {
4040
name: 'sdk-plugin',
@@ -53,18 +53,39 @@ const TestSDKPLugin = new DynamicRemotePlugin({
5353
},
5454
});
5555

56+
const FullManifest = new DynamicRemotePlugin({
57+
extensions: [],
58+
sharedModules,
59+
pluginManifestFilename: 'full-manifest.json',
60+
entryScriptFilename: 'full-manifest.js',
61+
moduleFederationSettings: {
62+
// Use non native webpack plugins
63+
pluginOverride: {
64+
ModuleFederationPlugin,
65+
ContainerPlugin,
66+
},
67+
},
68+
pluginMetadata: {
69+
name: 'full-manifest',
70+
version: '1.0.0',
71+
exposedModules: {
72+
'./SDKComponent': resolve(__dirname, './src/modules/SDKComponent.tsx'),
73+
},
74+
},
75+
});
76+
5677
function init() {
5778
/** @type { import("webpack").Configuration } */
5879
const config = {
5980
entry: {
6081
mock: resolve(__dirname, './src/index.tsx'),
6182
},
62-
cache: { type: 'filesystem', cacheDirectory: resolve(__dirname, '.cdn-cache')},
83+
cache: { type: 'filesystem', cacheDirectory: resolve(__dirname, '.cdn-cache') },
6384
output: {
6485
publicPath: 'auto',
6586
},
6687
mode: 'development',
67-
plugins: [TestSDKPLugin],
88+
plugins: [TestSDKPlugin, FullManifest],
6889
module: {
6990
rules: [
7091
{

0 commit comments

Comments
 (0)