javascript - 本机 node.js 和浏览器加密的同构代码
问题描述
有一个isomorphic-webcrypto假装这样做但没有:它为每个目标构建单独的构建。
有一种高贵的加密方式可以做到这一点,但它基于 if-else 条件,如果我想要一个同构的 mjs 代码,它就会失败。
最后,还有eval 的 require 方式来传递 bundler,但是 node 无法在 mjs 中使用它。
简单来说 :
const crypto = require("crypto"); // work only in node.js but not in mjs file.
const crypto = eval(`require("crypto")`); // pass-thru bundler, then work only in node.js but not in mjs file.
window.crypto; // work only in browser
import * as crypto from "crypto"; // could work from both but must be at top level of a module, so it can't be a conditional import.
我想在 node.js 和浏览器中以同构的方式使用本机加密,以便能够在节点和浏览器中透明地使用本机导入 mjs。
我怎样才能做到这一点?
解决方案
好吧。准备好迎接丑陋的事情了吗?:-) 看哪,我最近的 hackjob……IsomorphicCyrpto.js:
export default
globalThis.crypto ||
(await import('node:crypto')).default.webcrypto
;
这适用于 Node.js v16 的模块模式("type": "module"
在 package.json或等效的 CLI args 中),并且可能也适用于您的捆绑程序……但谁知道呢。;-) 任何使用此代码片段的人都应该在他们想要使用它的任何平台上进行彻底的测试。
简而言之:
- 对于大多数浏览器上下文,我们使用
globalThis
代表global
Node.js的 ,window
甚至可能是 Worker 上下文。 - 我们首先检查是否
crypto
是一个东西。如果是,我们可能在浏览器上,并且可以直接使用它。 - 如果
crypto
不是,我们可能在 Node.js 上,我们需要导入模块。 - 因为这是动态完成的,所以我们需要一个dynamic
import()
而不是 trueimport
。 import()
是异步的并返回一个 Promise。但是,嘿,这一切都很好,因为顶级await
现在是 Node.js 中的东西!
然后使用该模块:
import crypto from './lib/IsomorphicCrypto.js';
console.log( crypto.randomUUID() );
Uggggly,但现在可以使用。希望有人提出更好的解决方案,或者 Node.js 和浏览器上下文在未来会集中在命名上。
推荐阅读
- java - 在 onDataChange 方法中设置数据,并在外部使用
- unity3d - unity BoxCollider2D 穿过一些物体,同时保留触发器属性
- powerbi - PowerBI 中的 MDX 过滤
- python - 附加到 Django 中的 request.sessions[list]
- java - 带有spring boot postgresql的GraalVM native-image将无法构建
- sql - 在SQL LEFT JOIN中使用ISNULL来检查结果是否为null,如果是则使用另一个值加入
- node.js - 带有自定义快递服务器的 nextjs 不会在生产中重定向 url
- javascript - Angular 谷歌地图自定义 HTML infoWindow
- php - ImageColorAt 不从 ImageCreateTrueColor 返回 alpha
- html - 为什么我的 CSS 网格区域的行为不像它应该的那样?