如何在node.js上使用openpgp.js(Cloudflare worker)-Error Uncaught Re



我有一个Cloudflare Worker(根据Typescript模板创建,构建配置几乎没有更改(,它需要使用openpgp.js,如此链接所示,在Node.js上运行时应该支持它。

当我用npm run build构建它时,它似乎工作得很好,但当我尝试用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]

这个问题看起来很相似,但那里的解决方案似乎不适用于我的情况。

一种解决方案是使用浏览器env将全局变量navigator公开给node.js环境。当我尝试的时候,我得到了一个巨大的错误,结果是这样的:

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 ./node_modules/window/node_modules/tough-cookie/lib/memstore.js 35: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
...
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';`

尝试安装类型/浏览器环境:

▶ npm i --save-dev @types/browser-env
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@types%2fbrowser-env - Not found

嗯,我想这不是我想要的,在浏览器环境的文档中有一个严厉的警告:

https://github.com/jsdom/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global

当人们使用jsdom时,我们看到的一个常见的反模式是将全局变量从jsdom窗口复制到Node.js全局变量上,然后尝试在Node.js内运行用于浏览器的代码。这非常糟糕,你不应该这样做。

我认为,使用detect-node的另一个建议解决方案不适用于我的情况,因为无论是否是浏览器,都不需要运行我的代码。。。在运行构建时,这似乎是一个编译问题。

所以我完全陷入了困境。

有没有人更熟悉所涉及的无数工具(webpack、node.js、Typescript、浏览器API、wrapper、Cloudflare API(,能够告诉我至少是哪一个导致了这种情况,以及我可以尝试修复它?

经过长时间的努力,我发现问题源于Cloudflare在其环境上部署Javascript代码之前对其进行验证的方式(即使在运行预览模式时也是如此(。

它不允许使用某些API,包括通常在后端Javascript中不可用的navigator对象。

在使用openpgp.js时,这是一个问题,因为它使用navigator来识别userAgent和可用的内核数量。

我提出了一个拉取请求,将对navigator的访问转移到一个可以用webpack等工具轻松替换的地方,但PR被拒绝了,因为它甚至没有必要,例如,你可以用{}替换navigator,一切都应该正常。

查看pull请求以了解更多详细信息,但总的来说,在你的webpack.config.json文件中添加这样的内容:

plugins: [
new webpack.ProvidePlugin({
'navigator': ['{}'],
}),
]

openpgp.js的作者似乎热衷于在未来的版本中删除对navigator的依赖,所以在不久的将来,可能不再需要这种破解了!

最新更新