This file is being treated as an ES module because it has a '.js' file extension
Asked Answered
A

2

27

I want to use jtest to do a unit test in the typescript (Node version v16.13.2) project. First I install the jtest "jest": "^27.5.1" and add jest.config.js file:

module.exports = {
    roots: [
        "<rootDir>/test"
    ],
    testRegex: 'test/(.+)\\.test\\.(jsx?|tsx?)$',
    transform: {
        "^.+\\.tsx?$": "ts-jest"
    },
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

Add the test entry:

import DeviceHandler from "@utils/data/DeviceHandler";

test('hello world test', () => {
    let deviceId = DeviceHandler.getDeviceId();
    expect(deviceId).toBe("xxxx");
});

But when I run the test command yarn test:

ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/Users/dolphin/source/reddwarf/frontend/js-wheel/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///Users/dolphin/source/reddwarf/frontend/js-wheel/jest.config.js:1:1
    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
    at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
    at async requireOrImportModule (/Users/dolphin/source/reddwarf/frontend/js-wheel/node_modules/jest-util/build/requireOrImportModule.js:65:32)
    at async readConfigFileAndSetRootDir (/Users/dolphin/source/reddwarf/frontend/js-wheel/node_modules/jest-config/build/readConfigFileAndSetRootDir.js:132:22)
    at async readConfig (/Users/dolphin/source/reddwarf/frontend/js-wheel/node_modules/jest-config/build/index.js:233:18)
    at async readConfigs (/Users/dolphin/source/reddwarf/frontend/js-wheel/node_modules/jest-config/build/index.js:420:26)
    at async runCLI (/Users/dolphin/source/reddwarf/frontend/js-wheel/node_modules/@jest/core/build/cli/index.js:132:59)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
(base) 

This is the DeviceHandler.ts content:

const DeviceHandler = {
    getDeviceId: async() : Promise<string> => {
        return new Promise((resolve, reject) => {
            resolve("xxxx");
        });
    },
    getDeviceIdEnhance: async (): Promise<string> => {
        return new Promise((resolve, reject) => {
            // Initialize an agent at application startup.
            const fpPromise = require('@fingerprintjs/fingerprintjs').load();
            // Get the visitor identifier when you need it.
            fpPromise
                .then((fp: { get: () => any; }) => fp.get())
                .then(async (result: { visitorId: any; }) => {
                    // This is the visitor identifier:
                    const deviceId = result.visitorId;
                    resolve(deviceId);
                });
        });
    }
};

export default DeviceHandler;

Why did this error happen? what should I do to make the unit test work?

Ammonify answered 2/3, 2022 at 11:15 Comment(0)
S
61

You probably have "type": "module" in your package.json file. If you remove that it will fix this.

Alternatively, if you want to keep your "type": "module" you could convert your jest.config.js to be jest.config.json (and/or if you have a babel.config.js you will need to convert that one to be babel.config.json as well). Note that you will actually have to convert it to be in JSON format (so, remove module.exports = from it, etc).

This example project goes way more in depth on all this

Seminole answered 4/3, 2022 at 1:18 Comment(1)
this is very helpful! Thanks. You can also use module.exports = in jest and babel config files by rename them to jest.config.cjs and babel.config.cjs.Pulido
W
3

I ran into this error today and wanted to keep my library as "type": "module" in my package.json so I changed my jest.config.js to jest.config.json as cmcculloh suggests. I had to make changes to the file to accommodate the change.

jest.config.js:

/* eslint-disable */
module.exports = {
  displayName: '@company/admin-lib',
  preset: '../../../jest.preset.js',
  transform: {
    '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
    '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }],
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
  coverageDirectory: '../../../coverage/packages/@company/admin-lib',
};

The equivalent jest.config.json would be:

{
  "displayName": "@company/admin-lib",
  "preset": "../../../jest.preset.js",
  "transform": {
    "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest",
    "^.+\\.[tj]sx?$": ["babel-jest", { "presets": ["@nx/react/babel"] }]
  },
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx"],
  "coverageDirectory": "../../../coverage/packages/@company/admin-lib"
}
Watchful answered 13/1 at 21:22 Comment(1)
What if you don't use babel?Aleshia

© 2022 - 2024 — McMap. All rights reserved.