wxt-dev / wxt-dev/wxt

[WXT Modules] Automatically add build and runtime options without manual module augmentation

Open
#1,629 5 comments 0 reactions 1 assignee View on GitHub

@aklinker1 is already working on this.

Since Apr 28, 2025.

Dominant language
TypeScript
Stars
10.5k
Forks
564
PR merge metrics
No merged PRs in 30d

Description

I attempted to set this up, but ran into an error as soon as I tried building a WXT module that adds types to the WXT config.

$ pnpm tsdown
ℹ tsdown v0.10.0 powered by rolldown v1.0.0-beta.8-commit.151352b                               tsdown 6:04:57 PM
[tsdown 6:04:57 PM] ℹ Using tsdown config: /Users/aklinker1/Development/github.com/wxt-dev/wxt/packages/analytics/tsdown.config.ts
[tsdown 6:04:57 PM] ℹ entry: modules/analytics/index.ts, modules/analytics/client.ts, modules/analytics/background-plugin.ts, modules/analytics/types.ts, modules/analytics/providers/google-analytics-4.ts, modules/analytics/providers/umami.ts
ℹ Using tsconfig: tsconfig.json                                                                 tsdown 6:04:57 PM
ℹ [ESM] Build start                                                                             tsdown 6:04:57 PM

 FATAL  Build failed with 2 errors:                                                              tsdown 6:04:58 PM

[UNRESOLVED_IMPORT] Error: Could not resolve '../pkg' in ../../node_modules/.pnpm/lightningcss@1.29.3/node_modules/lightningcss/node/index.js
    ╭─[ ../../node_modules/.pnpm/lightningcss@1.29.3/node_modules/lightningcss/node/index.js:17:28 ]
    │
 17 │   module.exports = require(../pkg);
    │                            ────┬───
    │                                ╰───── Module not found.
────╯

[UNLOADABLE_DEPENDENCY] Error: Could not load ../../node_modules/.pnpm/fsevents@2.3.3/node_modules/fsevents/fsevents.node
    ╭─[ ../../node_modules/.pnpm/fsevents@2.3.3/node_modules/fsevents/fsevents.js:13:24 ]
    │
 13 │ const Native = require("./fsevents.node");
    │                        ────────┬────────
    │                                ╰────────── stream did not contain valid UTF-8
────╯


    at normalizeErrors (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/rolldown@1.0.0-beta.8-commit.151352b_typescript@5.8.3/node_modules/rolldown/dist/shared/src-DvIQg0VF.mjs:935:18)
    at handleOutputErrors (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/rolldown@1.0.0-beta.8-commit.151352b_typescript@5.8.3/node_modules/rolldown/dist/shared/src-DvIQg0VF.mjs:1758:34)
    at transformToRollupOutput (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/rolldown@1.0.0-beta.8-commit.151352b_typescript@5.8.3/node_modules/rolldown/dist/shared/src-DvIQg0VF.mjs:1752:2)
    at RolldownBuild.write (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/rolldown@1.0.0-beta.8-commit.151352b_typescript@5.8.3/node_modules/rolldown/dist/shared/src-DvIQg0VF.mjs:4168:11)
    at async build (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/rolldown@1.0.0-beta.8-commit.151352b_typescript@5.8.3/node_modules/rolldown/dist/shared/src-DvIQg0VF.mjs:4210:22)
    at async /Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/index.js:536:5
    at async Promise.all (index 0)
    at async rebuild (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/index.js:527:3)
    at async buildSingle (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/index.js:519:2)
    at async Promise.all (index 0)
    at async build (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/index.js:491:19)
    at async CAC.<anonymous> (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/run.js:19:2)
    at async runCLI (/Users/aklinker1/Development/github.com/wxt-dev/wxt/node_modules/.pnpm/tsdown@0.10.0_publint@0.3.10_typescript@5.8.3/node_modules/tsdown/dist/run.js:37:3)

This is caused by the weird circular dependency between WXT and the module agumentation :/

The solution is simple: don't do module augmentation. instead, when a config key is listed in the module options, WXT should generate the module augmentation instead of requiring the module author to include it in the module code.

import { defineWxtModule } from 'wxt/modules';
- import 'wxt';

- export interface MyModuleOptions {
+ export interface ModuleOptions {
  // Add your build-time options here...
}
- declare module 'wxt' {
-   export interface InlineConfig {
-     // Add types for the "myModule" key in wxt.config.ts
-     myModule: MyModuleOptions;
-   }
- }

export default defineWxtModule<AnalyticModuleOptions>({
  configKey: 'myModule',

  // Build time config is available via the second argument of setup
  setup(wxt, options) {
    console.log(options);
  },
});

Then in the project's .wxt directory, we generate something like the following:

// .wxt/module-build-options.d.ts
import 'wxt';

declare module 'wxt' {
  export interface InlineConfig {
    myModule: import("my-module").ModuleOptions
  }
}

Good news, this shouldn't be a breaking change! Regardless of if we migrate to tsdown, this is something that should be done.

Originally posted by @aklinker1 in #1628

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.