I am experiencing import issues with ts-node/ts-jest and unable to import the necessary modules

I'm having trouble with a syntax error while trying to integrate mdast-util-from-markdown into my Jest tests for a TypeScript project. I am seeking a solution that does not involve using Babel.

The code functions properly when using ts-node.

Issue:

Running my Jest tests results in 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

Configuration:

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 attempted 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 Solutions

  • Adjusting module settings in tsconfig.json (e.g., changing to "esnext", "commonjs")
  • Modifying jest.config.js to
    • handle ES module syntax,
    • transformIgnorePatterns: ['<rootDir>/node_modules/(?!unist-util-visit)'],
  • Attempted using Babel, despite preferring not to, and still encountering the error :/

Question:

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

Edit:

Found success 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

Answer №1

react-markdown has a multitude of dependencies that need to be excluded in the Jest configuration:

// 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))',
  ],
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should I take to export a function from a React functional component in order to create a reusable library?

Currently, I am in the midst of developing a React component library and one of my components contains a function that I want to export. The purpose of the addParticle function is to enable users of the library to dynamically insert particles into a cont ...

Converting JSON to TypeScript with Angular Casting

I'm facing an issue detailed below. API: "Data": [ { "Id": 90110, "Name": "John", "Surname": "Doe", "Email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="472d282f2923282207202a262e2b ...

Angular can display text on hover based on the state shown in a <td> element

Working on an Angular 7 project, I have a <td> element where I display different colors to indicate the status of a task: Red - Indicates 'Delayed' Orange - Indicates 'In progress' Grey - Indicates 'Rejected' Cu ...

How can the panel within an accordion be enlarged or minimized?

Currently, I am implementing an accordion feature with the option to expand or collapse all panels using two buttons. My goal is to allow users to manage each panel within the accordion individually. However, I have encountered an issue that needs attenti ...

Creating Versatile Functions for HttpClient Wrapping

Scenario: In my set of services, I find myself repeatedly writing code for data calls which results in a lot of duplicated code. To streamline the process and reduce redundancy, I am looking to implement a wrapper function: All these functions essentiall ...

Control the transparency of the initial parent div that includes an *ngFor loop

I want to add opacity only to the first div which contains an icon and a heading in another nested div. The second div should remain fully visible (opacity: 1). Here is the HTML structure: <div class="row clearfix"> <div class="col-lg-3 col- ...

Pause for Progress - Angular 6

I'm looking for a solution to solve the following issue. I need to access a property that will store data from an http request. Therefore, I want to verify this property only after the transaction is completed. validateAuthorization(path: string): ...

Harness the power of TypeScript in a single test file with jest's expect.extend() method

This question is similar to Can you limit the scope of a TypeScript global type? but it presents a slightly different scenario that requires clarification (although an answer to this would be greatly appreciated as well). In my Jest setup, I am attempting ...

Exploring intricate JSON data in Angular 4 applications

Below is the json structure I have: [ { "section":{ "secName":"Module 1", "pages":[ { "pageName":"Page 1", "pageType":"brightcove", "pageData":[ { ...

Guide to swapping out embedded objects within a TypeScript data structure

I am in need of modifying a TypeScript object by conducting a key search. It is important to note that the key may be repeated within the object, so I must ensure it belongs to the correct branch before making modifications to the corresponding object. To ...

Importing components in real-time to generate static sites

My website has a dynamic page structure with each page having its unique content using various components. During the build process, I am statically pre-rendering the pages using Next.js' static site generation. To manage component population, I have ...

Alert: The route "/D:/original/22-02-2017/job2.html" specified in [react-router] does not correspond to any existing routes

I am currently working on a project using TypeScript with React. I'm utilizing webpack as a compiler, and my directory structure looks like this: d:/original/22-02-2017/ - In my web.config.js file, the entry point is set to ./src/index.tsx. All ...

Encountering a type discrepancy issue when attempting to send a message to the SQS queue

Encountering a type mismatch error while attempting to send a message to the SQS queue using the documentation found at https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_sqs_code_examples.html. I have provided package details and ...

Make sure to declare rest parameters first when using Typescript

I am dealing with a function that takes in multiple string arguments and one final argument of a complex type, which is called Expression. This particular code looks like this in JavaScript: function layerProp(...args) { const fields = args.slice(0, -1) ...

Creating a custom type for accepted arguments in a Typescript method

Below is the structure of a method I have: const a = function (...args: any[]) { console.log(args); } In this function, the type of args is any[]. I am looking to create a specific type for the array of arguments accepted by this method in Typescript. ...

Creating an interface that extends the Map object in TypeScript to maintain the order of keys

After learning that the normal object doesn't preserve key order in TypeScript, I was advised to use Map. Nevertheless, I'm struggling to figure out how to assign values once I've declared the interface. Take a look at my approach: Coding ...

Unveiling the types of an object's keys in Typescript

I am currently utilizing an object to store a variety of potential colors, as seen below. const cardColors = { primaryGradientColor: "", secondaryGradientColor: "", titleTextColor: "", borderColor: "&quo ...

Adding a total property at the row level in JavaScript

Here is a JavaScript array that I need help with: [{ Year:2000, Jan:1, Feb: }, {Year:2001, Jan:-1, Feb:0.34 }] I want to calculate the total of Jan and Feb for each entry in the existing array and add it as a new property. For example: [{ Year:2000, Ja ...

Check for a rapid return if the function ends up returning null in JavaScript

Is there a way to make this code more concise? const result = getResult(); if (!result) { return; } // Work with result I have several instances of this code in my project and I'm looking for a simpler solution like: const result = getResult() ...

Problem with Ionic 2 checkboxes in segment controls

I encountered an issue with my screen layout. The problem arises when I select checkboxes from the first segment (Man Segment) and move to the second segment (Woman Segment) to choose other checkboxes. Upon returning to the first segment, all my previous ...