Angular 13类库中使用JSZip报非构造函数错误如何解决
Angular 13公共类库集成JSZip运行时报「不是构造函数」的解决方案
这个报错本质是Angular类库和普通应用的模块打包规则不一致导致的,和业务代码、依赖安装失败没关系:
- 之前在单站点里用
import * as JSZip from 'jszip'能正常运行,是因为Angular应用的webpack默认做了语法适配,会把CommonJS格式的JSZip构造函数直接绑到导入的命名空间对象上 - 抽成Angular 13公共类库之后,ng-packagr为了符合Angular Package Format规范,构建时会关掉这类自动适配逻辑,webpack会给导入的模块加一层命名空间缓存,你拿到的
JSZip实际是包含所有导出的整个模块对象,根本不是构造函数本身,调用new自然会抛错
可按顺序尝试的解决方案
- 方案1:调整TS配置+更换导入语法
先修改类库目录下的tsconfig.lib.json,在compilerOptions中开启两个模块互操作配置:
再把原来的导入语句替换为默认导入:{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true } }
重新构建类库后即可正常实例化。import JSZip from 'jszip'; - 方案2:使用TS原生CommonJS导入语法(适配方案1无效的场景)
如果开了esModuleInterop还是报默认导出不存在的问题,直接用TS兼容的CommonJS导入写法,绕开webpack的命名空间缓存逻辑:
我之前抽离文件处理公共类库时踩过一模一样的坑,这个写法最稳,不需要额外改TS配置,能直接通过ng-packagr构建,运行时也不会有模块包装问题。import JSZip = require('jszip'); - 方案3:排查多版本依赖冲突
如果以上两种改法都无效,在项目根目录执行npm ls jszip(用pnpm/yarn的话换对应包管理器的list命令)检查依赖树:如果类库和宿主站点各自安装了不同版本的JSZip,webpack解析时会拿到两份模块实例,也会触发构造函数校验错误。
这种情况可以在根目录package.json中通过overrides(npm 8+)或resolutions(yarn/pnpm)字段锁定JSZip版本,重新安装依赖即可。
临时验证技巧:如果需要快速确认问题根因,可以在实例化前打印导入的JSZip对象,你会看到真正的构造函数挂在
default属性上,临时写const zip = new (JSZip as any).default()也能运行,但不推荐在生产环境用这种写法,后续JSZip版本升级很容易出兼容问题。
内容的提问来源于stack exchange,提问作者Minop
相关产品推荐
相关产品推荐

