Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest with Angular 7 SyntaxError: Unexpected token { #277

Closed
ctfrancia opened this issue May 31, 2019 · 14 comments
Closed

Jest with Angular 7 SyntaxError: Unexpected token { #277

ctfrancia opened this issue May 31, 2019 · 14 comments

Comments

@ctfrancia
Copy link

I don't even know where to start with this one as I am not too familiar with testing and using this package for jest testing. I have about 27 fails and all have a variety of :

 FAIL  src/Components/chat/chat.component.spec.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/user/application/app/node_modules/@ionic/angular/dist/fesm5.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { __extends, __awaiter, __generator, __assign } from 'tslib';
                                                                                                    ^

    SyntaxError: Unexpected token {

      3 | import { MediaCapture, MediaFile, CaptureError, CaptureImageOptions } from '@ionic-native/media-capture';
      4 | //Schemas
    > 5 | import { Contact } from '../../Schemas/Contact';
        |                 ^
      6 | import { Message } from '../../Schemas/Message';
      7 | //Services
      8 | import { ChatService } from '../../app/Services/SocketIO/chat.service';

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
      at Object.<anonymous> (src/Components/chat/chat.component.ts:5:17)

I have seen posts regarding '<' but haven't encountered one with '{' I have no idea where to even start with this.

read this and this oh and can't forget this

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

tsconfig.spec.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "types": [
      "jest",
      "jasmine",
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

jest.config.js

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  moduleNameMapper: {
    '@app/(.*)': '<rootDir>/src/app/$1',
    '@assets/(.*)': '<rootDir>/src/assets/$1',
    '@core/(.*)': '<rootDir>/src/app/core/$1',
    '@env': '<rootDir>/src/environments/environment',
    '@src/(.*)': '<rootDir>/src/src/$1',
    '@state/(.*)': '<rootDir>/src/app/state/$1'
  },
  transformIgnorePatterns: ['node_modules/(?!(jest-test))']
};

@ctfrancia
Copy link
Author

been trying to follow this thread and here for the solutions however it is still failing with the same issue, I also now have the .babelrc file that was mentioned and have the preset installed.

@wtho
Copy link
Collaborator

wtho commented May 31, 2019

Can you also share your tsconfig.json? Which version of Angular are you using?

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

sure, I am using Angular 7, Ionic 4/Cordova

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

@wtho
Copy link
Collaborator

wtho commented May 31, 2019

The problem is, that jest runs inside node.js. node.js only allows commonjs-style imports of other files using require(...), not import.

Before passing your files to jest, ts-jest will transpile the Angular TypeScript files to javascript and put them in commonjs syntax, so jest can load them and test them without any problem.

Packages in node_modules are expected by jest to not be required to transform. But if you look at node_modules/@ionic/angular/dist/fesm5.js, you will see that this is not the issue for the ionic package. It uses es6-style imports.

The solution to your problem is this, as suggested by the initial Jest message:

To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

@wtho ok, thank you for your response. I will try and give that a try, again. I have tried so many things before wasting people's time here that I forgot all that I have tried. However, I tried to have all the node_modules be ignored but that didn't fix anything. Also,

• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.

so in order for it TO BE transformed you add it to the IGNORE patterns.... seems backwards no?

@wtho
Copy link
Collaborator

wtho commented May 31, 2019

The default configuration of the transformIgnorePatterns are set to [/node_modules/], as you can see in the official documentation. When using this preset, it will be set to ['node_modules/(?!@ngrx)'].

When overriding you will want to say "ignore everything in node_modules except @ionic". An example of this is shown in our documentation:
transformIgnorePatterns: ['node_modules/(?!@ionic)']

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

Thanks but it is still not transforming somethings, for example:


    /Users/user/Desktop/application/app/node_modules/@ionic/angular/dist/fesm5.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { __extends, __awaiter, __generator, __assign } from 'tslib';

The error above is also repeated for the ngx-socket-io (which I have aded to the IgnorePatterns but does't appear to have taken effect.

I have updated my config to:

  transformIgnorePatterns: [
    'node_modules/(?!@ionic)',
    'node_modules/(?!@ionic/angular)',,
    'node_modules/(?!ngx-socket-io)'
  ]

sorry for being dense, 😅. I have also been running $ jest --clearCache to make sure that it is running fresh

@wtho
Copy link
Collaborator

wtho commented May 31, 2019

This won't work:

  transformIgnorePatterns: [
    'node_modules/(?!@ionic)',
    'node_modules/(?!@ionic/angular)',,
    'node_modules/(?!ngx-socket-io)'
  ]

As stated in the docs:

If the test path matches any of the patterns, it will not be transformed.

Therefore node_modules/@ionic/angular/dist will match in /node_modules/(?!ngx-socket-io)/, and therefore be ignored. You can try this in any node repl or in online regex tools.

You have to put them all in one pattern, otherwise anything not matching the first ignore pattern will be matched in another one:
'node_modules/(?!@ionic)(?!ngx-socket-io)'

Yeah, running --clearCache is a good point. You can also run with --no-cache during the try-out phase.

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

still not working. I have been trying:

  • transformIgnorePatterns: ['node_modules/(?!@ionic/)']
  • transformIgnorePatterns: ['node_modules/(?!@ionic/).+\\.js$'] as recommended here
  • "node_modules/(?!(@ionic)/)"recommended here
  • "node_modules/(?!@ionic/)"
  • "node_modules/(?!@ionic)/"

I am trying to just ignore one file before I worry about two or three. I'm just trying the shotgun approach now because I am absolutely dumfounded by this.

@wtho
Copy link
Collaborator

wtho commented May 31, 2019

Ok, after that you are passing all of the js files to ts-jest:

  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },

ts-jest will use tsc with your tsconfig.spec.ts. To let js files transformed by ts-jest, you will have to add "allowJs": true to the compilerOptions, otherwise they will be left untouched, which is not what we want.

So try to add this to tsconfig.spec.ts and see if it works then.

@ctfrancia
Copy link
Author

I had the "allowJs": true in my package.json, but ot in the tsconfig.spec.ts file! klajsdfkhasdiuadsiufaisuyfasu alright, now on to multiple node modules! thanks a lot for your help!

@ctfrancia
Copy link
Author

ctfrancia commented May 31, 2019

how I have updated:

jest.config.js

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  moduleNameMapper: {
    '@app/(.*)': '<rootDir>/src/app/$1',
    '@assets/(.*)': '<rootDir>/src/assets/$1',
    '@core/(.*)': '<rootDir>/src/app/core/$1',
    '@env': '<rootDir>/src/environments/environment',
    '@src/(.*)': '<rootDir>/src/src/$1',
    '@state/(.*)': '<rootDir>/src/app/state/$1'
  },
  transformIgnorePatterns: [
    '/node_modules/(?!@ionic|ngx-socket-io/).+\\.js$'
  ]
};

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

ts.config.spec.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "allowJs": true,
    "types": [
      "jest",
      "jasmine",
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

hope this will save someone many hours!

@chat-du-cheshire
Copy link

Hi, there. After several hours of fighting with the same problem it successfully resolved with

transformIgnorePatterns: [ '/node_modules/(?!module1|module2/).+\\.js$' ]

Thanks @ctfrancia & @wtho

But be careful, you could encounter an error *.default is not a constructor. I've solved it by adding "esModuleInterop": true in tsconfig.spec.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants