chaijs / chai

BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
https://chaijs.github.io
MIT License
8.11k stars 694 forks source link

@types/chai seems not to be adapted to version 5.0.0 #1578

Open dhjnam opened 7 months ago

dhjnam commented 7 months ago

import chai from 'chai' does not work with chai version 5.0.0.

// test.spec.ts
import chai from 'chai';
chai

and executing

ts-mocha ./test.spec.ts"

Raises the following error

Error [ERR_REQUIRE_ESM]: require() of ES Module <project-root>/node_modules/chai/chai.js from <project-root>/test.spec.ts not supported.
Instead change the require of chai.js in <project-root>/test.spec.ts to a dynamic import() which is available in all CommonJS modules.

at Object.<anonymous> (<project-root>/test.spec.ts:6:32)
at m._compile (<project-root>/node_modules/ts-mocha/node_modules/ts-node/dist/index.js:327:29)
at require.extensions.<computed> [as .ts] (<project-root>/node_modules/ts-mocha/node_modules/ts-node/dist/index.js:329:16)
at <project-root>/node_modules/mocha/lib/mocha.js:414:36
at Array.forEach (<anonymous>)
at Mocha.loadFiles (<project-root>/node_modules/mocha/lib/mocha.js:411:14)
at Mocha.run (<project-root>/node_modules/mocha/lib/mocha.js:972:10)
at Object.run (<project-root>/node_modules/mocha/lib/cli/watch-run.js:263:22)
at FSWatcher.<anonymous> (<project-root>/node_modules/mocha/lib/cli/watch-run.js:184:14)

Other imports work fine.

tsconfig.json:

{
  "compilerOptions": {
    "composite": true,
    "target": "ES6",
    "module": "Node16",
    "rootDir": "./",
    "moduleResolution": "Node16",
    "typeRoots": [
      "./node_modules/@types/",
    ],
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,                
    "outDir": "./dist/",
    "declarationDir": "./dist/@types",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
  },
}

package.json:

{
  "name": "chai5",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "ts-mocha test.spec.ts"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/chai": "^4.3.11",
    "@types/mocha": "^10.0.6",
    "chai": "^5.0.0",
    "mocha": "^10.2.0",
    "ts-mocha": "^10.0.0",
    "typescript": "^5.3.3"
  }
}
43081j commented 7 months ago

This is because the project is esm only now.

As the error message says, you would have to use a dynamic import to import it since you're in a commonjs project.

Your package.json doesn't have type: "module", so typescript (with node16/nodenext resolution) will detect your project as commonjs and parse it as such.

I have an example here: https://gist.github.com/43081j/78ce1392abb5043b02a29355006880a5

if you're unable to make your project ESM-only, you will have to use a dynamic import (const chai = await import('chai')), or stick to 4.x until you're able to migrate forward.

We're still publishing 4.x versions for security etc.

rufreakde commented 7 months ago

With mocha I did someting like so:

const chaiHttp = require("chai-http");
let chai;
before(async () => {
  await import("chai").then((result) => {
    chai = result;
    // Configure chai
    chai.use(chaiHttp);
    chai.should();
  });
});

issue is that somehow chai.request is failing...

TypeError: chai.request is not a function

is chai-http 4.4.0 not compatible with chai 5.x?

rufreakde commented 7 months ago

Okay it seems with the new version the use functionality is broken... https://github.com/chaijs/chai/issues/1569 interesting

43081j commented 7 months ago

for now (maybe permanently, depending on the outcome of 1569), you can do:

await import("chai").then((result) =>
  chai = result.use(chaiHttp);
});
caiosantos10 commented 5 months ago

You can try import just methods from 'chai' like this:

import { use, expect } from 'chai'; import chaiHttp from 'chai-http'; const chai = use(chaiHttp);

melroyvandenberg commented 4 months ago

I can't take it anymore with Chai + Cha-http with ESM (even when not using TS, but just JS).

It just impossible to import those two libs. I get SyntaxError: The requested module 'chai' does not provide an export named 'request' and if I use import * as chai from 'chai to allow me to use chai.request I now get: TypeError: chai.request is not a function

caiosantos10 commented 4 months ago

I can't take it anymore with Chai + Cha-http with ESM (even when not using TS, but just JS).

It just impossible to import those two libs. I get SyntaxError: The requested module 'chai' does not provide an export named 'request' and if I use import * as chai from 'chai to allow me to use chai.request I now get: TypeError: chai.request is not a function

You can try this way:

import chaiHttp from 'chai-http'; const chai = use(chaiHttp);

and then call:

chai.request()

melroyvandenberg commented 4 months ago

Ow so use returns a new object?.. interesting! Thanks. I still believe chai should improve this ESM import / usage.

43081j commented 4 months ago

yes, use returns an extended chai

import {use} from 'chai';
import chaiHttp from 'chai-http';

const chai = use(chaiHttp);

we have an issue open to investigate if there's any way we can improve this pattern