Skip to content

fix: deduplicate content script CSS in build output#2268

Open
oc-wonton wants to merge 1 commit intowxt-dev:mainfrom
oc-wonton:fix/content-script-css-dedup-1987
Open

fix: deduplicate content script CSS in build output#2268
oc-wonton wants to merge 1 commit intowxt-dev:mainfrom
oc-wonton:fix/content-script-css-dedup-1987

Conversation

@oc-wonton
Copy link
Copy Markdown

Description

When content scripts import CSS files, Vite outputs the CSS in two locations:

  1. content-scripts/{name}.css (referenced in manifest)
  2. assets/{name}.css (duplicate, not needed)

This adds a post-build deduplication step that removes identical CSS files from assets/ when they already exist in content-scripts/ with the same base name and content.

Related Issues

Fixes #1987

Type of Change

  • Bug fix

Implementation

  • New deduplicateCss() utility in packages/wxt/src/core/utils/building/deduplicate-css.ts
  • Called after entrypoint builds merge but before manifest generation (in rebuild.ts)
  • Conservative matching: only removes files with same base name AND identical content
  • Preserves legitimate CSS files in assets/ (e.g., unlisted-style entrypoints)

Testing

  • 8 unit tests covering: duplicate removal, different content preservation, different name preservation, multiple files, empty cases, missing files, multi-step builds
  • 1 e2e test verifying CSS only appears in content-scripts/ and not duplicated in assets/
✓ src/core/utils/building/__tests__/deduplicate-css.test.ts (8 tests) 71ms
  Test Files  1 passed (1)
       Tests  8 passed (8)

Additional Notes

Based on maintainer guidance in #1987: each content script is built in a separate Vite build, causing CSS to appear in both locations. This fix deduplicates at the output level rather than changing the build pipeline.

When content scripts import CSS files, Vite outputs the CSS in two locations:
1. content-scripts/{name}.css (referenced in manifest)
2. assets/{name}.css (duplicate, not needed)

This change adds a post-build deduplication step that removes identical
CSS files from assets/ when they already exist in content-scripts/ with
the same base name and content. This reduces extension package size by
eliminating unnecessary duplicate files.

The deduplication logic:
- Only compares files with matching base names (e.g., both named "content.css")
- Verifies content is identical before removing
- Preserves legitimate CSS files in assets/ (unlisted-style entrypoints)
- Only removes true duplicates created by Vite's build process

Fixes wxt-dev#1987

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@oc-wonton oc-wonton requested a review from aklinker1 as a code owner April 15, 2026 14:32
@github-actions github-actions bot added the pkg/wxt Includes changes to the `packages/wxt` directory label Apr 15, 2026
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 15, 2026

Deploy Preview for creative-fairy-df92c4 ready!

Name Link
🔨 Latest commit bacf0a9
🔍 Latest deploy log https://app.netlify.com/projects/creative-fairy-df92c4/deploys/69dfa191f2ed15000895251e
😎 Deploy Preview https://deploy-preview-2268--creative-fairy-df92c4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@oyzamil
Copy link
Copy Markdown
Contributor

oyzamil commented Apr 16, 2026

@oc-wonton When using tailwindcss in content-script and other pages like popup, options etc.

The CSS file is created 2 times. Will this pull also fix it or not?

See the 2 files. I am also curious why the CSS file is named as my component name, Button-id.css; it should be styles.css

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg/wxt Includes changes to the `packages/wxt` directory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Content Script CSS is added twice to build output

2 participants