ai / nanoid

A tiny (124 bytes), secure, URL-friendly, unique string ID generator for JavaScript
https://zelark.github.io/nano-id-cc/
MIT License
24.33k stars 788 forks source link

SyntaxError: Unexpected token 'export' #395

Closed melvinwallerjr closed 1 year ago

melvinwallerjr commented 1 year ago

I'm looking to replace UUID with NanoID and getting the above error when running Jest tests. Each place where I've applied NanoID in place of UUID I get the export error. The project uses Node 14.20.0, React 17.0.2, Typescript 4.82, and Jest 29.0.3

I've tried suggestions to add to to jest.config.js with no improvement.

transformIgnorePatterns: ['/node_modules/(?!nanoid)'],

The error is basic and repeats:


Test suite failed to run
    Jest encountered an unexpected token

    Details:

    C:\projects\shared-ui-components\node_modules\nanoid\index.browser.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { urlAlphabet } from './url-alphabet/index.js'
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      1 | import React, { useState } from 'react';
    > 2 | import { nanoid } from 'nanoid';
        |                        ^

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1678:14)
ai commented 1 year ago

Try Nano ID 3.x. The 4.x branch is only for ESM projects (looks like you have CommonJS project and compile ESM to CJS).

melvinwallerjr commented 1 year ago

Thanks for the reply. Project was using "uuid": "8.3.2" and now replacing it with "nanoid": "3.3.4". Deleted node_modules and started fresh as a double check. Still getting the same errors. Any other suggestions?

ai commented 1 year ago

Nano ID is dual ESM/CJS package. Jest is hacking the Node.js loading mechanism. You may use old Jest and configure it in a wrong way, so it loads ESM-files into CJS package for some reason.

You need to ask Jest community since they use non-standard hacks which I do not know.

SunXinFei commented 1 year ago
jest.mock("nanoid", () => { return {
  nanoid : ()=>{}
} });

use mock in setupTests.js of jest

bencoullie commented 1 year ago

I ran into the same issue as OP. I'm on nanoid 4.0.1, jest 29.4.3 and node 18.12.1.

I also tried transformIgnorePatterns: ['node_modules/(?!nanoid)'] in my jest.config.js. I assumed that would tell the babel compiler 'compile these files for testing based off jest.config.js and my babel config (set by next.js via presets: ['next/babel'] in babel.config.js).

However I still got the SyntaxError: Unexpected token 'export' error.

I feel like there is something I don't understand here... that should be compiling nanoid and the error should disappear but it never. Any clues welcome.


My solution:

@SunXinFei's solution works for me (though I tweaked it to return a predictable actual string to test against):

// Mock nanoid to return a fake ID when called in a test
jest.mock('nanoid', () => ({
  nanoid: () => 'this-is-a-fake-nano-id',
}))
gabycperezdias commented 1 year ago

Facing the same issues, I cannot mock this since this is used as a dependency of a dependency of mine...

I tried with both nanoid 4 and 3...

Any tips?

taro-ishihara commented 1 year ago

Only I can do is like this. But this way, you can't change the fakeKey dinamically in each test.

const fakeKey = 'ABCD5678'
jest.mock('nanoid', () => {
    return { customAlphabet: () => () => fakeKey }
})