47

When Jest.js encounters import.meta in the code, I get an error:

FAIL  testFile.test.ts
  ● Test suite failed to run

    testFile.ts:40:10 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'.

    40          return import.meta?.env as EnvironmentalVariablesType

I have installed the following babel related packages:

// package.json
    "devDependencies": {
        "@babel/core": "^7.16.5",
        "@babel/preset-env": "^7.16.5",
        "@babel/preset-typescript": "^7.16.5",
        "@vitejs/plugin-react-refresh": "1.3.6",
        "babel-jest": "^27.4.5",
        "jest": "27.3.1",
        "jest-environment-jsdom-global": "3.0.0",
        "react": "17.0.1",
        "ts-jest": "27.0.7",
        "typescript": "4.1.3",
        "vite": "2.6.14"
    "dependencies": {
        "babel-plugin-transform-vite-meta-env": "^1.0.3",
        "babel-preset-vite": "^1.0.4",

I've setup babel.config.js as follows:

module.exports = {
    plugins: [ 'babel-plugin-transform-vite-meta-env' ],
    presets: [
        [
            '@babel/preset-env',
            { targets: { node: 'current' } },
        ],
        [ '@babel/preset-typescript' ],
        [ 'babel-preset-vite' ],
    ],
}

and my vite.config.js:

import { defineConfig } from 'vite'
import reactRefresh from '@vitejs/plugin-react-refresh'
import replace from '@rollup/plugin-replace'

// https://vitejs.dev/config/
export default defineConfig( {
    base: '/time/',
    server: {
        port: 9000,
    },
    plugins: [
        reactRefresh(),
        replace( {
            'process.env.NODE_ENV': JSON.stringify( 'development' ),
            'process.env.SHOW_DEV_TOOLS': JSON.stringify( 'true' ),
        } ),
    ],
} )

Tried

  • set module in tsconfig.json to es2020, esnext, or system

None of these cleared or changed the terminal error.

Is there some misconfiguration above that is preventing Jest from properly running babel?

Sean D
  • 3,810
  • 11
  • 45
  • 90
  • I am sure you must have tried `NODE_OPTIONS=--experimental-vm-modules npx jest` as suggested in the Jest website, but did it work? I cannot make it work. I have a React + Typescript + Parcel setup and Jest is giving me big headaches with this problem. Also, for the fun of it, I tried to transpile the project with `tsc` (module esXXXX), change the suffixes to .mjs and try to run the tests again... nothing... rabbit hole getting deeper and deeper. – Johnny Dec 23 '21 at 11:21
  • For me going to this post and using nstanard's solution solves the issue better than any of the finnicky non-solutions I've found elsewhere: https://stackoverflow.com/questions/72128718/test-suite-failed-to-run-import-meta-env-vite – plutownium Feb 17 '23 at 17:52

4 Answers4

35

In tsconfig.json, try setting the compilerOptions as so:

{
  "compilerOptions": {
    "module": "es2022",
    "moduleResolution": "Node"
  },
  ...
}
Jenni
  • 414
  • 5
  • 6
  • 4
    This worked great for me and was a quick and simple solution. Thanks for this, been some rough times on a Vue project that uses TS. All these tooling advancements are supposed to make our lives as devs easier, right?! – twknab Mar 04 '22 at 00:15
  • 50
    This did not resolve it for me. I get the exact same error after making this change. – Dave Munger Sep 02 '22 at 15:51
  • For those who can't fix by these options, try `rm tsconfig.tsbuildinfo` and run again. It seems like the options can be cached and works for me after removing it. – foray1010 Feb 24 '23 at 19:47
  • 2
    @foray1010 - where is that file located? it's nowhere in my project – Nico Jun 26 '23 at 12:20
  • @Nico if you don't see it, you don't have it. That file is built by `tsc` in the output directory (when appropriate). [See TS Docs for more info.](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html) – Adam Leis Aug 11 '23 at 15:29
  • Then I get `SyntaxError: Cannot use import statement outside a module` in \dist\main.js:1 on line `import { NestFactory } from '@nestjs/core'` – Spixy Aug 11 '23 at 16:15
  • If using [Next.js](https://nextjs.org/), deleting the auto-generated folder `/.next` might help. This folder will be re-created with the next build. It caches things as well _(FYI see `/.next/cache`)_. – kca Sep 01 '23 at 10:31
9
  1. Install vite-plugin-environment plugin (https://www.npmjs.com/package/vite-plugin-environment)
  2. Create .env file in your project root folder near package.json
  3. provide your env variables in .env files
  4. change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR
  5. open vite.config.ts and list the vite-plugin-environment:
import EnvironmentPlugin from 'vite-plugin-environment';

...

plugins: [
  react(), 
  ...
  EnvironmentPlugin('all')
]

Jest will understand process.env.YOUR_VAR, so if you change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR your test will pass without import.meta.env error

This article helped me for setting up Jest in my Vite project.

Manu Artero
  • 9,238
  • 6
  • 58
  • 73
Rohan Tarai
  • 260
  • 4
  • 8
  • 5
    This does not answer what is the problem and why this is a solution you can recomment. Apart from that, to me this also sounds like terrible advice, installing unneeded depedencies just to solve some problem you dont want to understand :) – Pwnball May 27 '23 at 18:12
0

You can use the following command to run the test as per the jest documentation along with setting allowSyntheticDefaultImports to "true" in ts config file, these two changes solved the error for me.

 yarn NODE_OPTIONS=--experimental-vm-modules npx jest

or

npm NODE_OPTIONS=--experimental-vm-modules npx jest

Ensure you have the relevant modules installed as per this. This article, have proper ts, jest and babel config added. (I have shared my config files for anyone who comes across this error. This article came in pretty handy to know about initial set-up requirements.)

//tsconfig.json

    {
      "compilerOptions": {
      
        "target": "ES2020", /* Specify ECMAScript target version: '' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
        "module": "ES2020", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
        "allowJs": true, /* Allow javascript files to be compiled. */
        "allowSyntheticDefaultImports": true,
        "strict": true, /* Enable all strict type-checking options. */
 
        /* Module Resolution Options */
        "moduleResolution": "Node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
        "baseUrl": "src", /* Base directory to resolve non-absolute module names. */

        "types": [
          "jest"
        ], /* Type declaration files to be included in compilation. */
        "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
      },
      "include": [
        "src/**/*.ts",
        "./src/**/*.js"
      ],
      "exclude": [
        "node_modules"
      ],
    }

//babel.config.js
export default api => {
    const isTest = api.env('test');
    // You can use isTest to determine what presets and plugins to use.

    return {
        presets: [
            [
                '@babel/preset-env',
                '@babel/preset-typescript',
                {
                    'targets': {
                        'node': 'current',
                    },
                },

            ]
        ],
    };

};

    //jest.config.js 
    /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */

    export default {
      preset: 'ts-jest',
      testEnvironment: 'node',
      testTimeout: 20000, //to resolve timeout error
      roots: ['src'], 
      modulePaths: ['node_modules', '<rootDir>/src'],
      testPathIgnorePatterns: [
        '<rootDir>/node_modules/', "/__utils"
      ],
      moduleDirectories: [
       "src"
      ],
      transform: {
        "^.+\\.js?$": "babel-jest",
        "^.+\\.ts?$": "ts-jest"
      },
      transformIgnorePatterns: [""], // you can add any module that you do not want to transform, The first pattern will match (and therefore not transform) files inside /node_modules. 
      testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|tsx?)$",
      "transform": {
        "^.+\\.(t|j)s$": "ts-jest"
      },
      testEnvironment: "node",
      "moduleNameMapper": {
        "src/(.*)": "<rootDir>/src/$1"
      },
      globals: {
        "ts-jest": {
          "useESM": true
        }
      },
      extensionsToTreatAsEsm: ['.ts'],
      moduleNameMapper: {
        '^(\\.{1,2}/.*)\\.js$': '$1',
      }
    };
Marcellia
  • 204
  • 2
  • 9
-2

I switched from jest to vitest, which got rid of this error. No changes to the test code were necessary.

For reference, this is my vitest.config.js:

import { defineConfig } from 'vite';

export default defineConfig({
    test: {
        globals: true,
        environment: 'jsdom'
    }
});

Daniel Veihelmann
  • 1,275
  • 10
  • 13