简体   繁体   中英

Jest: SyntaxError: Cannot use import statement outside a module in React/Typescript project

I am having an issue with Jest when it comes to testing certain components using Babel, Typescript, React, and Jest.

While testing a React/Typescript component I get SyntaxError: Cannot use import statement outside a module .

Things I have tried :

  1. Using plugins for babel (see babel config below)
  2. Using ts-jest
  3. Tried ts-jest ESM Support from docs
  4. Read this , this , and this post that had similar issues

Here is the jest.config.js :

const ignores = ['/node_modules/'];

module.exports = {
    preset: 'ts-jest',
    roots: ['<rootDir>'],
    modulePaths: [
        "<rootDir>/src"
    ],
    moduleDirectories: [
        "node_modules",
    ],
    transformIgnorePatterns: [...ignores],
    transform: {
        '^.+\\.(ts|tsx)?$': 'ts-jest',
        '^.+\\.(gif|svg|ico)$': '<rootDir>/svgTransform.js',
    },
    testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.js?$',
    moduleFileExtensions: ['tsx', 'js', 'ts'],
    moduleNameMapper: {
        "\\.(css|less|scss|sass)$": "identity-obj-proxy",
        '^(\\.{1,2}/.*)\\.js$': '$1',
      },
    clearMocks: true,
    // collectCoverage: true, // todo
    // coverageDirectory: "coverage",  // todo
    testEnvironment: 'jsdom',
    setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect', './src/tests/setup.js'],
    resolver: 'jest-webpack-resolver',
}

Here is the babel.config.js :

module.exports = {
    // For transformation of TSX and other react related bable plugins
    presets: [
        ['@babel/preset-env',  {
            targets: { esmodules: false, node: "current" }
         }],
        // Enabling Babel to understand TypeScript
        '@babel/preset-typescript', "@babel/preset-react"
    ],
    plugins: ['@babel/plugin-transform-modules-commonjs', '@babel/plugin-transform-runtime'],
}

Here is the Code-Trace of error:

代码跟踪

package.json :

{
    "name": "@unirep-social/frontend",
    "version": "1.0.0",
    "private": true,
    "scripts": {
        "start": "webpack-dev-server",
        "start-local": "webpack-dev-server",
        "build": "webpack",
        "lint": "prettier .",
        "build:worker": "webpack --config webpack.worker.js",
        "postinstall": "link-module-alias && yarn copyCircuits",
        "copyCircuits": "node scripts/copy_circuits",
        "test": "jest --config ./jest.config.js",
        "test:watch": "jest --watch",
        "test:coverage": "jest --coverage"
    },
    "_moduleAliases": {
        "worker_threads": "./externals/worker_threads.js"
    },
    "dependencies": {
        "@babel/plugin-transform-runtime": "^7.18.6",
        "@babel/preset-env": "^7.18.6",
        "@types/react": "^17.0.15",
        "@types/react-dom": "^17.0.9",
        "@unirep/circuits": "git+https://github.com/Unirep/circuits.git#alpha",
        "@unirep/crypto": "git+https://github.com/Unirep/crypto.git",
        "@unirep/unirep": "git+https://github.com/Unirep/unirep.git#alpha",
        "@unirep/unirep-social": "git+https://github.com/Unirep/unirep-social.git#alpha",
        "babel-preset-env": "^1.7.0",
        "bootstrap": "^5.0.2",
        "dateformat": "^4.5.1",
        "ethers": "^5.5.4",
        "identity-obj-proxy": "^3.0.0",
        "jest-environment-jsdom": "^28.1.2",
        "keyv": "4.1.1",
        "markdown-it": "^12.3.2",
        "mobx": "^6.4.2",
        "mobx-react-lite": "^3.3.0",
        "n-readlines": "^1.0.1",
        "nanoid": "^4.0.0",
        "node-sass": "^6.0.1",
        "react": "^17.0.2",
        "react-circular-progressbar": "^2.0.4",
        "react-dom": "^17.0.2",
        "react-favicon": "^1.0.0",
        "react-icons": "^4.2.0",
        "react-jdenticon": "^0.0.9",
        "react-router-dom": "^5.2.0",
        "react-router-hash-link": "^2.4.3",
        "snarkjs": "^0.3.59",
        "ts-jest": "^28.0.5"
    },
    "devDependencies": {
        "@babel/core": "^7.18.6",
        "@babel/plugin-transform-modules-commonjs": "^7.18.6",
        "@babel/preset-react": "^7.18.6",
        "@babel/preset-typescript": "^7.18.6",
        "@cloudflare/kv-asset-handler": "^0.2.0",
        "@testing-library/jest-dom": "^5.16.4",
        "@testing-library/react": "12.1.5",
        "@testing-library/user-event": "^14.2.1",
        "@types/jest": "^28.1.4",
        "@types/keyv": "^3.1.2",
        "@types/markdown-it": "^12.2.3",
        "@types/n-readlines": "^1.0.2",
        "@types/react-router-dom": "^5.1.8",
        "@types/shelljs": "^0.8.9",
        "assert": "^2.0.0",
        "babel-jest": "^28.1.2",
        "babel-loader": "^8.2.3",
        "buffer": "^6.0.3",
        "crypto-browserify": "^3.12.0",
        "css-loader": "^6.7.1",
        "css-minimizer-webpack-plugin": "^3.4.1",
        "file-loader": "^6.2.0",
        "html-webpack-plugin": "^5.5.0",
        "jest": "^28.1.2",
        "jest-axe": "^6.0.0",
        "jest-webpack-resolver": "^0.3.0",
        "link-module-alias": "^1.2.0",
        "mini-css-extract-plugin": "^2.6.0",
        "os-browserify": "^0.3.0",
        "prettier": "^2.6.0",
        "react-test-renderer": "^18.2.0",
        "sass": "^1.49.9",
        "sass-loader": "^12.6.0",
        "stream-browserify": "^3.0.0",
        "ts-loader": "^9.2.8",
        "typescript": "^4.3.5",
        "url-loader": "^4.1.1",
        "webpack": "^5.70.0",
        "webpack-cli": "^4.9.2",
        "webpack-dev-server": "^4.7.4"
    },
    "jestWebpackResolver": {
        "webpackConfig": "./webpack.config.js"
    },
    "prettier": {
        "tabWidth": 4,
        "singleQuote": true,
        "semi": false
    }
}

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')
// const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const webpack = require('webpack')

module.exports = {
    entry: ['./src/index.tsx'],
    mode: 'development',
    devServer: {
        port: 3000,
        // proxy: {
        //     '/api': {
        //         target: 'http://localhost:3000',
        //         router: () => 'http://localhost:3001',
        //     },
        // },
        historyApiFallback: true,
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        publicPath: '/',
    },
    resolve: {
        extensions: ['*', '.js', '.ts', '.tsx', '.json', '.scss'],
        fallback: {
            crypto: require.resolve('crypto-browserify'),
            assert: require.resolve('assert/'),
            stream: require.resolve('stream-browserify'),
            os: require.resolve('os-browserify/browser'),
            fs: false,
            dotenv: false,
        },
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-react'],
                        },
                    },
                    {
                        loader: 'ts-loader',
                    },
                ],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-react'],
                },
            },
            {
                test: /\.(png|jpg|gif|svg|ico)$/i,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            esModule: false,
                            limit: 8192,
                        },
                    },
                ],
            },
            {
                test: /\.s[ac]ss$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    // Translates CSS into CommonJS
                    'css-loader',
                    // Compiles Sass to CSS
                    'sass-loader',
                ],
            },
            {
                test: /\.(css)$/,
                // exclude: /node_modules/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    'css-loader',
                ],
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            filename: 'index.html',
            inlineSource: '.(js|css)',
        }),
        new MiniCssExtractPlugin({
            filename: 'styles.css',
        }),
        // new HtmlWebpackInlineSourcePlugin(),
        new webpack.DefinePlugin({
            'process.env': {},
            'process.argv': [],
            'process.versions': {},
            'process.versions.node': '"12"',
            process: {
                exit: '(() => {})',
                browser: true,
                versions: {},
                cwd: '(() => "")',
            },
        }),
        new webpack.ProvidePlugin({
            Buffer: path.resolve(__dirname, 'externals', 'buffer.js'),
        }),
        new webpack.ContextReplacementPlugin(/\/keyv\//, (data) => {
            delete data.dependencies[0].critical
            return data
        }),
        new webpack.ContextReplacementPlugin(/\/maci\-crypto\//, (data) => {
            delete data.dependencies[0].critical
            return data
        }),
    ],
    optimization: {
        // minimizer: [
        //   `...`,
        //   new CssMinimizerPlugin(),
        // ],
    },
}


What worked for me: Downgraded nanoid package to 3.3.4

nanoid包降级到 3.3.4

OP posted it as a comment but, he fixed it by downgrading the nanoid package from v4.0.0

I was facing the same issue and downgrading to the previous stable version 3.3.4 worked for me. Here is how I did it:

npm i nanoid@3.3.4

Thanks OP!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM