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

Viewed 8459

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?

3 Answers

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

{
  "compilerOptions": {
    "module": "es2022",
    "moduleResolution": "Node"
  },
  ...
}
  • https://codingwithmanny.medium.com/quick-jest-setup-with-vitejs-react-typescript-82f325e4323f
  • refer the above link for setting up Jest in your Vite project.
  • install this plugin (https://www.npmjs.com/package/vite-plugin-environment)
  • create .env file in your project root folder near package.json
  • provide your env variables in .env files
  • change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR
  • open vite.config.ts and import import EnvironmentPlugin from 'vite-plugin-environment';
  • add EnvironmentPlugin('all') in plugins. example: plugins: [react(), EnvironmentPlugin('all')]
  • now your test will pass without import.meta.env error.
  • the explanation behind this config is that Jest will understand process.env.YOUR_VAR, so if you change all your import.meta.env.YOUR_VAR to process.env.YOUR_VAR then Jest will not give error.
  • But then we have to provide vite-plugin-environment to Vite Config so that it understands process.env.YOUR_VAR
  • it works in production as well.

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',
      }
    };

Related