Skip to content

Commit 1def4cd

Browse files
authored
feat: drop support for jiti v1.21 (#18996)
* feat: drop support for jiti v1.21 * fix for CommonJS TS config that exports undefined
1 parent 7dd402d commit 1def4cd

File tree

4 files changed

+128
-8
lines changed

4 files changed

+128
-8
lines changed

docs/src/use/configure/configuration-files.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ npx eslint --flag unstable_ts_config
529529

530530
For more information about using feature flags, see [Feature Flags](../../flags/).
531531

532-
For Deno and Bun, TypeScript configuration files are natively supported; for Node.js, you must install the optional dev dependency [`jiti`](https://github.com/unjs/jiti) in your project (this dependency is not automatically installed by ESLint):
532+
For Deno and Bun, TypeScript configuration files are natively supported; for Node.js, you must install the optional dev dependency [`jiti`](https://github.com/unjs/jiti) in version 2.0.0 or later in your project (this dependency is not automatically installed by ESLint):
533533

534534
```bash
535535
npm install -D jiti

lib/config/config-loader.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -173,21 +173,22 @@ async function loadConfigFile(filePath, allowTS) {
173173
*/
174174
if (allowTS && isTS && !isDeno && !isBun) {
175175

176-
const createJiti = await import("jiti").then(jitiModule => (typeof jitiModule?.createJiti === "function" ? jitiModule.createJiti : jitiModule.default), () => {
176+
// eslint-disable-next-line no-use-before-define -- `ConfigLoader.loadJiti` can be overwritten for testing
177+
const { createJiti } = await ConfigLoader.loadJiti().catch(() => {
177178
throw new Error("The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.");
178179
});
179180

181+
// `createJiti` was added in jiti v2.
182+
if (typeof createJiti !== "function") {
183+
throw new Error("You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features.");
184+
}
185+
180186
/*
181187
* Disabling `moduleCache` allows us to reload a
182188
* config file when the last modified timestamp changes.
183189
*/
184190

185191
const jiti = createJiti(__filename, { moduleCache: false, interopDefault: false });
186-
187-
if (typeof jiti?.import !== "function") {
188-
throw new Error("You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features.");
189-
}
190-
191192
const config = await jiti.import(fileURL.href);
192193

193194
importedConfigFileModificationTime.set(filePath, mtime);
@@ -294,7 +295,6 @@ async function calculateConfigArray(configFilePath, basePath, options) {
294295
return configs;
295296
}
296297

297-
298298
//-----------------------------------------------------------------------------
299299
// Exports
300300
//-----------------------------------------------------------------------------
@@ -517,6 +517,15 @@ class ConfigLoader {
517517
return this.#configArrays.get(configFilePath);
518518
}
519519

520+
/**
521+
* Used to import the jiti dependency. This method is exposed internally for testing purposes.
522+
* @returns {Promise<Record<string, unknown>>} A promise that fulfills with a module object
523+
* or rejects with an error if jiti is not found.
524+
*/
525+
static loadJiti() {
526+
return import("jiti");
527+
}
528+
520529
}
521530

522531
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export = void 0;

tests/lib/eslint/eslint.js

+110
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,61 @@ describe("ESLint", () => {
13131313

13141314
});
13151315

1316+
it("should fail to load a TS config file if jiti is not installed", async () => {
1317+
1318+
const { ConfigLoader } = require("../../../lib/config/config-loader");
1319+
1320+
sinon.stub(ConfigLoader, "loadJiti").rejects();
1321+
1322+
const cwd = getFixturePath("ts-config-files", "ts");
1323+
1324+
eslint = new ESLint({
1325+
cwd,
1326+
flags: tsFlags
1327+
});
1328+
1329+
await assert.rejects(
1330+
eslint.lintText("foo();"),
1331+
{ message: "The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it." }
1332+
);
1333+
});
1334+
1335+
it("should fail to load a TS config file if an outdated version of jiti is installed", async () => {
1336+
1337+
const { ConfigLoader } = require("../../../lib/config/config-loader");
1338+
1339+
sinon.stub(ConfigLoader, "loadJiti").resolves({});
1340+
1341+
const cwd = getFixturePath("ts-config-files", "ts");
1342+
1343+
eslint = new ESLint({
1344+
cwd,
1345+
flags: tsFlags
1346+
});
1347+
1348+
await assert.rejects(
1349+
eslint.lintText("foo();"),
1350+
{ message: "You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features." }
1351+
);
1352+
});
1353+
1354+
it("should fail to load a CommonJS TS config file that exports undefined with a helpful error message", async () => {
1355+
1356+
const cwd = getFixturePath("ts-config-files", "ts");
1357+
1358+
eslint = new ESLint({
1359+
cwd,
1360+
flags: tsFlags,
1361+
overrideConfigFile: "eslint.undefined.config.ts"
1362+
});
1363+
1364+
await assert.rejects(
1365+
eslint.lintText("foo"),
1366+
{ message: "Config (unnamed): Unexpected undefined config at user-defined index 0." }
1367+
);
1368+
1369+
});
1370+
13161371
});
13171372

13181373
it("should pass BOM through processors", async () => {
@@ -5753,6 +5808,61 @@ describe("ESLint", () => {
57535808

57545809
});
57555810

5811+
it("should fail to load a TS config file if jiti is not installed", async () => {
5812+
5813+
const { ConfigLoader } = require("../../../lib/config/config-loader");
5814+
5815+
sinon.stub(ConfigLoader, "loadJiti").rejects();
5816+
5817+
const cwd = getFixturePath("ts-config-files", "ts");
5818+
5819+
eslint = new ESLint({
5820+
cwd,
5821+
flags: newFlags
5822+
});
5823+
5824+
await assert.rejects(
5825+
eslint.lintFiles("foo.js"),
5826+
{ message: "The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it." }
5827+
);
5828+
});
5829+
5830+
it("should fail to load a TS config file if an outdated version of jiti is installed", async () => {
5831+
5832+
const { ConfigLoader } = require("../../../lib/config/config-loader");
5833+
5834+
sinon.stub(ConfigLoader, "loadJiti").resolves({});
5835+
5836+
const cwd = getFixturePath("ts-config-files", "ts");
5837+
5838+
eslint = new ESLint({
5839+
cwd,
5840+
flags: newFlags
5841+
});
5842+
5843+
await assert.rejects(
5844+
eslint.lintFiles("foo.js"),
5845+
{ message: "You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features." }
5846+
);
5847+
});
5848+
5849+
it("should fail to load a CommonJS TS config file that exports undefined with a helpful error message", async () => {
5850+
5851+
const cwd = getFixturePath("ts-config-files", "ts");
5852+
5853+
eslint = new ESLint({
5854+
cwd,
5855+
flags: newFlags,
5856+
overrideConfigFile: "eslint.undefined.config.ts"
5857+
});
5858+
5859+
await assert.rejects(
5860+
eslint.lintFiles("foo.js"),
5861+
{ message: "Config (unnamed): Unexpected undefined config at user-defined index 0." }
5862+
);
5863+
5864+
});
5865+
57565866
});
57575867

57585868
it("should stop linting files if a rule crashes", async () => {

0 commit comments

Comments
 (0)