如何在Jest中Mock仅支持浏览器的@zip.js/zip.js库?
解决Jest中Mock仅支持浏览器的@zip.js/zip.js库问题
问题背景
项目引入的utils包依赖@zip.js/zip.js,但该库仅支持浏览器环境,无法在Node.js中运行。执行Jest测试时触发「Jest encountered an unexpected token」错误,提示import语句不能在模块外使用——这个错误信息存在误导性,实际核心问题是库不兼容Node.js环境,而非模块语法问题。
已尝试的无效方案:
- 按Jest手动Mock文档创建
__mocks__目录结构 - 在测试文件首行添加
jest.mock('@zip.js/zip.js') - 在
package.json中设置"type": "module"及相关Issue解决方案
错误详情
FAIL tests/index.test.ts ● Test suite failed to run Jest encountered an unexpected token This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript. By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules". Here's what you can do: • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it. • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. • If you need a custom transformation specify a "transform" option in your config. • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. You'll find more details and examples of these config options in the docs: https://jestjs.io/docs/en/configuration.html Details: ./node_modules/@zip.js/zip.js/index.js:29 import Deflate from "./lib/core/codecs/deflate.js"; ^^^^^^ SyntaxError: Cannot use import statement outside a module > 1 | import { | ^ 2 | Data64URIWriter, 3 | Entry, 4 | TextWriter, at Runtime.createScriptFromCode (../../node_modules/jest-cli/node_modules/jest-runtime/build/index.js:1350:14) at Object.<anonymous> (../utils/src/unzipFolder.ts:1:1) Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 5.926 s
正确Mock方案
1. 配置Jest映射Mock文件
在Jest配置文件(jest.config.js/jest.config.ts)中添加moduleNameMapper,将@zip.js/zip.js直接映射到本地Mock文件,跳过对原库的解析:
module.exports = { // 保留原有配置 moduleNameMapper: { '^@zip.js/zip.js$': '<rootDir>/__mocks__/zip.js' } };
2. 创建Mock实现文件
在项目根目录新建__mocks__/zip.js,根据utils包中实际用到的导出内容,模拟对应的类和方法:
// 模拟你代码中用到的@zip.js/zip.js导出项 export class Data64URIWriter { write() {} close() { return Promise.resolve(); } } export class Entry { name = 'mock-entry'; getData() { return Promise.resolve(new Blob(['mock-content'])); } } export class TextWriter { content = ''; write(chunk) { this.content += chunk; } close() { return Promise.resolve(this.content); } } // 若有其他用到的导出,按需添加模拟实现
3. 测试文件中自定义Mock行为(可选)
如果需要在特定测试中覆盖Mock逻辑,可在测试文件中重新Mock:
import { Data64URIWriter } from '@zip.js/zip.js'; jest.mock('@zip.js/zip.js', () => ({ Data64URIWriter: jest.fn().mockImplementation(() => ({ write: jest.fn(), close: jest.fn().mockResolvedValue('mock-base64') })), Entry: jest.fn().mockReturnValue({ name: 'test-file.txt', getData: jest.fn().mockResolvedValue(new Blob(['test content'])) }) })); // 后续测试逻辑 test('unzipFolder works correctly', async () => { // ...测试代码 });
4. TypeScript类型兼容处理
如果是TypeScript项目,为避免类型报错,可在tsconfig.json中添加路径映射:
{ "compilerOptions": { // 其他配置 "paths": { "@zip.js/zip.js": ["__mocks__/zip.js"] } } }
内容的提问来源于stack exchange,提问作者Sharcoux
相关产品推荐
相关产品推荐

