wxt-dev / wxt

⚡ Next-gen Web Extension Framework
https://wxt.dev
MIT License
4.48k stars 186 forks source link

[Discussion] Built-in Messaging API #643

Open aklinker1 opened 6 months ago

aklinker1 commented 6 months ago

Feature Request

Replacement for browser.runtime.sendMessage/browser.runtime.connect/browser.tabs.sendMessage. The APIs provided by Chrome are difficult to use, not type-safe, and leads to bad DX.

In particular, the messaging API should support the following:

Additionally, there are multiple ways of architecting an extension around storage/messaging. I don't think a single solution will work for all these architechures. We may want to consider different APIs for each?

Background as an "API" Event-based Decentralized
import { ... } from 'wxt/rpc' import { ... } from 'wxt/events' import { ... } from 'wxt/messaging'

These are all the main ways I'm aware of at least.

That said, I don't like the decentralized approach, and would prefer to omit it entirely from WXT. It basically turns into the "background as an API" in the end anyways, since messages have to be passed through the background. I guess we could make an abstraction around it so it seems like you're able to message between contexts without the background, so maybe an API like that could exist.

Background as an API

Something like https://github.com/jlalmes/trpc-chrome could be good. Need to support more types of messaging though.

Also, https://webext-core.aklinker1.io/guide/proxy-service/ is very convenient to use. Though a tRPC approach accomplishes the same thing, and perhaps more elegantly?

Event-based

Made a POC for an extension based on events a while back: https://github.com/aaronklinker-st/event-driven-web-extension/tree/main/src/plugins/event-framework

Decentralized

Something like https://www.npmjs.com/package/webext-bridge could be good. Need to support more types of messaging though.

manojhl commented 6 months ago

I believe having a wxt way of sending Messaging API is critical, maybe create a separate package wxt-messaging to keep it as optional.

I come from plasmo ecosystem, though i use both @plasmohq/messaging and webext-bridge. I like webext-bridge way of doing things, it's simple but limited.

aklinker1 commented 6 months ago

@manojhl thanks for the feedback! I never used plasmo's messaging APIs, I'll look at their API for reference as well.

Eventually, I plan on publishing all these extra utils (including storage and localization) as separate packages so you can use them outside WXT as well.

spookyuser commented 5 months ago

I also like background as an api! I don't love plasmo's messaging because there's so much setup involved to create a new api function vs trpc which is just one line.

I too have been enjoying https://github.com/sinanbekar/webext-zustand and (ofc) https://webext-core.aklinker1.io/guide/proxy-service, being able to switch between contexts makes the messaging apis feel particularly annoying soo I also like the proxying approach with everything in the bg.

Also https://github.com/janek26/trpc-browser seems to be better maintained, but the last time I tried it I kept getting error messages related to chrome ports so I haven't used it since, but I think these may have actually been because of plasmo 😬

I don't understand react server components nearly well enough to know if this is even conceptually possibly, but it would be cool if it were possible to run the react-dom server in the bg and use it as a react server for components in the content script

aklinker1 commented 5 months ago

I don't understand react server components nearly well enough to know if this is even conceptually possibly, but it would be cool if it were possible to run the react-dom server in the bg and use it as a react server for components in the content script

Man, I have no idea how this would work lol. Maybe with offscreen documents? But I guess I don't understand why it would be useful to "server render" UI in an extension... But an interesting idea non-the-less.

I too have been enjoying https://github.com/sinanbekar/webext-zustand

Didn't know about this one, thanks for sharing!

spookyuser commented 4 months ago

Man, I have no idea how this would work lol. Maybe with offscreen documents? But I guess I don't understand why it would be useful to "server render" UI in an extension... But an interesting idea non-the-less.

lol me too - I think the only reason would be being able to manage all the state in one place and being able to do fetch requests and stuff without having to proxy them through the background first so I guess it would remove the need for the trpc-browser layer / js object proxy

axuj commented 4 months ago

@webext-core/proxy-service works very well, but after build, both ui and background will have called code. I wrote a lib that ui only use typescript, and support pass stream data in asyncGeneratorFunctions.

aklinker1 commented 4 months ago

@webext-core/proxy-service works very well, but after build, both ui and background will have called code

Yeah, that's something I've known about for a while, but have never fixed. Would require a breaking change to fix.

Instead, I've been using trpc-chrome for my communication needs. It's a little more setup, but I think it creates a more unified API and includes tons of other features like validation.

axuj commented 4 months ago

@webext-core/proxy-service works very well, but after build, both ui and background will have called code

Yeah, that's something I've known about for a while, but have never fixed. Would require a breaking change to fix.

Instead, I've been using trpc-chrome for my communication needs. It's a little more setup, but I think it creates a more unified API and includes tons of other features like validation.

Validation is not as important in browser extensions as it is in web APIs, in my opinion. You can check out my library webext-rpc which works like @webext-core/proxy-service but doesn't build the dependency into the UI.

aklinker1 commented 4 months ago

I like your library a lot! Like the API, thanks for sharing!

manojhl commented 4 months ago

Just mentioning @extend-chrome's https://github.com/extend-chrome/messages package which is built on promises and observables.

Timeraa commented 3 months ago

Just gonna comment on this, I'm currently trying my best to implement this in a good type-safe way, so far it's looking good, taking a lot of inspiration from @aklinker1's Proxy service but supporting all the possibilities and especially different ways of messaging is a bit of a pain.

I'll try to get as much progress done and open a draft PR if I can, working on a POC right now