1

So, I have a project that imports a package utils, and this package depends on '@zip.js/zip.js' lib. This lib is meant for browser usage and doesn't work on node.

The first weird thing is that, when I try to run jest, I get:

 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

Which is totally misleading.

Anyway, now that I know that the problem is the usage of zip.js on node, I need to mock it so that jest doesn't break.

According to the docs for Manual mocks, here is what I did:

  • create a folder __mocks__ in the root folder (next to node_modules)
  • create a folder @zip.js inside it
  • create a file zip.js inside

It didn't work. So I tried the code we see in that doc and try to add jest.mock('@zip.js/zip.js') as first line in my test file, but to no avail.

I'm really not sure about how the mock system is actually working, so any help is really appreciated.

Edit:

I'll keep here the list of what was tried and failed:

  • using "type": "module" in package.json (same result)
  • All solutions from here and there (same result. Anyway, I'm convinced that the error message is just misleading)
Sharcoux
  • 5,546
  • 7
  • 45
  • 78
  • 1
    Does your `package.json` file contain `"type": "module"`? Note also that `zip.js` can run in Node.js 18+ – check_ca Oct 19 '22 at 20:22
  • Thanks. That didn't solve it, but when replying to you I discovered "moduleNameMapper". This solved the issue! – Sharcoux Oct 19 '22 at 21:16

1 Answers1

1

I discovered the moduleNameMapper feature from jest. It totally solved my problem.

Here is my final jest.config.js file:

export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
  moduleNameMapper: {
    '@zip.js/zip.js': '<rootDir>/__mocks__/@zip.js/zip.js',
  },
}

And here is what I have in <rootDir>/__mocks__/@zip.js/zip.js file:

module.exports = {}

Hope it helps someone!

Sharcoux
  • 5,546
  • 7
  • 45
  • 78