ts-node/ts-jest won't allow me to import

178 views Asked by At

I'm encountering a syntax error when integrating mdast-util-from-markdown in my Jest tests for a TypeScript project. Looking for a solution that avoids using Babel.

My code runs fine using ts-node.

Problem:

When I run my Jest tests, I receive the following error:

Details:

/Users/dudeman/ac/_utils/md-hierarchical-parser/node_modules/mdast-util-from-markdown/index.js:2
export {fromMarkdown} from './lib/index.js'
^^^^^^

SyntaxError: Unexpected token 'export'

> 1 | import { fromMarkdown } from "mdast-util-from-markdown";

Current setup

Config:

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs", // Also tried "esnext"
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": [
    "src/**/*",
    "test/**/*"
  ]
}

jest.config.cjs (also tried jest.config.js)

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  globals: {
    'ts-jest': {
      useESM: true
    }
  },
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1'
  },
  transform: {
    '^.+\\.ts$': 'ts-jest'
  },
  extensionsToTreatAsEsm: ['.ts']
};

Runner

npx jest

NODE_OPTIONS='--loader ts-node/esm' npc jest

Tried

  • Modifying my tsconfig.json to use different module settings (e.g., "esnext", "commonjs")
  • Modifying jest.config.js to
    • handle ES module syntax,
    • transformIgnorePatterns: ['<rootDir>/node_modules/(?!unist-util-visit)'],
  • I also used babel (even though I'd prefer to not), and I still get the error :/

Question:

How can I configure Jest and TypeScript to work with mdast-util-from-markdown without encountering the 'Unexpected token' error, and preferably without introducing Babel into my setup?

Edit:

Seems to work with

tsconfig.json

{
  "compilerOptions": {
    "strict": true,
    "target": "ES2022",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": ["esnext"],
    "types": ["node", "jest"],
    "skipLibCheck": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true
  },
  "ts-node": {
    "experimentalSpecifierResolution": "node",
    "transpileOnly": true,
    "esm": true,
  },
  "exclude": ["node_modules", "lib"]
}

jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  transform: {
    '^.+\\.{ts|tsx}?$': ['ts-jest', {
      useESM: true
    }],
  },
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1'
  },
  extensionsToTreatAsEsm: ['.ts']
};

package.json

  "type": "module",
  "dependencies": {},
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^6.13.1",
    "@typescript-eslint/parser": "^6.13.1",
    "@types/jest": "29.5.10",
    "eslint": "^8.55.0",
    "jest": "29.7.0",
    "ts-jest": "29.1.1",
    "ts-node": "^10.9.1",
    "typescript": "^5.2.2"
  }

jest --env=node --colors --coverage test

1

There are 1 answers

0
Masterpage On

react-markdown comes with a ton of dependencies you have to ignore by jest config:

// jest.config.js

const config = {
  transformIgnorePatterns: [
    '[/\\\\]node_modules[/\\\\](?!(bail|ccount|character-entities|comma-separated-tokens|decode-named-*|escape-string-regexp|hast-util-*|is-plain-obj|markdown*|mdast-util-*|micromark*|property-information|react-markdown|remark-*|space-separated-*|trim-lines|trough|unified*|unist-util-*|vfile))',
  ],
};