lisonge / vite-plugin-monkey

A vite plugin server and build your.user.js for userscript engine like Tampermonkey, Violentmonkey, Greasemonkey, ScriptCat
MIT License
1.39k stars 71 forks source link

GM.xmlHttpRequest not resolvable without reconfiguring minify #166

Closed blakehurd closed 3 months ago

blakehurd commented 5 months ago

Thanks for the plugin, it remains useful!

The default minify ON settings appear to clobber the following:

import {
    GM,
} from '$';

const STREAMING_SUPPORTED = GM.xmlHttpRequest?.RESPONSE_TYPE_STREAM;
console.log('Streaming supported: ', STREAMING_SUPPORTED);

.... using GM.xmlHttpRequest in code instead of GM_xmlHttpRequest, to maintain compatibility with Greasemonkey/GM API 4 while supporting Tampermonkey and others.

Is this intentional? By clobber, I mean these references resolve to "undefined" in Greasemonkey and Tampermonkey, instead of resolving to 'stream' and the appropriate xhr function.

When I add this configuration to Vite, then it works: esbuild: { minifyIdentifiers: false, keepNames: true, },

But it doesn't minify as completely as it could. Ideally this would work with default minify.

lisonge commented 5 months ago

what is your raw code, build config and product code

blakehurd commented 5 months ago

So the code in question is https://greasyfork.org/en/scripts/472236-gm-fetch/code but lightly revised to work with GM.xmlHttpRequest only instead of GM_xmlhttprequest, which ensures it works on Greasemonkey too (besides Tampermonkey).

build config

export default defineConfig({
  plugins: [
    monkey({
      entry: 'src/main.js',
      userscript: {
        author: 'foo',
        description: 'foo',
        name: 'foo',
        namespace: 'bar',
        downloadURL:
          '...',
        updateURL:
          '...',
        match: [
            // ...
        ],
      },
      build: {
        fileName: 'foo.user.js',
        metaFileName: true,
      },
    }),
  ],
  build: {
    minify: true,
  },
  // TODO: https://github.com/lisonge/vite-plugin-monkey/issues/166 default minify settings appear to clobber GM.xmlHttpRequest. Reconfiguring esbuild's minify settings mitigates this, at the cost of a slightly less minified userscript. (+43 kB)
  esbuild: {
    minifyIdentifiers: false,
    keepNames: true,
  },
});

If you want a full printout let me know. Not sure what else you need?

lisonge commented 5 months ago

Can you provide the repository url to reproduce this issue?

Or you can upload a repository zip file to the github comment section

blakehurd commented 5 months ago

output.zip jstest.user.js.txt

Please let me know if any issues reproducing the issue. (My way of invoking npm is a bit different but I think this is close enough you should be able to run with it). Attached a sample user.js with the default minify settings as well, for reference. I added some more specifics to the README in the zip as well.

FWIW, the script I've attached seems to work on both Greasemonkey and Tampermonkey when minify customization is applied (the esbuild settings referenced earlier, which shouldn't be needed), and doesn't work when minify is run without customization (when the esbuild settings are commented out).

If I use import GM_xmlhttpRequest instead it works in Tampermonkey (minify doesn't clobber) but it doesn't work in Greasemonkey (the function doesn't exist in Greasemonkey).

Thanks!

lisonge commented 5 months ago

This is caused by autoGrant, you can manually set grant to solve it

grant: ['GM.xmlHttpRequest'],
blakehurd commented 5 months ago

Thanks! That appears to resolve the issue. Happy to have the minify benefits and I don't require autoGrant to work here. That's good enough for me.

That said, is there something fixable in autoGrant here? I would suspect others running into this issue might not expect to look there (unless they happen upon this issue link).

Sec-ant commented 4 months ago

@blakehurd Hi, I'm the maintainer of the said script (gm-fetch) you'd like to adapt. Just want you to know I'd love to accept PRs for it to be compatible with Greasemonkey in a non-breaking way, but of course it's entirely up to you :)