Skip to content

Commit 03e5576

Browse files
authored
feat(css): add bundleAllCSS option to control CSS asset inclusion in exposed modules (#347)
1 parent bc7eaaf commit 03e5576

File tree

5 files changed

+69
-3
lines changed

5 files changed

+69
-3
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ export default defineConfig({
114114
// You can set this to "entry" to inject it into the entry script instead.
115115
// Useful if your application does not load from index.html.
116116
hostInitInjectLocation: "html", // or "entry"
117+
// Controls whether all CSS assets from the bundle should be added to every exposed module.
118+
// When false (default), the plugin will not process any CSS assets.
119+
// When true, all CSS assets are bundled into every exposed module.
120+
bundleAllCSS: false, // or true
117121
}),
118122
],
119123
server: {

src/plugins/pluginMFManifest.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ const Manifest = (): Plugin[] => {
163163
}
164164

165165
// Second pass: Collect all CSS assets
166-
const allCssAssets = collectCssAssets(bundle);
166+
const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : new Set<string>();
167167

168168
const exposesModules = Object.keys(mfOptions.exposes).map(
169169
(item) => mfOptions.exposes[item].import
@@ -200,8 +200,10 @@ const Manifest = (): Plugin[] => {
200200
);
201201
processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
202202

203-
// Add all CSS assets to every export
204-
addCssAssetsToAllExports(filesMap, allCssAssets);
203+
// Add all CSS assets to every export if bundleAllCSS is enabled
204+
if (mfOptions.bundleAllCSS) {
205+
addCssAssetsToAllExports(filesMap, allCssAssets);
206+
}
205207

206208
// Final deduplication of all assets
207209
filesMap = deduplicateAssets(filesMap);

src/utils/__tests__/cssModuleHelpers.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
buildFileToShareKeyMap,
1010
} from '../cssModuleHelpers';
1111
import type { OutputBundleItem, PreloadMap } from '../cssModuleHelpers';
12+
import { normalizeModuleFederationOptions } from '../normalizeModuleFederationOptions';
1213

1314
describe('cssModuleHelpers', () => {
1415
describe('createEmptyAssetMap', () => {
@@ -167,11 +168,54 @@ describe('cssModuleHelpers', () => {
167168
getNormalizeModuleFederationOptions: vi.fn(() => ({
168169
name: 'test-app',
169170
virtualModuleDir: '__mf_virtual_test',
171+
bundleAllCSS: false,
172+
})),
173+
normalizeModuleFederationOptions: vi.fn((options) => ({
174+
name: 'test-app',
175+
virtualModuleDir: '__mf_virtual_test',
176+
bundleAllCSS: options.bundleAllCSS || false,
170177
})),
171178
}));
172179

173180
const result = await buildFileToShareKeyMap(shareKeys, resolveFn);
174181
expect(result.get('path/to/react.js')).toBe('react');
175182
});
176183
});
184+
185+
describe('bundleAllCSS option', () => {
186+
it('should default bundleAllCSS to false when not specified', () => {
187+
const options = normalizeModuleFederationOptions({
188+
name: 'test-app',
189+
exposes: {
190+
'./Button': './src/Button.jsx',
191+
},
192+
});
193+
194+
expect(options.bundleAllCSS).toBe(false);
195+
});
196+
197+
it('should set bundleAllCSS to false when explicitly set to false', () => {
198+
const options = normalizeModuleFederationOptions({
199+
name: 'test-app',
200+
exposes: {
201+
'./Button': './src/Button.jsx',
202+
},
203+
bundleAllCSS: false,
204+
});
205+
206+
expect(options.bundleAllCSS).toBe(false);
207+
});
208+
209+
it('should set bundleAllCSS to true when explicitly set to true', () => {
210+
const options = normalizeModuleFederationOptions({
211+
name: 'test-app',
212+
exposes: {
213+
'./Button': './src/Button.jsx',
214+
},
215+
bundleAllCSS: true,
216+
});
217+
218+
expect(options.bundleAllCSS).toBe(true);
219+
});
220+
});
177221
});

src/utils/__tests__/normalizeModuleFederationOption.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ describe('normalizeModuleFederationOption', () => {
2828
ignoreOrigin: false,
2929
virtualModuleDir: '__mf__virtual',
3030
hostInitInjectLocation: 'html',
31+
bundleAllCSS: false,
32+
getPublicPath: undefined,
33+
publicPath: undefined,
3134
});
3235
});
3336

src/utils/normalizeModuleFederationOptions.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ export type ModuleFederationOptions = {
286286
* Defaults to Vite's base config or "auto" if base is empty
287287
*/
288288
publicPath?: string;
289+
/**
290+
* Controls whether all CSS assets from the bundle should be added to every exposed module.
291+
* When false (default), the plugin will not process any CSS assets.
292+
* When true, all CSS assets are bundled into every exposed module.
293+
*/
294+
bundleAllCSS?: boolean;
289295
shared?:
290296
| string[]
291297
| Record<
@@ -335,6 +341,12 @@ export interface NormalizedModuleFederationOptions {
335341
ignoreOrigin?: boolean;
336342
virtualModuleDir: string;
337343
hostInitInjectLocation: HostInitInjectLocationOptions;
344+
/**
345+
* Controls whether all CSS assets from the bundle should be added to every exposed module.
346+
* When false (default), the plugin will not process any CSS assets.
347+
* When true, all CSS assets are bundled into every exposed module.
348+
*/
349+
bundleAllCSS: boolean;
338350
}
339351

340352
type HostInitInjectLocationOptions = 'entry' | 'html';
@@ -426,5 +438,6 @@ export function normalizeModuleFederationOptions(
426438
ignoreOrigin: options.ignoreOrigin || false,
427439
virtualModuleDir: options.virtualModuleDir || '__mf__virtual',
428440
hostInitInjectLocation: options.hostInitInjectLocation || 'html',
441+
bundleAllCSS: options.bundleAllCSS || false,
429442
});
430443
}

0 commit comments

Comments
 (0)