aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

SyntaxError: Cannot use import statement outside a module, using aws-amplify-react-native in a Jest environment #5479

Closed ThomasCarca closed 1 year ago

ThomasCarca commented 4 years ago

I am working on a react-native project with amplify to help me sign in users via Cognito. Everything has been ok so far but I've been stuck on the following issue the past days : When running tests, some fail unexpectedly with the following error : image

After doing some research, it seems a similar issue has already happened for the module "ui-react" (#5322, #5282) and a PR was merged recently #5324.

All in all, it seems to me that it has to do with the module not being transpiled from ES6 to ES5, but I have not dived in the code.

The app works fine and the issue happens when running tests on components importing withOAuth from amplify-js-react-native.

I also found this stackoverflow thread and tried the accepted answer. I added to my jest configuration the following line :

"transformIgnorePatterns": [
    "node_modules/(?!(react-native|aws-amplify-react-native)/)"
]

And got a new error : image

From there I am stuck...

Package.json ``` { "name": ..., "version": ..., "private": true, "scripts": { ... }, "dependencies": { "@react-native-community/async-storage": "^1.8.1", "@react-native-community/masked-view": "^0.1.7", "@react-native-community/netinfo": "^5.7.1", "@react-navigation/native": "^5.0.9", "@react-navigation/stack": "^5.1.1", "@reduxjs/toolkit": "^1.3.4", "@types/enzyme": "^3.10.5", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/i18n-js": "^3.0.1", "@types/react-navigation": "^3.4.0", "@types/react-redux": "^7.1.7", "@types/redux-mock-store": "^1.0.2", "amazon-cognito-identity-js": "^4.2.1", "appcenter": "3.0.0", "appcenter-analytics": "3.0.0", "appcenter-crashes": "3.0.0", "aws-amplify": "^3.0.8", "aws-amplify-react-native": "^4.0.4", "axios": "0.18.0", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "graphql": "^14.6.0", "graphql-request": "^1.8.2", "i18n-js": "^3.5.1", "moment": "^2.24.0", "normalizr": "^3.6.0", "react": "16.9.0", "react-dom": "^16.13.0", "react-native": "0.61.5", "react-native-animatable": "^1.3.3", "react-native-config": "^0.12.0", "react-native-flash-message": "^0.1.15", "react-native-gesture-handler": "^1.6.0", "react-native-linear-gradient": "^2.5.6", "react-native-localize": "^1.3.3", "react-native-logs": "^2.0.2", "react-native-material-menu": "^1.1.0", "react-native-reanimated": "^1.7.0", "react-native-safe-area-context": "^0.7.3", "react-native-screens": "^2.2.0", "react-native-splash-screen": "^3.2.0", "react-native-user-avatar": "^1.0.4", "react-native-webview": "^9.0.2", "react-redux": "^7.2.0", "redux": "^4.0.5", "redux-mock-store": "^1.5.4", "redux-observable": "^1.2.0", "redux-persist": "^6.0.0", "rxjs": "^6.5.4", "tslint": "^6.0.0", "tslint-config-prettier": "^1.18.0", "tslint-config-standard": "^9.0.0", "tslint-react": "^4.2.0" }, "devDependencies": { "@babel/core": "^7.6.2", "@babel/runtime": "^7.6.2", "@react-native-community/eslint-config": "^0.0.5", "@types/detox": "^14.5.2", "@types/jasmine": "^3.5.7", "@types/jest": "^25.1.3", "@types/react-native": "^0.60.25", "@types/react-native-material-menu": "^1.0.0", "@types/react-test-renderer": "16.9.1", "@typescript-eslint/eslint-plugin": "^2.24.0", "@typescript-eslint/parser": "^2.24.0", "babel-jest": "^24.9.0", "babel-plugin-module-resolver": "^4.0.0", "detox": "^15.4.2", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.0", "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-react": "^7.19.0", "jasmine-marbles": "^0.6.0", "jest": "^24.9.0", "jest-fetch-mock": "^3.0.2", "jest-sonar-reporter": "^2.0.0", "jest-transform-stub": "^2.0.0", "metro-react-native-babel-preset": "^0.56.0", "prettier": "^1.19.1", "react-native-version": "^4.0.0", "react-test-renderer": "16.9.0", "redux-devtools-extension": "^2.13.8", "sonar-scanner": "^3.1.0", "ts-jest": "^25.2.1", "typescript": "^3.7.3" }, "jest": { "collectCoverage": true, "coverageDirectory": "coverage", "preset": "react-native", "setupFiles": [ "./setup-tests.ts", "./node_modules/react-native-gesture-handler/jestSetup.js" ], "automock": false, "moduleFileExtensions": [ "ts", "tsx", "js", "jsx", "json", "node" ], "moduleNameMapper": { ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub", "^~store(.*)$": "/src/store$1" } } "test-runner": "jest" } } ```
Environment ``` System: OS: Linux 5.4 Manjaro Linux CPU: (8) x64 Intel(R) Core(TM) i7-8705G CPU @ 3.10GHz Memory: 3.76 GB / 15.37 GB Container: Yes Shell: 3.1.0 - /bin/fish Binaries: Node: 13.10.1 - /usr/bin/node Yarn: 1.22.0 - /usr/bin/yarn npm: 6.14.2 - /usr/bin/npm Watchman: 4.9.0 - /usr/bin/watchman Browsers: Firefox: 74.0 npmPackages: @babel/core: ^7.6.2 => 7.9.0 @babel/runtime: ^7.6.2 => 7.9.2 @react-native-community/async-storage: ^1.8.1 => 1.9.0 @react-native-community/eslint-config: ^0.0.5 => 0.0.5 @react-native-community/masked-view: ^0.1.7 => 0.1.9 @react-native-community/netinfo: ^5.7.1 => 5.7.1 @react-navigation/native: ^5.0.9 => 5.1.6 @react-navigation/stack: ^5.1.1 => 5.2.11 @reduxjs/toolkit: ^1.3.4 => 1.3.5 @types/detox: ^14.5.2 => 14.5.2 @types/enzyme: ^3.10.5 => 3.10.5 @types/enzyme-adapter-react-16: ^1.0.6 => 1.0.6 @types/i18n-js: ^3.0.1 => 3.0.2 @types/jasmine: ^3.5.7 => 3.5.10 @types/jest: ^25.1.3 => 25.2.1 @types/react-native: ^0.60.25 => 0.60.31 @types/react-native-material-menu: ^1.0.0 => 1.0.0 @types/react-navigation: ^3.4.0 => 3.4.0 @types/react-redux: ^7.1.7 => 7.1.7 @types/react-test-renderer: 16.9.1 => 16.9.1 @types/redux-mock-store: ^1.0.2 => 1.0.2 @typescript-eslint/eslint-plugin: ^2.24.0 => 2.29.0 @typescript-eslint/parser: ^2.24.0 => 2.29.0 amazon-cognito-identity-js: ^4.2.1 => 4.2.1 appcenter: 3.0.0 => 3.0.0 appcenter-analytics: 3.0.0 => 3.0.0 appcenter-crashes: 3.0.0 => 3.0.0 aws-amplify: ^3.0.8 => 3.0.8 aws-amplify-react-native: ^4.0.4 => 4.0.4 axios: 0.18.0 => 0.18.0 babel-jest: ^24.9.0 => 24.9.0 babel-plugin-module-resolver: ^4.0.0 => 4.0.0 detox: ^15.4.2 => 15.5.0 enzyme: ^3.11.0 => 3.11.0 enzyme-adapter-react-16: ^1.15.2 => 1.15.2 eslint: ^6.8.0 => 6.8.0 eslint-config-prettier: ^6.10.0 => 6.10.1 eslint-plugin-prettier: ^3.1.2 => 3.1.3 eslint-plugin-react: ^7.19.0 => 7.19.0 graphql: ^14.6.0 => 14.6.0 graphql-request: ^1.8.2 => 1.8.2 i18n-js: ^3.5.1 => 3.5.1 jasmine-marbles: ^0.6.0 => 0.6.0 jest: ^24.9.0 => 24.9.0 jest-fetch-mock: ^3.0.2 => 3.0.3 jest-sonar-reporter: ^2.0.0 => 2.0.0 jest-transform-stub: ^2.0.0 => 2.0.0 metro-react-native-babel-preset: ^0.56.0 => 0.56.4 moment: ^2.24.0 => 2.24.0 normalizr: ^3.6.0 => 3.6.0 prettier: ^1.19.1 => 1.19.1 react: 16.9.0 => 16.9.0 react-dom: ^16.13.0 => 16.13.1 react-native: 0.61.5 => 0.61.5 react-native-animatable: ^1.3.3 => 1.3.3 react-native-config: ^0.12.0 => 0.12.0 react-native-flash-message: ^0.1.15 => 0.1.15 react-native-gesture-handler: ^1.6.0 => 1.6.1 react-native-linear-gradient: ^2.5.6 => 2.5.6 react-native-localize: ^1.3.3 => 1.4.0 react-native-logs: ^2.0.2 => 2.1.2 react-native-material-menu: ^1.1.0 => 1.1.3 react-native-reanimated: ^1.7.0 => 1.8.0 react-native-safe-area-context: ^0.7.3 => 0.7.3 react-native-screens: ^2.2.0 => 2.5.0 react-native-splash-screen: ^3.2.0 => 3.2.0 react-native-user-avatar: ^1.0.4 => 1.0.4 react-native-version: ^4.0.0 => 4.0.0 react-native-webview: ^9.0.2 => 9.2.1 react-redux: ^7.2.0 => 7.2.0 react-test-renderer: 16.9.0 => 16.9.0 redux: ^4.0.5 => 4.0.5 redux-devtools-extension: ^2.13.8 => 2.13.8 redux-mock-store: ^1.5.4 => 1.5.4 redux-observable: ^1.2.0 => 1.2.0 redux-persist: ^6.0.0 => 6.0.0 rxjs: ^6.5.4 => 6.5.5 sonar-scanner: ^3.1.0 => 3.1.0 ts-jest: ^25.2.1 => 25.4.0 tslint: ^6.0.0 => 6.1.1 tslint-config-prettier: ^1.18.0 => 1.18.0 tslint-config-standard: ^9.0.0 => 9.0.0 tslint-react: ^4.2.0 => 4.2.0 typescript: ^3.7.3 => 3.8.3 npmGlobalPackages: @angular/cli: 9.0.0 @aws-amplify/cli: 4.18.0 @vue/cli: 4.2.2 cloudcms-cli: 1.1.126 create-react-app: 3.4.0 generator-jhipster-vuejs: 1.3.0 generator-jhipster: 6.5.1 jhipster: 0.0.2 node-gyp: 6.1.0 npm: 6.14.2 semver: 7.1.3 yarn: 1.22.0 yo: 3.1.1 ```

Thank you for your help !

amhinson commented 4 years ago

@ThomasCarca I'm looking into the 1st error you are seeing. But it also looks like that 2nd error message is for a different library (react-native-flash-message). Could you try adding that library to the transformIgnorePatterns list as well to see if that allows your tests to run?

ThomasCarca commented 4 years ago

Putting

    "transformIgnorePatterns": [
      "node_modules/(?!(react-native|aws-amplify-react-native)|react-native-flash-message/)"
    ]

yields the following error : image

Then

"transformIgnorePatterns": [
      "node_modules/(?!(react-native|aws-amplify-react-native|react-native-flash-message|react-native-iphone-x-helper)/)"
    ]

gives :
image

Looking at other files, I'm getting all kinds of errors of the same type : image image image

I doubt adding more dependencies to the transformIgnorePatterns array is the right solution.

amhinson commented 4 years ago

Can you post your babel and/or jest configuration as well?

ThomasCarca commented 4 years ago

babel.config.js :

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./src'],
        alias: {
          '~assets': './src/assets',
          '~components': './src/components',
          '~config': './src/config',
          '~constants': './src/constants',
          '~containers': './src/containers',
          '~mocks': './__mocks__',
          '~models': './src/models',
          '~store': './src/store',
          '~stubs': './__stubs__',
          '~utils': './src/utils',
        },
      },
    ],
  ],
};

Most of our jest configuration is directly in the package.json file : package.json :

...
"jest": {
    "collectCoverage": true,
    "coverageDirectory": "coverage",
    "preset": "react-native",
    "setupFiles": [
      "./setup-tests.ts",
      "./node_modules/react-native-gesture-handler/jestSetup.js"
    ],
    "automock": false,
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "moduleNameMapper": {
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
      "^~store(.*)$": "<rootDir>/src/store$1"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!(react-native|aws-amplify-react-native|react-native-flash-message|react-native-iphone-x-helper|@aws-sdk)/)"
    ]
  },
...

We're using a setup-tests.ts file to do some setup : setup-tests.ts :

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { enableFetchMocks } from 'jest-fetch-mock';
import L from '~utils/logger.util';
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock.js';

jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);

Enzyme.configure({ adapter: new Adapter() });
enableFetchMocks();

// Fixes unwanted warnings when running tests with jest-environment and Enzyme
// see issue : https://github.com/enzymejs/enzyme/issues/1436
console.error = (message: any) => message;

// Set the severity on error to not print logs when running test, unless the log
// is very important such as an error
L.setSeverity('error');
ThomasCarca commented 4 years ago

I have successfully resolved my issue this morning after semi-randomly tweaking the transformIgnorePatterns array.

The resulting array is the following :

"transformIgnorePatterns": [
      "node_modules/(?!(react-native|aws-amplify-react-native|@aws-sdk/eventstream-serde-browser|@react-native-community/masked-view))"
    ]

Please note I have removed the / character in the regexp, and it helped a lot : from

"transformIgnorePatterns": [
      "node_modules/(?!(...|...|...)/)"
    ]

... in my previous posts, to :

"transformIgnorePatterns": [
      "node_modules/(?!(...|...|...))"
    ]

Now, all tests pass successfully. I still think this is a hack and the problem should be addressed.

amhinson commented 4 years ago

Ok thanks for the update! It does look like the code isn't being transpiled (which doesn't cause any issues when running the app). I'll mark this as a feature request for now so we can come back around to it in the future.

madhu-sudhan-bhat commented 4 years ago

import React, { Component } from "react" [0] ^^^^^^ [0] [0] SyntaxError: Cannot use import statement outside a module

getting same error in react.js

tannerabread commented 1 year ago

Hi 👋 Closing this as resolved. This package is now deprecated. We recommend that you migrate to the new amplify UI library.

Thank you!