6

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:

code-trace

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

7
  • You shouldn't need to use both Babel and TypeScript. Can you explain your webpack config (specifically whether you're using Babel or TypeScript)? Commented Jul 11, 2022 at 4:41
  • @NickMcCurdy Would you mind explaining why babel is not needed? Also, I just posted my webpack config file. Commented Jul 11, 2022 at 11:59
  • 1
    I meant that you don't need to use Babel together with TypeScript, because both can convert TypeScript to JavaScript. In this case, since you're building your webpack bundle with Babel, I'd recommend only using Babel with Jest. You can uninstall ts-jest, which should hopefully speed up and simplify your test setup. Commented Jul 11, 2022 at 18:01
  • 1
    @NickMcCurdy Yes, I mentioned that above. Commented Jul 11, 2022 at 23:04
  • 1
    Note: Fixed by downgrading nanoid package. Commented Jul 13, 2022 at 3:03

1 Answer 1

5

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 [email protected]

Thanks OP!

Sign up to request clarification or add additional context in comments.

3 Comments

Also, made an edit to the original post about downgrading nanoid stackoverflow.com/questions/72933087/…
Did not work for me, I'm on [email protected]! Same problem
@PeterStjernholmMeldgaard what node version do you have

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.