require("url") resolves to null
# workers-help
m
I have an npm dependency in my worker that has a dependency on the "url" lib/module that is built into the nodejs runtime. Excerpt:
Copy code
const url_1 = require("url");
...
...
...
const url = new url_1.URL(input);//throws undefined
When I run wrangler dev I receive an undefined error I am guessing because the worker env doesn't know how to resolve the require("url") which is built into the nodejs runtime environment. Is there a way to bundle some kind of replacement for nodejs's url lib/module in order to get the require("url") to resolve correctly inside of the worker runtime. I was looking at the Configuration > Bundling documentation in the Wrangler docs but no lightbulbs have gone off on how to leverage it to provide a solution. Any experience anyone can share would be greatly appreciated!
k
Any reason you can't just use the
URL
global?
It's the same you'd expect of browsers.
Oh, you have a dependency that relies on it.
m
Yeah. That is the challenge.
I did verify it would work by modifying the source directly in my local node_modules of the dependency.
Like this:
Copy code
//const url_1 = require("url");
...
...
...
const url = new URL(input);//it works!
This was teh Bundling documentation I thought I might be able to leverage: https://developers.cloudflare.com/workers/wrangler/configuration/#bundling
k
That's just including arbitrary files,
esbuild
is what bundles your NPM dependencies.
You can add
node_compat = true
to your Wrangler.toml which adds some polyfills but you can't selectively just include the
url
module so it adds some bloat.
m
Thanks @kian for the info about esbuild I do have the
node_compat = true
as well as the
compatibility_flags = [ "nodejs_compat" ]
I was experimenting some more running
wrangler publish --dry-run --outdir dist
and do see that require("url"); being replaced with require_url() which is defined as this:
Copy code
// node-modules-polyfills-commonjs:url
var require_url = __commonJS({
  "node-modules-polyfills-commonjs:url"(exports2, module2) {
    init_virtual_process_polyfill();
    init_buffer();
    var polyfill = (init_url(), __toCommonJS(url_exports));
    if (polyfill && polyfill.default) {
      module2.exports = polyfill.default;
      for (let k in polyfill) {
        module2.exports[k] = polyfill[k];
      }
    } else if (polyfill) {
      module2.exports = polyfill;
    }
  }
});
So maybe its an issue where the polyfill isn't working in this scenario
🤷‍♂️