Skip to content

Migrate build system from Webpack to WXT#22

Open
skid-dev wants to merge 1 commit into
mainfrom
claude/recursing-goldberg-5b5636
Open

Migrate build system from Webpack to WXT#22
skid-dev wants to merge 1 commit into
mainfrom
claude/recursing-goldberg-5b5636

Conversation

@skid-dev
Copy link
Copy Markdown
Owner

Summary

  • Replace Webpack 5 + hand-authored src/manifest.json with WXT: manifest is now generated from wxt.config.ts + entrypoint discovery in src/entrypoints/.
  • Background, popup, and all 9 dynamically-injected content scripts are now WXT entrypoints. Output paths are preserved (background.js, popup.html, launcher_homepage.js, etc.) so existing chrome.scripting.executeScript({ files: [...] }) and insertCSS call sites in src/background/events/injects/** keep working without changes.
  • CSS assets moved into public/ for verbatim copy at the same root paths.
  • Build output moved from dist/.output/chrome-mv3/. bun run zip produces a Web-Store-ready zip at .output/<name>-<version>-chrome.zip.

The migration is intentionally minimal — chrome.* globals are left in place (WXT runs them as-is), src/storage/ is unchanged, and React isn't pulled into the popup. All of those can be follow-ups.

What changed

Area Before After
Build system webpack.config.cjs (5+ loaders, 8 deps) wxt.config.ts (~25 lines)
Manifest static src/manifest.json generated from wxt.config.ts + entrypoints
Background top-level chrome.*.addListener(...) calls inside defineBackground(() => { ... })
Content scripts bundled by Webpack, copied to dist/ defineUnlistedScript(() => { ... }) in src/entrypoints/*.ts
CSS CopyWebpackPlugin patterns public/**/*.css
Dev workflow bun run dev → Webpack watch bun run dev → Vite + HMR + auto-launched browser
Firefox not supported bun run build:firefox works for free

Code review cleanups (from /simplify)

  • Extract show_detection_banner() helper used by detect_domain and detect_rss_feed (kills ~22 lines of duplicate banner code per file).
  • Switch detect_domain / detect_rss_feed to use set_setting() instead of inlining chrome.storage.sync.get → mutate → set.
  • Split set_setting() into its own file so content-script entrypoints don't transitively pull in poll_feed / fast-xml-parser. This saves ~63 kB per detect_* bundle (detect_schooltape.js: 64.74 kB → 1.37 kB).
  • Collapse mirrored addedNodes/removedNodes branches in detect_schooltape.ts into a handle_stylesheet_change() helper.
  • Trim verbose web_accessible_resources list to glob patterns.
  • Drop redundant compile npm script.
  • Remove duplicated "Load unpacked" steps in README.

Total bundle size went from 548 kB (post-naive-migration) to 485 kB after the cleanup — actually smaller than what Webpack was producing, because the set_setting split also fixes a pre-existing transitive-import bloat in detect_schooltape.js.

Test plan

  • bun run typecheck passes
  • bun run build produces all 11 expected JS entries + 9 CSS files + popup.html + manifest.json
  • bun run zip produces .output/schoolbox-chrome-extension-1.3.0-chrome.zip
  • Manual: load .output/chrome-mv3/ as unpacked extension in Chrome
  • Manual: verify popup opens from toolbar icon
  • Manual: verify Ctrl+K launcher works on LMS homepage
  • Manual: verify news-search autocomplete still works
  • Manual: verify post-history diffs render on edited posts
  • Manual: verify SchoolTape detection toggles schooltape_compatibility when SchoolTape installs/removes its stylesheet

The migration plan and full WXT reference are saved in ~/.claude/plans/pure-bouncing-cat.md.

🤖 Generated with Claude Code

Replace webpack.config.cjs + hand-authored src/manifest.json with WXT's
convention-based entrypoint discovery and wxt.config.ts:

- Move src/background/background.ts -> src/entrypoints/background.ts
  (wrapped in defineBackground; listener registrations moved into main())
- Move src/popup/* -> src/entrypoints/popup/index.html + popup.ts + styles.css
- Move 9 dynamically-injected content scripts under src/entrypoints/*.ts
  (wrapped in defineUnlistedScript; output paths preserved so existing
  chrome.scripting.executeScript({ files: [...] }) calls still resolve)
- Move all injected CSS into public/ for verbatim copy at the same paths
- Delete webpack.config.cjs and src/manifest.json
- Replace dist/ build target with .output/chrome-mv3/
- Update tsconfig.json to extend ./.wxt/tsconfig.json
- Update .releaserc.json to build via 'bun run zip' and copy the artifact
- Update README with WXT-flavoured development instructions

Side-effect cleanups surfaced by the code review:
- Extract show_detection_banner() helper, consume from detect_domain and
  detect_rss_feed (kills ~22 lines of duplicate banner code per file)
- Use set_setting() in detect_domain / detect_rss_feed instead of
  inlining chrome.storage.sync.get -> mutate -> set
- Split set_setting into its own file so content-script entrypoints don't
  pull in pull_feed / fast-xml-parser (saves ~63 kB per detect_* bundle)
- Collapse mirrored added/removed branches in detect_schooltape into a
  single handle_stylesheet_change() helper
- Trim verbose w_a_r list to glob patterns
- Drop redundant 'compile' npm script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant