I am trying to use OpenPGP.js V6 in a webapp made with SvelteKit, TypeScript and Vite.
OpenPGP.js V6 is now declared as a module, and I cannot find a way to import it correctly with my current stack.
I first tried to import openpgp in my Svelte component as suggested by the doc:
<script lang="ts">
import * as openpgp from "openpgp";
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<p>{ JSON.stringify(openpgp.config) }</p>
I result in a browser error:
TypeError: import_module.createRequire is not a function
<anonymous> openpgp.mjs:1767
<script lang="ts">
import * as openpgp from "openpgp/lightweight";
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<p>{ JSON.stringify(openpgp.config) }</p>
This results in a Vite error:
[plugin:vite:import-analysis] Missing "./" specifier in "openpgp" package
It seems that by default, importing from "openpgp" actually imports the node modules. So I tried to import the browser module directly:
<script lang="ts">
import * as openpgp from "../../node_modules/openpgp/dist/openpgp.mjs";
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<p>{ JSON.stringify(openpgp.config) }</p>
This works in the browser but gives a TypeScript error:
Could not find a declaration file for module '../../node_modules/openpgp/dist/openpgp.mjs'. '/.../test-app/node_modules/openpgp/dist/openpgp.mjs' implicitly has an 'any' type.ts(7016)
I could //@ts-ignore
it of course, but it would remove most of the benefits of using TypeScript.
The issue can be reproduced by creating a minimal SvelteKit app (npx sv create my-app
with the SvelteKit minimal template).
package.json (please note that I also installed @openpgp/web-stream-tools
as the doc suggests):
{
"name": "test-app",
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
"@openpgp/web-stream-tools": "^0.1.3",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/node": "^22.9.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0",
"vite": "^5.0.3"
},
"dependencies": {
"openpgp": "^6.0.0"
}
}
vite.config.ts:
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()]
});
svelte.config.js:
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter()
}
};
export default config;
tsconfig.json:
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
}
So in the end, it was an issue with OpenPGP.js v6.0.0. The bug was fixed on November 21: https://github.com/openpgpjs/openpgpjs/commit/f75447afaa681dc6fa7448a4bf82c63b10265b46