I am working on an Angular 18 project that uses JSZip to compress multiple .txt files into an archive. I was previously using the “usual” JSZip syntax like such:
import JSZip from "jszip";
export class ScriptDatabase {
// My class code...
exportDatabase(): Promise<Blob> {
const zip = new JSZip();
for (const [id, archive] of this.archives) {
zip.file(`${id}.txt`, archive.exportArchive());
}
return zip.generateAsync({type: "blob"});
}
}
I tried to convert this into a dynamic async import to reduce the final bundle size of my application, as JSZip is actually quite a big library. I tried something like this at first:
async exportDatabase(): Promise<Blob> {
const JSZip = await import('jszip');
const zip = new JSZip();
for (const [id, archive] of this.archives) {
zip.file(`${id}.txt`, archive.exportArchive());
}
return await zip.generateAsync({ type: "blob" });
}
But my issue is that apparently the JSZip
constant is actually a JSZip object, so I can’t call new
on that, as it has no constructor.
So I tried to use the JSZip
constant as an actual JSZip instance like so:
async exportDatabase(): Promise<Blob> {
const JSZip = await import('jszip');
for (const [id, archive] of this.archives) {
JSZip.file(`${id}.txt`, archive.exportArchive());
}
return await JSZip.generateAsync({ type: "blob" });
}
My IDE stopped complaining, and the app actually built, but when I tried executing the method, I got this error: ERROR TypeError: JSZip.file is not a function
.
And sure enough, when I tried to console log this object, it seems like I got a strange, incomplete version of the JSZip object, and I can only use loadAsync on it. So it’s very clear that I’m not using this correctly.
So now I’m stumped. What’s the correct syntax to use JSZip with dynamic imports?