wxt icon indicating copy to clipboard operation
wxt copied to clipboard

Clarify code outside of `defineBackground` as related error

Open avi12 opened this issue 10 months ago • 15 comments

Feature Request

Suppose I have

// code
export default defineBackground(() => {
  // code
});

it will throw an error that doesn't clarify that I must not have code outside of defineBackground

Is your feature request related to a bug?

Not related to a particular bug, though this issue could be classified as a bug

What are the alternatives?

Knowledge of the situation according to the documentation, nothing else

Additional context

Having this issue clarified will benefit both WXT devs who are new to the framework and devs like me, who explore using an agentic AI to code the extension (e.g. OpenHands) Such an agent can often use errors to modify the code so that the error disappears

avi12 avatar Apr 10 '25 14:04 avi12

@avi12 Can you show me an example I'm not able to reproduce it.

Is it something like this? Cause this is working just fine.

const foo = () => {
  console.log(browser.runtime.getURL("/"));
};

export default defineBackground(() => {
  console.log("Hello background!", { id: browser.runtime.id });
  console.log(foo());
});

nishu-murmu avatar Apr 22 '25 10:04 nishu-murmu

Try

const foo = "bar";

export default defineBackground(() => {
  console.log(foo);
});

avi12 avatar Apr 22 '25 11:04 avi12

Try

const foo = "bar";

export default defineBackground(() => { console.log(foo); });

@avi12 I checked for this code as well. It is working for me.

Image

nishu-murmu avatar Apr 23 '25 08:04 nishu-murmu

@nishu-murmu According to that logic, this code should be perfectly valid:

console.log("background");

export default defineBackground(() => {});

avi12 avatar Apr 23 '25 10:04 avi12

Suppose I want to do

browser.runtime.onMessage.addListener(() => {});

export default defineBackground(() => {});

the WXT compiler will yell at me

avi12 avatar Apr 23 '25 10:04 avi12

Suppose I want to do

browser.runtime.onMessage.addListener(() => {});

export default defineBackground(() => {}); the WXT compiler will yell at me

I ran every command, from pnpm compile, pnpm build, pnpm postinstall I'm not seeing any errors.

And listeners are also working just fine.

Image

nishu-murmu avatar Apr 23 '25 11:04 nishu-murmu

@nishu-murmu According to that logic, this code should be perfectly valid:

console.log("background");

export default defineBackground(() => {});

Yeah, this is perfectly valid.

nishu-murmu avatar Apr 23 '25 11:04 nishu-murmu

This one failed https://github.com/avi12/auto-detect-new-youtube-videos/blob/background-script-fails/src/entrypoints/background.ts

avi12 avatar Apr 23 '25 12:04 avi12

Can you try separating the code in different files and importing them in the root file. Create background folder entrypoint. Something like this?

Image

nishu-murmu avatar Apr 23 '25 12:04 nishu-murmu

To be fair, the project I linked is a puppet project that I let AI code it But in general, it's good advice to code split Besides that, I'd assume that the branch I linked failed to compile, am I right?

avi12 avatar Apr 23 '25 15:04 avi12

To be fair, the project I linked is a puppet project that I let AI code it But in general, it's good advice to code split Besides that, I'd assume that the branch I linked failed to compile, am I right?

Let me clone and check it myself.

nishu-murmu avatar Apr 24 '25 04:04 nishu-murmu

@avi12 I checked the code. Problem is with browser.action API, I've checked with other APIs like storage API, those are working fine. @aklinker1 can chime in as to why that is happening

Image

nishu-murmu avatar Apr 25 '25 09:04 nishu-murmu

Another question is why do all of the chrome APIs need specific implementations in browser

avi12 avatar Apr 25 '25 13:04 avi12

Another question is why do all of the chrome APIs need specific implementations in browser

I don't have much idea regarding this, @aklinker1 has much more idea regarding this. I'm assuming all the chrome APIs are monkey patched to browser

nishu-murmu avatar Apr 25 '25 13:04 nishu-murmu

I polyfill the node environment with a chrome and browser global from @webext-core/fake-browser.

Ideally all APIs would have an in-memory implementation, for testing, but I haven't implemented all of them.

So that's why some APIs don't throw an error, like storage, and some do, like the action APIs.

aklinker1 avatar Apr 27 '25 01:04 aklinker1

I definitely need the browser.action.XXX methods added to fake-browser (as I see there is a PR for), since my tests failing as a result. Just adding comment to help make clear this is needed.

zampettim avatar Jun 11 '25 13:06 zampettim

I definitely need the browser.action.XXX methods added to fake-browser (as I see there is a PR for), since my tests failing as a result. Just adding comment to help make clear this is needed.

@zampettimWe can add them, but it's also possible for you to add mock implementations yourself. Just modify the fakeBrowser object in a setup file:

// vitest.setup.ts
import { fakeBrowser } from 'wxt/testing';
import { vi } from 'vitest';

const onClickCallbacks = new Set();
fakeBrowser.action ??= {}
fakeBrowser.action.onClicked ??= {}
fakeBrowser.action.onClicked = vi.fn((callback) => {
  onClickCallbacks.add(callback)
})
fakeBrowser.action.onClicked.trigger = () => {
  onClickCallbacks.forEach(callback => callback())
}

This is necessary because sometimes you might need to specifically mock things with Vitest in the future. Just for reference.

aklinker1 avatar Jun 14 '25 20:06 aklinker1

@avi12 Does this section clarify things?

https://deploy-preview-1743--creative-fairy-df92c4.netlify.app/guide/essentials/extension-apis.html#entrypoint-limitations

See https://github.com/wxt-dev/wxt/pull/1743

aklinker1 avatar Jun 14 '25 20:06 aklinker1