I recently created a Cloudflare Worker using the Typescript template, with minimal changes to the build configuration. The worker needs to utilize openpgp.js, which is supposed to be supported on Node.js based on the given link.
After successfully building it with npm run build
, I encountered an error when attempting to build with wrangler dev
:
webpack 5.38.1 compiled successfully in 1147 ms
Error: Something went wrong with the request to Cloudflare...
Uncaught ReferenceError: navigator is not defined
at line 237 in ./node_modules/openpgp/dist/lightweight/openpgp.min.mjs
at line 827 in __webpack_require__
at line 625 in ./src/crypto.ts
at line 827 in __webpack_require__
at line 749 in ./src/handler.ts
at line 827 in __webpack_require__
at line 1064
at line 1069
at line 1071
[API code: 10021]
While browsing for solutions, I came across a recommendation to use browser-env to expose the global variable navigator
. However, upon trying this approach, I encountered a cascade of errors leading to module not found issues:
ERROR in ./node_modules/window/node_modules/tough-cookie/lib/cookie.js 34:11-26
Module not found: Error: Can't resolve 'util' in '/Users/renato/programming/projects/renato-worker/node_modules/window/node_modules/tough-cookie/lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
...
ERROR in /Users/renato/programming/projects/renato-worker/src/index.ts
./src/index.ts 4:23-36
[tsl] ERROR in /Users/renato/programming/projects/renato-worker/src/index.ts(4,24)
TS7016: Could not find a declaration file for module 'browser-env'. '/Users/renato/programming/projects/renato-worker/node_modules/browser-env/src/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/browser-env` if it exists or add a new declaration (.d.ts) file containing `declare module 'browser-env';`
My attempt to install types/browser-env resulted in a 404 error, leading me to rethink the solution provided. The documentation for browser-env also warned against a particular usage:
https://github.com/jsdom/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global
A common antipattern we see when people use jsdom is copying globals from a jsdom window onto the Node.js global, and then trying to run the code---intended for a browser---inside Node.js. This is very bad and you should not do it.
The alternative suggestion of using detect-node
did not seem applicable to my situation, as the issue appears to relate more to the compilation process than differentiating between a browser or Node environment.
At this point, I am at a standstill. Would appreciate any insights from those proficient in tools like webpack, node.js, Typescript, browser APIs, wrangler, and Cloudflare API to help identify the root cause and suggest possible solutions.