Skip to content

Commit bca6396

Browse files
committed
test(integration): add basic remote build tests as poc
1 parent 7ca5697 commit bca6396

File tree

7 files changed

+158
-1
lines changed

7 files changed

+158
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Integration Test
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
permissions:
9+
pull-requests: read
10+
11+
jobs:
12+
integration-test:
13+
name: Integration (vite ${{ matrix.vite-version }})
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
# This plugin does not yet correctly support version above 7.1.7
19+
vite-version: ['5', '6', '7.1.7']
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v5
23+
24+
- name: PNPM Install
25+
uses: pnpm/action-setup@v4
26+
with:
27+
version: 10.28.2
28+
29+
- name: Setup Node
30+
uses: actions/setup-node@v6
31+
with:
32+
node-version: 24
33+
cache: 'pnpm'
34+
registry-url: https://registry.npmjs.org/
35+
36+
- run: corepack enable
37+
38+
- name: Install NPM Dependencies
39+
run: pnpm install --frozen-lockfile
40+
41+
- name: Override vite version
42+
run: pnpm add -Dw vite@${{ matrix.vite-version }}
43+
44+
- name: Run Integration Tests
45+
run: pnpm test:integration

integration/build.test.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import defu from 'defu';
2+
import { resolve } from 'path';
3+
import { build, Rollup } from 'vite';
4+
import { describe, expect, it } from 'vitest';
5+
import { federation } from '../src/index';
6+
import { findAsset, findChunk, getChunkNames } from './helpers/matchers';
7+
8+
const FIXTURES = resolve(__dirname, 'fixtures');
9+
const BASIC_REMOTE = resolve(FIXTURES, 'basic-remote');
10+
11+
async function buildFixture(optionsOverrides?: Partial<Parameters<typeof federation>[0]>) {
12+
const defaultOptions = {
13+
name: 'basicRemote',
14+
filename: 'remoteEntry.js',
15+
exposes: {
16+
'./exposed': resolve(BASIC_REMOTE, 'exposed-module.js'),
17+
},
18+
shared: {},
19+
dts: false,
20+
} satisfies Parameters<typeof federation>[0];
21+
22+
const mfOptions = defu(defaultOptions, optionsOverrides);
23+
24+
const result = await build({
25+
root: BASIC_REMOTE,
26+
logLevel: 'silent',
27+
plugins: [federation(mfOptions)],
28+
build: {
29+
write: false,
30+
target: 'chrome89',
31+
},
32+
});
33+
34+
// Vite returns RollupOutput[] only with multiple rollupOptions.output entries.
35+
// Our test configs should never produce that — fail fast if they do.
36+
expect(Array.isArray(result), 'E xpected a single RollupOutput, not an array').toBe(false);
37+
return result as Rollup.RollupOutput;
38+
}
39+
40+
describe('build', () => {
41+
describe('remote', () => {
42+
it('produces a remoteEntry chunk', async () => {
43+
const output = await buildFixture();
44+
const chunks = getChunkNames(output);
45+
expect(chunks.some((name) => name.includes('remoteEntry'))).toBe(true);
46+
});
47+
48+
it('remoteEntry contains federation runtime init with correct name', async () => {
49+
const output = await buildFixture();
50+
const remoteEntry = findChunk(output, 'remoteEntry');
51+
expect(remoteEntry).toBeDefined();
52+
expect(remoteEntry!.code).toContain('basicRemote');
53+
expect(remoteEntry!.code).toContain('moduleCache');
54+
});
55+
56+
it('exposed module content is included in output', async () => {
57+
const output = await buildFixture();
58+
const allCode = output.output
59+
.filter((o): o is Rollup.OutputChunk => o.type === 'chunk')
60+
.map((c) => c.code)
61+
.join('\n');
62+
63+
expect(allCode).toContain('Hello');
64+
});
65+
66+
it('generates mf-manifest.json when manifest is enabled', async () => {
67+
const manifestOutput = await buildFixture({
68+
manifest: true,
69+
});
70+
71+
const manifest = findAsset(manifestOutput, 'mf-manifest.json');
72+
expect(manifest).toBeDefined();
73+
74+
const parsed = JSON.parse(manifest!.source as string);
75+
expect(parsed).toHaveProperty('exposes');
76+
});
77+
});
78+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Minimal app entry — just needs to exist for vite to build
2+
console.log('hello world');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function greet(name) {
2+
return `Hello, ${name}!`;
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
<div id="app"></div>
5+
<script type="module" src="./entry.js"></script>
6+
</body>
7+
</html>

integration/helpers/matchers.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { Rollup } from 'vite';
2+
3+
export function getChunkNames(output: Rollup.RollupOutput) {
4+
return output.output
5+
.filter((o): o is Rollup.OutputChunk => o.type === 'chunk')
6+
.map((c) => c.fileName);
7+
}
8+
9+
export function findChunk(output: Rollup.RollupOutput, test: string | RegExp) {
10+
return output.output.find(
11+
(o): o is Rollup.OutputChunk =>
12+
o.type === 'chunk' &&
13+
(typeof test === 'string' ? o.fileName.includes(test) : test.test(o.fileName))
14+
);
15+
}
16+
17+
export function findAsset(output: Rollup.RollupOutput, test: string) {
18+
return output.output.find(
19+
(o): o is Rollup.OutputAsset => o.type === 'asset' && o.fileName.includes(test)
20+
);
21+
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"dev-nv": "pnpm -filter 'examples-nuxt-vite-host' -filter 'examples-vite-vite-remote' run dev",
3333
"preview-vv": "pnpm -filter 'examples-vite-vite*' run preview",
3434
"multi-example": "pnpm --filter \"multi-example-*\" --parallel run start",
35-
"test": "vitest",
35+
"test": "vitest run src",
36+
"test:integration": "vitest run integration",
3637
"e2e": "playwright test",
3738
"changeset": "changeset",
3839
"changeset:status": "changeset status"

0 commit comments

Comments
 (0)