简体   繁体   中英

How can I run Jest tests with an imported library that is made available in es2015 modules? (Jest encountered unexpected token error)

I have two npm packages. I provide direct links to the repos, but also the relevant code snippets and descriptions below.

Here is the summary of the question and what is detailed further below

  • Project 1 uses TypeScript option "module": "es2015" to compile it's code
  • Project 2 has project 1 as a dependency. This project has one test file, which tests an object which makes a call to code from the imported project 1.
  • Jest gives an error when we run this project 2 test. The error basically says that there is an error in the code of the imported library.
  • When in project 1 I change the TypeScript option to something else, or omit it, the compiled code is of course not es2015 , but the project 2 test works.
  • How can I make it so that the Jest test works with the es2015 option in the imported library?

Here are the details

Here is a very simple TypeScript npm module, let's call it project 1. It has one index.ts file that exports an object with one method in it. I executed yarn tsc to generate an index.js file in a ./lib folder, with an auto-generated declaration file index.d.ts . I've gitignored the src/index.ts , so the repo only shows the lib folder that would be available were this repo to be published as an npm module in the npm registry.

These are the relevant files:

// tsconfig.js
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "sourceMap": false,
    "target": "es5",
    "module": "es2015",
    "skipLibCheck": true,
    "strict": true,
    "resolveJsonModule": true,
    "outDir": "./lib",
    "declaration": true
  },
  "exclude": ["node_modules", "lib"]
}
// package.json
{
  "name": "TypedNpmModule",
  "version": "1.0.0",
  "description": "",
  "main": "./lib/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tsc": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "prettier": "^1.17.0",
    "typescript": "^3.4.5"
  }
}
// src/index.ts
export const myObject = {
  method1: function(str: string) {
    return str;
  }
};

The TypeScript generated .js file is

export var myObject = {
  method1: function(str) {
    return str;
  },
};

Here is a very simple TypeScript npm module, let's call it project 2, that imports project 1. It has an index.ts exports an actions object that has a method that just calls the method that we get from the object exported in project 1:

// src/index.ts
import { myObject } from 'TypedNpmModule';

export const actions = {
  meth1: myObject.method1('hello'),
};

This project uses Jest to test calling this actions object:

// src/__tests__/index.test.js
import { actions } from '../index';

test('actions', () => {
  const result = actions.meth1('hello');
  expect(result).toMatchSnapshot();
});
// package.json
{
  "name": "Jest1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/jest": "^24.0.12",
    "jest": "^24.7.1",
    "prettier": "^1.17.0",
    "ts-jest": "^24.0.2",
    "typescript": "^3.4.5"
  },
  "dependencies": {
    "TypedNpmModule": "evian-pring/TypedNpmModule#master"
  },
  "jest": {
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    }
  }
}

This is where the problem is

When I run the Jest tests, using npx jest , I get an error:

在此输入图像描述

The issue was that Jest by default ignores all files in node_modules . Therefore, no transformations are applied to any external libraries. I read in this other thread that ts-jest requires files to use commonjs , and since project1 's files are using ES6 native modules, we get an error.

Solution:

  • In project 2 , tell Jest to not ignore project1 package. This is done in the Jest config, under key transformIgnorePatterns . Read more about that here
  • In project 2 , install babel correctly: besides babel-jest we also need @babel/core and @babel/preset-core . yarn add --dev @babel/core @babel/preset/core babel-jest
  • I think this is also a requirement since Babel 7: use a babel.config.js file not a .babelrc file. Here is why. This is what the one for project2 looks like
module.exports = function(api) {
  api.cache(true);

  const presets = ["@babel/env"];

  return {
    presets
  };
};

See also the repos linked in the question for the working code.

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