Existe el isomorphic-webcrypto que pretende hacer eso pero no lo hace: crea una compilación separada para cada objetivo.
Existe la forma noble-crypto de hacerlo, pero se basa en condiciones if-else y falla si quiero un código mjs isomorfo.
Finalmente, existe la forma eval require way para pasar a través del paquete, pero el nodo no puede usarlo en mjs.
En breve :
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.Me gustaría usar criptografía nativa en node.js y en el navegador, de forma isomorfa, para poder usar mjs de importación nativos en el nodo y el navegador de forma transparente.
¿Cómo puedo hacer esto?
Bien. ¿Listo para algo feo? :-) He aquí, mi último hackjob... IsomorphicCyrpto.js:
export default globalThis.crypto || (await import('node:crypto')).default.webcrypto ; Esto funciona en Node.js v16 en modo módulo ( "type": "module" en paquete.json , o argumentos CLI equivalentes), y probablemente también funcionará con su paquete... pero quién sabe. ;-) Cualquiera que use este fragmento de código debe probar a fondo en cualquier plataforma en la que quiera usarlo.
En una palabra:
globalThis , que representa global bajo Node.js, window para la mayoría de los contextos del navegador, y tal vez incluso podría ser un contexto de Worker.crypto es una cosa. Si es así, probablemente estemos en un navegador y podamos usarlo directamente.crypto no existe, probablemente estemos en Node.js y necesitemos importar el módulo.import() en lugar de una import real.import() es asíncrono y devuelve una Promesa. Pero bueno, todo está bien, ¡porque la await de nivel superior es una cosa en Node.js ahora!Para luego usar el módulo:
import crypto from './lib/IsomorphicCrypto.js'; console.log( crypto.randomUUID() );Uggggly, pero funciona por ahora. Con suerte, a alguien se le ocurrirá una mejor solución, o Node.js y los contextos del navegador convergerán en la asignación de nombres en el futuro.