lisonge / vite-plugin-monkey

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

GM.xmlHttpRequest not resolvable without reconfiguring minify #166

Open blakehurd opened 3 weeks ago

blakehurd commented 3 weeks 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 3 weeks ago

what is your raw code, build config and product code

blakehurd commented 3 weeks 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 3 weeks 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 3 weeks 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 3 weeks ago

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

grant: ['GM.xmlHttpRequest'],
blakehurd commented 3 weeks 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 2 weeks 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 :)