javascriptwebpacktampermonkey

How to access webpack modules from a userscript?


I want to write a userscript (for TamperMonkey et al) for a website that instead of any sane method, uses webpack to bundle/load JS libraries. I need to tinker with one of those libraries. They not on the global namespace as usual, so where are they?

Note that while there are similar questions here on SO, they are from a developer's perspective and boil down to "change the code" or "change the webpack config", both of which I can't do.


Solution

  • Webpack creates an object in the window. You can push your own module there to get a reference to exports of other modules.

    https://github.com/moonlight-mod/webpackTools has nice utils, but it boils down to this:

    // ==UserScript==
    // @name        Webpack Exports
    // @namespace   Violentmonkey Scripts
    // @match       https://x.com/*
    // @grant       none
    // @version     1.0
    // @author      -
    // @description -
    // ==/UserScript==
    
    // You can hardcode the key once you find it
    for (const key of Object.getOwnPropertyNames(window)) {
      if ((key.includes("webpackJsonp") || key.includes("webpackChunk") || key.includes("__LOADABLE_LOADED_CHUNKS__"))) {
        console.log("WEBPACK key", key);
        // Pushing our module
        window[key].push([
          ["_userscriptModule"],
          {
            hackermans: (module, exports, webpackRequire) => {
              console.log('WEBPACK', module, exports, webpackRequire);
              window.__wpRequire = webpackRequire;
              // modules code
              console.log('WEBPACK .m', window.__wpRequire.m);
              // cache of modules, look for __wpRequire.c['somekey'].exports
              // like __wpRequire.c['somekey'].exports.default
              console.log('WEBPACK .c', window.__wpRequire.c);
            }
          },
          (webpackRequire) => {
            console.log('Webpack Onload');
            webpackRequire('hackermans');
          }
        ]);
      }
    }