parcel icon indicating copy to clipboard operation
parcel copied to clipboard

fix(transformers/webextension): raw JSON and JS for web_accessible_resources

Open louisgv opened this issue 2 years ago • 22 comments

↪️ 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

louisgv avatar Jun 30 '22 05:06 louisgv

Is there a reason you don't always pass pipeline: 'raw' (and remove that js/json extension check)?

mischnic avatar Jun 30 '22 08:06 mischnic

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.

louisgv avatar Jun 30 '22 10:06 louisgv

Might need to update the integration tests since we're now avoiding transforming web_accessible_resources - right now we test that .jsx is compiled.

101arrowz avatar Jul 02 '22 01:07 101arrowz

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...

louisgv avatar Jul 02 '22 17:07 louisgv

Don't worry about the HMR tests, they're flakey.

mischnic avatar Jul 03 '22 08:07 mischnic

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).

mischnic avatar Jul 03 '22 08:07 mischnic

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.

louisgv avatar Jul 03 '22 15:07 louisgv

@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.

louisgv avatar Jul 15 '22 20:07 louisgv

So do we only want to do this for JSON files then? Sounds like @mischnic thinks this is a breaking change.

devongovett avatar Jul 31 '22 16:07 devongovett

The idea actually is to change it for all file declared in the web_accesible_reaourves as raw import.

louisgv avatar Jul 31 '22 17:07 louisgv

Why?

devongovett avatar Jul 31 '22 17:07 devongovett

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.

louisgv avatar Jul 31 '22 18:07 louisgv

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?

devongovett avatar Jul 31 '22 18:07 devongovett

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.

101arrowz avatar Jul 31 '22 19:07 101arrowz

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?

devongovett avatar Jul 31 '22 19:07 devongovett

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.

louisgv avatar Jul 31 '22 21:07 louisgv

What's the usecase for exposing the source code of a typescript file?

devongovett avatar Jul 31 '22 22:07 devongovett

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.

louisgv avatar Jul 31 '22 23:07 louisgv

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?

devongovett avatar Aug 02 '22 04:08 devongovett

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.

101arrowz avatar Aug 02 '22 04:08 101arrowz

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.

louisgv avatar Aug 02 '22 17:08 louisgv

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.

101arrowz avatar Aug 03 '22 18:08 101arrowz