parcel
parcel copied to clipboard
fix(transformers/webextension): raw JSON and JS for web_accessible_resources
↪️ Pull Request
When having a json
or js
file in web-accessible resources, parcel transforms and wrap them into js
instead of keeping them as-is.
"web_accessible_resources": [{
"resources": [
"resources/test.json"
],
"matches": [
"https://www.plasmo.com/*"
]
}],
Get turned into:
"web_accessible_resources": [
{
"resources": [
"resources/test.js"
],
"matches": ["https://www.plasmo.com/*"]
},
],
This is undesirable as web-accessible-resources should stay raw without any transformation/bundling applied.
💻 Examples
🚨 Test instructions
✔️ PR Todo
- [ ] Added/updated unit tests for this change
- [ ] Filled out test instructions (In case there aren't any unit tests)
- [ ] Included links to related issues/PRs
Is there a reason you don't always pass pipeline: 'raw'
(and remove that js/json extension check)?
Is there a reason you don't always pass
pipeline: 'raw'
(and remove that js/json extension check)?
I thought about that too, that'd make this code block much simpler. Tho, one reason might be that users might want to include a ts
or tsx
file or certain files that need transformation/bundling/optimizing (img for example).
But my guts tell me that folks who adding stuffs into the web_accessible_resources
just want them copied verbatim, but I'm not entirely sure tbh.
Might need to update the integration tests since we're now avoiding transforming web_accessible_resources
- right now we test that .jsx
is compiled.
Might need to update the integration tests since we're now avoiding transforming
web_accessible_resources
- right now we test that.jsx
is compiled.
Done - I'm not sure how to fix the HMR test tho :d...
Don't worry about the HMR tests, they're flakey.
So this would be a breaking change. Are there any valid/common usecases for JS inside web_accessible_resources?
Also one thing that probably is useful is using the image transformer to resize/encode an image. I'm not sure how that behaves right now (if pipeline: 'raw'
takes precedence or not).
So this would be a breaking change. Are there any valid/common usecases for JS inside web_accessible_resources?
Also one thing that probably is useful is using the image transformer to resize/encode an image. I'm not sure how that behaves right now (if
pipeline: 'raw'
takes precedence or not).
Specific example: InboxSDK ships a .js
bundled file, it's a 3rd party vendor and they don't share the actual source https://github.com/PlasmoHQ/plasmo/issues/71
One of their js file need to be put into the web_accessible_resources
as-is.
@devongovett Just wanted to bump this PR up your queue - at the moment, since webextension transformer does not use scheme, user can't overcome this issue with raw:file.json
either.
So do we only want to do this for JSON files then? Sounds like @mischnic thinks this is a breaking change.
The idea actually is to change it for all file declared in the web_accesible_reaourves as raw import.
Why?
Why?
Specifically, the "end-user" of this particular web extension feature need the resource as-is with no transformation (i.e the underlying webpage and the extension itself). However, since the current webext transformer implementation does not respect parcel scheme, the easiest way to resolve the issue for the 80% use case (need no transformation/asset optimization) is to keep it raw. The next iteration would be to resolve the TODO note in the transformer that would allow resource to use parcel scheme.
Still, for the majority of use case, raw pass thru would be the expected behavior, not transformed result.
I understand why a JSON file would need to be raw, but why should JS or CSS or images or anything else not be processed?
I think the argument is that any files being added by the user into web_accessible_resources
should be left as-is to preserve any qualities that external consumers need (e.g. a global entry point), while the files Parcel adds to web_accessible_resources
by scanning imports within content scripts should still be processed normally.
Parcel doesn't work like that anywhere else, so I think it would be weird if JS/CSS/etc was not processed as might be expected. Also it's a breaking change, so we cannot do that until a major version. Fixing JSON as was the original intent of this PR seems fine because it was broken before, but changing the behavior of JS doesn't seem viable.
Is there an issue with processing the code? Perhaps that is the real issue to be solved rather than not processing it at all?
Is there an issue with processing the code? Perhaps that is the real issue to be solved rather than not processing it at all?
Yes, and it largely pertains to how this feature (web accessible resource) is used in web extension.
Let's say a webext dev would like to expose a .ts file, a .svelte file, or a .js file that's already processsed to the end user, who are website owner targeted by these extension. Because parcel transform these files, it breaks the expected result for both the webext dev and the resource consumer.
I think webext dev would be weirded out that they must use the raw:
scheme to ensure no transformation is done to their file (if we decided to have transformation done by default to this web accessible resources list). It's true that it might be inconsistent with how parcel work but it's already not parsing scheme, so the current behavior doesn't align with parcel and is introducing a major blocker to 80% web ext developer who use this feature.
What's the usecase for exposing the source code of a typescript file?
Use case specific to "expose raw ts to website via web extension": the underlying webpage that is not owned by the webext dev has a ts interpreter, i.e it has a scripting system that uses ts, like deno. It intepret the web accessible resource file exposed by the extension to enhance/tailor its page to the extension user.
When webext dev do not need to expose these file to end user, they would import those file in their source code and it will be automatically added to the web accessible resource list. All in all, the files declared in web accessible resource list are intended to be delivered raw to end user.
A real-world use case of this web accessible resource feature where webext dev do not want to transform js file: inboxsdk https://www.inboxsdk.com/ (as mentioned above). I.e, a 3rd party vendor SDK is providing API in a prepacked js file, and to use it, dev must expose them as web accessible resource with no modification in the output.
Those sound like very narrow usecases for which prepending raw:
wouldn't be unreasonable. You'd need to use raw:
if importing such an asset in normal code as well. But I'll defer to @101arrowz since he is much more familiar with web extensions than I.
a 3rd party vendor SDK is providing API in a prepacked js file, and to use it, dev must expose them as web accessible resource with no modification in the output.
What is broken when it is processed with parcel? That seems like the real bug?
I think that @louisgv is right about the majority of users of web_accessible_resources
not wanting their files transformed. They're static assets in the majority of cases in my experience; in general, the only case in which they aren't is if you are importing stuff from your web extension within your content script, in which case Parcel will add it into web_accessible_resources
for you anyway.
However, upon reconsideration I think you're right that it's not a good idea to force every import to be raw:
because that makes it impossible to use transformation. Transformation could still be useful in some cases: for example, export a public API for your extension written in TypeScript to third-party websites.
I think a reasonable middle ground is to add support for using the raw:
pipeline within web_accessible_resources
. In other words, you can do:
{
"web_accessible_resources": [{
"resources": ["raw:static/InboxSDK.js"],
"extension_ids": ["your_id_here"]
}]
}
The only reason this doesn't work right now is because the globber doesn't let you use pipelines/querystrings/whatever. So our solution could be extract pipelines and query strings by slicing around :
and ?
that exists in the path, and then applying them again post-glob.
However, upon reconsideration I think you're right that it's not a good idea to force every import to be raw: because that makes it impossible to use transformation. Transformation could still be useful in some cases: for example, export a public API for your extension written in TypeScript to third-party websites.
I agree with this, but I think the default behavior should be raw. Then if there's a scheme available, the webext transformer would parse and pipe it down the line for other transformer/optimizer to do their job. Parcel is applying transformation when the default expectation for users of this feature is that "there should be none."
Those sound like very narrow usecases for which prepending raw: wouldn't be unreasonable. You'd need to use raw: if importing such an asset in normal code as well. But I'll defer to @101arrowz since he is much more familiar with web extensions than I.
Those are the main 80% use cases for this specific "web-accessible-resources" feature, which is why I had to emphasize those words above. The common use cases are generally solved by developers simply importing these resources in their source code, and parcel would pick them up and add them to this list automatically (thanks to @101arrowz works). The manual use of this "web_accessible_resources" list in manifest.json is really a "last resort" kind of action which is why a lot of the use case would seem "narrow." I highly rec looking at the issue from the lens of webext dev and not web dev.
I'm the core maintainer of Plasmo, a parcel-based web extension framework: https://github.com/PlasmoHQ/plasmo/ and in my Discord server I saw folks describing even stranger use-cases. I think it's really the power of extension - people exploring ideas that webpage can't do.
The problem with having it "raw by default" is that there's no current syntax for opting-in to the default transformation scheme (i.e. there's no named pipeline to tell Parcel to use SWC and Terser on your TypeScript file). However we do have the raw:
scheme to disable transformation. We shouldn't engineer a new syntax just for this singular part of Parcel, so I don't think raw by default is feasible.