Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Failing to parse ESM files imported from node_modules with a .js extension #2913

Open
gpremo-re opened this issue Dec 31, 2024 · 6 comments

Comments

@gpremo-re
Copy link

gpremo-re commented Dec 31, 2024

Version

14.4.2

Steps to reproduce

Easy reproduction steps:

Clone repository, install deps, run tests

git clone https://github.com/garretpremo/angular-19-test.git
cd angular-19-test
npm i
npm exec jest

Manual Reproduction Steps:

1. Create a new Angular project with @angular/cli v19.0.6

npm install -g @angular/[email protected]
ng new --standalone --skip-git --style=css --ssr=false

2. Install jest

npm install jest @types/jest jest-preset-angular --save-dev

3. Add Jest configuration to project root

// jest.config.json
{
    "preset": "jest-preset-angular",
    "setupFilesAfterEnv": ["<rootDir>/setup-jest.ts"],
    "transformIgnorePatterns": [
        "node_modules/(?!(.*\\.mjs$)|set-utilities)"
    ]
}
// setup-jest.ts
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';

setupZoneTestEnv();
// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [ "jest" ]
  },
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

4. Run tests (should run successfully)

npm exec jest

5. Introduce a basic ESM library, e.g. set-utilities

npm install set-utilities

6. Use the library

export class AppComponent {
  title = 'angular-19-test';

  mySet = union(new Set([1,2,3]), new Set([4,5,6]));
}

7. Run tests (Should fail)

npm exec jest

Expected behavior

Should be able to parse and transform ESM files with a .js extension

Actual behavior

Jest fails to parse ESM files with a .js extension.

Console Output:

$ npm exec jest
 FAIL  src/app/app.component.spec.ts
  ● Test suite failed to run
                  
    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
    
    ...
Details:

    C:\Users\...\angular-19-test\node_modules\set-utilities\dist\index.js:2
    export { disjoint } from './comparisons/disjoint.function.js';
    ^^^^^^

    SyntaxError: Unexpected token 'export'
      1 | import { Component } from '@angular/core';
      2 | import { RouterOutlet } from '@angular/router';
    > 3 | import { union } from 'set-utilities';
        | ^
    ...

Additional context

Manually changing the file names of the set-utilities library from .js -> .mjs resolves the issue.

Environment

System:
    OS: Windows 11 10.0.22631
    CPU: (24) x64 AMD Ryzen 9 5900X 12-Core Processor            
  Binaries:
    Node: 20.13.1 - ~\scoop\apps\nodejs-lts\current\node.EXE
    Yarn: 1.22.21 - ~\scoop\apps\nodejs-lts\current\bin\yarn.CMD
    npm: 10.1.0 - ~\scoop\apps\nodejs-lts\current\bin\npm.CMD
    pnpm: 9.6.0 - ~\scoop\apps\nodejs-lts\current\bin\pnpm.CMD
    bun: 1.1.29 - ~\.bun\bin\bun.EXE
  npmPackages:
    jest: ^29.7.0 => 29.7.0
@ahnpnl
Copy link
Collaborator

ahnpnl commented Jan 3, 2025

It seems like there is an issue when using isolatedModules: false. Switching to use isolatedModules: true should help

Workaround is you do this

// jest.config.ts
import presets from 'jest-preset-angular/presets'

export default {
  ...presets.createCjsPreset({
    isolatedModules: true,
  }),
  "setupFilesAfterEnv": ["<rootDir>/setup-jest.ts"],
  "transformIgnorePatterns": [
    "node_modules/(?!(.*\\.mjs$)|set-utilities)"
  ],
}

@richardsengers
Copy link

Is this the same bug I'm getting when including this library?
https://www.npmjs.com/package/@material/material-color-utilities

The library consists of ts and js files and the test fails on the js files

 C:\sources\ItZHMW\Web\node_modules\.pnpm\@[email protected]\node_modules\@material\material-color-utilities\index.js:17
    export * from './blend/blend.js';
    ^^^^^^
    SyntaxError: Unexpected token 'export'

The index.js file looks like this
image

I've tried the above example on how to fix it but without any luck. This is my jest.config.ts
Some help would really be appreciated

import presets from 'jest-preset-angular/presets';

export default {
  ...presets.createCjsPreset({
    isolatedModules: true,
  }),
  displayName: 'shared-util',
  preset: '../../../jest.preset.js',
  coverageDirectory: '../../../coverage/libs/shared/util',
  transform: {
    '^.+\\.(ts|mjs|js|html|svg|txt)$': [
      'jest-preset-angular',
      {
        tsconfig: '<rootDir>/tsconfig.spec.json',
        stringifyContentPathRegex: '\\.(html|svg|txt)$',
      },
    ],
  },
  transformIgnorePatterns: ['node_modules/(?!.*.mjs$|.pnpm|@jsverse/)', 'node_modules/(?!(.*\\.mjs$)|@material/material-color-utilities)'],
  moduleNameMapper: {
    '^flat': 'node_modules/flat/index.js',
  },
  snapshotSerializers: [
    'jest-preset-angular/build/serializers/no-ng-attributes',
    'jest-preset-angular/build/serializers/ng-snapshot',
    'jest-preset-angular/build/serializers/html-comment',
  ],
  moduleFileExtensions: ['ts', 'js', 'html', 'svg', 'txt'],
};

@briancodes
Copy link

@richardsengers Have you tried different transformIgnorePatterns e.g different combinations of @material and material-color-utilities, in case it's not being matched

@richardsengers
Copy link

@briancodes yes I've tried a lot of different transform patterns. IN the end I've ended up with

moduleNameMapper: { '^flat': 'node_modules/flat/index.js', '@material/material-color-utilities': '@material/material-color-utilities/index.js' },
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],

This seems to work, but to be honest, I don't know why this works ans all the other options gave an error

@jpvanhal
Copy link

jpvanhal commented Feb 3, 2025

I bumped into this issue when attempting to update TypeScript from 5.5.4 to 5.7.3. I was able to bisect that the first TypeScript release that has this problem is 5.6.0-dev.20240801.

@lppedd
Copy link

lppedd commented Feb 13, 2025

but to be honest, I don't know why this works

This to me is crazy. I myself have applied fixes without understanding them.
A year down the line, or the first couple of updates, and we'll be here again lol.

There must be a better way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants