@@ -36,7 +36,7 @@ const extractCssImports = (code: string): string[] => {
3636 * @description Inject CSS files at the top of each generated chunk file for tsdown builds.
3737 * @return {Plugin } A Rolldown plugin to inject CSS imports into library chunks.
3838 */
39- export const libInjectCss = ( ) : Plugin => {
39+ export const injectCssPlugin = ( ) : Plugin => {
4040 // Track CSS imports per module
4141 const cssImportMap = new Map < string , string [ ] > ( ) ;
4242 // Track which modules are included in which chunks
@@ -85,6 +85,14 @@ export const libInjectCss = (): Plugin => {
8585 } ,
8686
8787 generateBundle ( options : NormalizedOutputOptions , bundle : OutputBundle ) {
88+ // Gather all CSS files that have been bundled
89+ const outputCssFiles = new Set < string > ( ) ;
90+ for ( const file of Object . keys ( bundle ) ) {
91+ if ( file . endsWith ( '.css' ) ) {
92+ outputCssFiles . add ( file ) ;
93+ }
94+ }
95+
8896 // Build a map of chunk -> CSS files
8997 const chunkCssMap = new Map < string , Set < string > > ( ) ;
9098
@@ -98,7 +106,13 @@ export const libInjectCss = (): Plugin => {
98106
99107 const chunkCss = chunkCssMap . get ( chunkName ) ! ;
100108 for ( const cssImport of cssImports ) {
101- chunkCss . add ( cssImport ) ;
109+ // Normalize CSS import path to match the output file name
110+ const normalizedPath = cssImport . replace ( / ^ \. \/ / , '' ) ;
111+
112+ // Only add CSS files have been bundled
113+ if ( outputCssFiles . has ( normalizedPath ) ) {
114+ chunkCss . add ( normalizedPath ) ;
115+ }
102116 }
103117 }
104118 }
@@ -165,7 +179,118 @@ export const libInjectCss = (): Plugin => {
165179 outputChunk . code = code ;
166180 }
167181 }
182+
183+ // generateBundle(options: NormalizedOutputOptions, bundle: OutputBundle) {
184+ // // First, get all CSS files that actually exist in the output bundle
185+ // const outputCssFiles = new Set<string>();
186+ // for (const file of Object.keys(bundle)) {
187+ // if (file.endsWith('.css')) {
188+ // outputCssFiles.add(file);
189+ // }
190+ // }
191+ //
192+ // console.log('BOSH: CSS files in output bundle:', Array.from(outputCssFiles));
193+ //
194+ // // Build a map of chunk -> CSS files
195+ // const chunkCssMap = new Map<string, Set<string>>();
196+ //
197+ // for (const [moduleId, cssImports] of cssImportMap.entries()) {
198+ // const chunkName = moduleToChunkMap.get(moduleId);
199+ //
200+ // if (chunkName) {
201+ // if (!chunkCssMap.has(chunkName)) {
202+ // chunkCssMap.set(chunkName, new Set());
203+ // }
204+ //
205+ // const chunkCss = chunkCssMap.get(chunkName)!;
206+ // for (const cssImport of cssImports) {
207+ // // Normalize the CSS import path to match output file names
208+ // const normalizedPath = cssImport.replace(/^\.\//, '');
209+ //
210+ // // Only add CSS files that actually exist in the output bundle
211+ // if (outputCssFiles.has(normalizedPath)) {
212+ // chunkCss.add(normalizedPath);
213+ // console.log(`BOSH: Adding CSS ${normalizedPath} to chunk ${chunkName}`);
214+ // } else {
215+ // console.log(
216+ // `BOSH: Skipping CSS ${normalizedPath} (not in output bundle, likely bundled into another CSS file)`
217+ // );
218+ // }
219+ // }
220+ // }
221+ // }
222+ //
223+ // console.log('BOSH: Chunk CSS Map:', Array.from(chunkCssMap.entries()));
224+ //
225+ // // Inject CSS imports into chunks
226+ // for (const chunk of Object.values(bundle)) {
227+ // if (chunk.type !== 'chunk') {
228+ // continue;
229+ // }
230+ //
231+ // const outputChunk = chunk as OutputChunk;
232+ //
233+ // // Skip non-JavaScript files (like .d.ts files)
234+ // if (
235+ // !outputChunk.fileName.endsWith('.js') &&
236+ // !outputChunk.fileName.endsWith('.mjs') &&
237+ // !outputChunk.fileName.endsWith('.cjs')
238+ // ) {
239+ // continue;
240+ // }
241+ //
242+ // const cssFiles = chunkCssMap.get(outputChunk.fileName);
243+ //
244+ // if (!cssFiles || cssFiles.size === 0) {
245+ // console.log(`BOSH: No CSS imports for ${outputChunk.fileName}`);
246+ // continue;
247+ // }
248+ //
249+ // console.log(`BOSH: Injecting ${cssFiles.size} CSS imports into ${outputChunk.fileName}`);
250+ //
251+ // // Find the position to inject CSS imports
252+ // const node = parse<JavaScriptTypes>(Lang.JavaScript, outputChunk.code)
253+ // .root()
254+ // .children()
255+ // .find((node) => !excludeTokens.includes(node.kind()));
256+ //
257+ // const position = node?.range().start.index ?? 0;
258+ //
259+ // // Inject CSS imports at the top of the chunk
260+ // let code = outputChunk.code;
261+ // const injections: string[] = [];
262+ //
263+ // for (const cssFileName of cssFiles) {
264+ // // Resolve the CSS file path relative to the chunk
265+ // let cssFilePath = cssFileName;
266+ //
267+ // // If it's a relative import, keep it relative
268+ // if (cssFilePath.startsWith('./') || cssFilePath.startsWith('../')) {
269+ // // Already relative, use as-is
270+ // } else {
271+ // // Make it relative
272+ // cssFilePath = `./${cssFilePath}`;
273+ // }
274+ //
275+ // const injection = options.format === 'es' ? `import '${cssFilePath}';` : `require('${cssFilePath}');`;
276+ //
277+ // injections.push(injection);
278+ // }
279+ //
280+ // if (injections.length > 0) {
281+ // code = code.slice(0, position) + injections.join('\n') + '\n' + code.slice(position);
282+ // }
283+ //
284+ // // Update code and sourcemap
285+ // outputChunk.code = code;
286+ //
287+ // if (sourcemap && options.sourcemap) {
288+ // const ms = new MagicString(code);
289+ // outputChunk.map = ms.generateMap({ hires: 'boundary' }) as any;
290+ // }
291+ //
292+ // console.log(`BOSH: Successfully injected CSS into ${outputChunk.fileName}`);
293+ // }
294+ // }
168295 } ;
169296} ;
170-
171- export default libInjectCss ;
0 commit comments