Skip to content

Commit f432619

Browse files
authored
feat: support component data fetch in ssr mode (#3753)
1 parent f777710 commit f432619

File tree

112 files changed

+4797
-515
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+4797
-515
lines changed

.changeset/rich-bees-applaud.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/manifest': patch
3+
---
4+
5+
fix(manifest): record all exposes even if the expose value is the same file

.changeset/spotty-trains-stare.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/modern-js': minor
3+
---
4+
5+
feat(modern-js-plugin): support component-level data fetch

apps/manifest-demo/webpack-host/runtimePlugin.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ export default function (): FederationRuntimePlugin {
44
return {
55
name: 'custom-plugin-build',
66
beforeInit(args) {
7+
const { userOptions, origin } = args;
8+
if (origin.options.name && origin.options.name !== userOptions.name) {
9+
userOptions.name = origin.options.name;
10+
}
711
console.log('[build time inject] beforeInit: ', args);
812
return args;
913
},
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# modern-component-data-fetch
2+
3+
## Running Demo
4+
5+
- host: [localhost:5001](http://localhost:5001/)
6+
- provider: [localhost:5002](http://localhost:5002/)
7+
- provider-csr: [localhost:5003](http://localhost:5003/)
8+
9+
## How to start the demos ?
10+
11+
```bash
12+
# Root directory
13+
pnpm i
14+
15+
nx build modern-js-plugin
16+
17+
pnpm run app:component-data-fetch:dev
18+
19+
open http://localhost:5001/
20+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
strict-peer-dependencies=false
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# modernjs-ssr-nested-remote
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
2+
import { defineConfig } from 'cypress';
3+
4+
export default defineConfig({
5+
projectId: 'sa6wfn',
6+
e2e: nxE2EPreset(__filename, { cypressDir: 'cypress' }),
7+
defaultCommandTimeout: 20000,
8+
retries: {
9+
runMode: 2,
10+
openMode: 1,
11+
},
12+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { getH2 } from '../support/app.po';
2+
3+
describe('csr with fetch data', () => {
4+
it('[ /csr ] - should render in client side and fetch data from server', () => {
5+
cy.visit('/csr');
6+
cy.wait(3000);
7+
cy.url().should('include', '/csr');
8+
getH2().contains('[ csr provider - server ] fetched data');
9+
10+
const stub = cy.stub();
11+
cy.on('window:alert', stub);
12+
13+
cy.get('#provider-csr-btn')
14+
.should('be.visible')
15+
.click()
16+
.then(() => {
17+
expect(stub.getCall(0)).to.be.calledWith(
18+
'[provider-csr-btn] Client side Javascript works!',
19+
);
20+
});
21+
22+
// it only render in client side, so it not have downgrade identifier
23+
cy.window().then((win) => {
24+
expect(win.globalThis._mfSSRDowngrade).to.not.exist;
25+
});
26+
});
27+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { getH1, getH2, getH3 } from '../support/app.po';
2+
3+
declare global {
4+
interface Window {
5+
globalThis: {
6+
_mfSSRDowngrade?: boolean | string[];
7+
};
8+
}
9+
}
10+
11+
describe('downgrade', () => {
12+
beforeEach(() => {
13+
// the page will hydrate failed and downgrade, so catch the error, keep on testing
14+
cy.on('uncaught:exception', (err, runnable) => {
15+
return false;
16+
});
17+
});
18+
19+
it('[ /client-downgrade ] - should downgrade load data.client.js to fetch data', () => {
20+
cy.visit('/client-downgrade');
21+
cy.wait(3000);
22+
cy.url().should('include', '/client-downgrade');
23+
getH2().contains('fetch data from provider client');
24+
25+
const stub = cy.stub();
26+
cy.on('window:alert', stub);
27+
28+
cy.get('#client-downgrade-btn')
29+
.should('be.visible')
30+
.click()
31+
.then(() => {
32+
expect(stub.getCall(0)).to.be.calledWith(
33+
'[client-downgrade] Client side Javascript works!',
34+
);
35+
});
36+
cy.window().then((win) => {
37+
expect(win.globalThis._mfSSRDowngrade).to.exist;
38+
});
39+
});
40+
41+
it('[ /server-downgrade ] - should downgrade and fetch data from server', () => {
42+
cy.visit('/server-downgrade');
43+
cy.wait(3000);
44+
cy.url().should('include', '/server-downgrade');
45+
getH2().contains('[ provider - server - ServerDowngrade]');
46+
47+
const stub = cy.stub();
48+
cy.on('window:alert', stub);
49+
50+
cy.get('#server-downgrade-btn')
51+
.should('be.visible')
52+
.click()
53+
.then(() => {
54+
expect(stub.getCall(0)).to.be.calledWith(
55+
'[server-downgrade] Client side Javascript works!',
56+
);
57+
});
58+
cy.window().then((win) => {
59+
console.log(win);
60+
expect(win.globalThis._mfSSRDowngrade).to.exist;
61+
});
62+
});
63+
});
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { getH1, getH2, getH3 } from '../support/app.po';
2+
3+
declare global {
4+
interface Window {
5+
globalThis: {
6+
_mfSSRDowngrade?: boolean | string[];
7+
};
8+
}
9+
}
10+
11+
describe('/', () => {
12+
beforeEach(() => cy.visit('/'));
13+
14+
describe('Welcome message', () => {
15+
it('should display welcome message', () => {
16+
getH1().contains('Welcome message from host');
17+
});
18+
});
19+
20+
// check that clicking back and forwards in client side routeing still renders the content correctly
21+
describe('Routing checks', () => {
22+
it('[ /basic ] - should render in client side and fetch data from server side', () => {
23+
// wait nav hydration
24+
cy.wait(3000);
25+
cy.get('.basic').parent().click();
26+
cy.url().should('include', '/basic');
27+
getH2().contains('[ provider - client ] fetched data');
28+
29+
const stub = cy.stub();
30+
cy.on('window:alert', stub);
31+
32+
cy.get('#provider-btn')
33+
.should('be.visible')
34+
.click()
35+
.then(() => {
36+
expect(stub.getCall(0)).to.be.calledWith(
37+
'[provider] Client side Javascript works!',
38+
);
39+
});
40+
41+
cy.window().then((win) => {
42+
expect(win.globalThis._mfSSRDowngrade).to.not.exist;
43+
});
44+
});
45+
46+
it('[ /client-downgrade ] - should render in client side and load data.client.js to fetch data', () => {
47+
cy.wait(3000);
48+
cy.get('.client-downgrade').parent().click();
49+
cy.url().should('include', '/client-downgrade');
50+
getH2().contains('fetch data from provider client');
51+
52+
const stub = cy.stub();
53+
cy.on('window:alert', stub);
54+
55+
cy.get('#client-downgrade-btn')
56+
.should('be.visible')
57+
.click()
58+
.then(() => {
59+
expect(stub.getCall(0)).to.be.calledWith(
60+
'[client-downgrade] Client side Javascript works!',
61+
);
62+
});
63+
cy.window().then((win) => {
64+
expect(win.globalThis._mfSSRDowngrade).to.not.exist;
65+
});
66+
});
67+
});
68+
});

0 commit comments

Comments
 (0)