Cannot use import statement outside a module - jest + nextj.js

89 Views Asked by At

Running jest test I faced following issue:

` SyntaxError: Cannot use import statement outside a module

      30 |   certificateEuropean: '/icons/certificate-european.svg',
      31 |   check: '/icons/check.svg',
    > 32 |   checkGold: '/icons/check-gold.svg',

`

This is the test:

` import React from 'react'; import { render } from '@testing-library/react';

import { Icon } from '@/components/UI/Icon';

describe('RegistrationForm', () => {
  test('should update and retrieve values correctly', () => {
    render(<Icon type="accreditation" />);
  });
});

`

This is the component:

` const iconMap = { accreditation: '/icons/accreditation.svg', . . }

export const getIconSrc = (type: IconType): string => iconMap[type];

export const Icon = React.forwardRef<HTMLImageElement, IconProps>(
  ({ type, size, width, alt = '', id, quantity }, ref) => {
    const _size = size ?? 24;
    const _width = width ?? _size;
    const iconSrc = getIconSrc(type);

    return (
      <>
        <img
          data-testid={id}
          className="h-full"
          ref={ref}
          src={iconSrc}
          width={_width}
          height={_size}
          alt={alt}
        />
        {typeof quantity === 'number' && quantity > 0 ? (
          <span>
            {quantity}
          </span>
        ) : null}
      </>
    );
  }
);
Icon.displayName = 'Icon';

`

and this is my jest.config.js

` // jest.config.js const nextJest = require('next/jest');

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test           environment
  dir: './',
});

const customJestConfig = {

  moduleDirectories: ['node_modules', '<rootDir>/'],


  moduleNameMapper: {
    '@/(.*)$': '<rootDir>/src/$1',
    '@@/(.*)$': '<rootDir>/$1',
    '\\.(ttf|otf|eot|svg)$': '<rootDir>/__mocks__/fontMock.js',
  },
  testEnvironment: 'jsdom',
  setupFiles: ['./text-encoder.mock.ts'],
  setupFilesAfterEnv: ['@testing-library/jest-dom'],
};

module.exports = createJestConfig(customJestConfig);`

I tried adding following fields to jest.config.js `
preset: 'ts-jest', testEnvironment: //every possible option transform: { '^.+\.tsx?$': 'ts-jest', }, transformIgnorePatterns: ['/node_modules/'],

globals: {
  "ts-jest": {
    isolatedModules: true,
  },
},`

in package.json

"type": "module",your text run node --experimental-vm-modules node_modules/jest/bin/jest.js instead of npm test result: Must use import to load ES Module: C:\Users\USERNAME\frontend\node_modules\@sitecore-feaas\clientside\dist\browser\react.esm.js

2

There are 2 best solutions below

0
Alex Baumgertner On

It seems like something wrong with @sitecore-feaas package.json — when I deleted "exports" field in @sitecore-feaas/package.json and did the same with @sitecore/byoc it started working.

I created a jest settings workaround:

jest.config.ts:

  globalSetup: '<rootDir>/jest/sitecoreLibsExportFixing.ts',
  globalTeardown: '<rootDir>/jest/sitecoreLibsExportFixingRestore.ts',

sitecoreLibsWithWrongExport.ts:

export const sitecoreLibsWithWrongExport = ['@sitecore/byoc', '@sitecore-feaas/clientside'];

sitecoreLibsExportFixing.ts:

import fs from 'fs';
import { sitecoreLibsWithWrongExport } from './sitecoreLibsWithWrongExport';

const sitecoreLibsExportFixing = (libsToPatch: string[]) => {
  libsToPatch.forEach((lib) => {
    const packageFilePath = `node_modules/${lib}/package.json`;
    const backupFilePath = `node_modules/${lib}/package.backup.json`;

    // Store a backup
    fs.copyFileSync(packageFilePath, backupFilePath);

    // Read the file
    const rawData = fs.readFileSync(packageFilePath, 'utf-8');
    const packageData = JSON.parse(rawData);

    // Remove the 'exports' property
    if (packageData.exports) {
      delete packageData.exports;

      // Write the updated content back to the file
      const updatedData = JSON.stringify(packageData, null, 2);
      fs.writeFileSync(packageFilePath, updatedData);
    }
  });
};

export default () => sitecoreLibsExportFixing(sitecoreLibsWithWrongExport);

sitecoreLibsExportFixingRestore.ts:

import fs from 'fs';
import { sitecoreLibsWithWrongExport } from './sitecoreLibsWithWrongExport';

const sitecoreLibsExportFixingRestore = (libsToRestore: string[]) => {
  libsToRestore.forEach((lib) => {
    const packageFilePath = `node_modules/${lib}/package.json`;
    const backupFilePath = `node_modules/${lib}/package.backup.json`;

    // Restore the backup file
    if (fs.existsSync(backupFilePath)) {
      fs.copyFileSync(backupFilePath, packageFilePath);
    }
  });
};

export default () => sitecoreLibsExportFixingRestore(sitecoreLibsWithWrongExport);

0
Alex Baumgertner On

Here is the other solution: mock @sitecore-jss in your test. For example if your component uses RichText you can mock it like this:

jest.mock('@sitecore-jss/sitecore-jss-nextjs', () => ({
  RichText: (props) => {
    return props.field?.value;
  },
}));