Skip to content

Commit ca7d40f

Browse files
authored
fix(eslint-plugin-fiori-tools): support ESLint 10 by upgrading @babel/eslint-parser to v8 (#4751)
* fix(eslint-plugin-fiori-tools): support ESLint 10 * fix comment
1 parent c58d70e commit ca7d40f

6 files changed

Lines changed: 378 additions & 34 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sap-ux/eslint-plugin-fiori-tools': minor
3+
---
4+
5+
fix: support ESLint 10 by upgrading `@babel/eslint-parser` and `@babel/core` to `8.0.0-rc.6` and adding `@babel/parser@8.0.0-rc.6` as a runtime dependency. This avoids `@babel/eslint-parser`'s `createRequire` failing to load `@babel/parser@8` (pure ESM) under pnpm's strict `node_modules` isolation, where `@babel/parser` is otherwise not visible from the consumer's resolution paths.

packages/eslint-plugin-fiori-tools/eslint.config.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ const __dirname = import.meta.dirname;
66

77
export default [
88
{
9-
ignores: ['config/**/eslintrc*.js', 'test/global-setup.js', 'jest.resolver.cjs']
9+
ignores: [
10+
'config/**/eslintrc*.js',
11+
'test/global-setup.js',
12+
'jest.resolver.cjs',
13+
'test/babel-eslint-parser.transformer.cjs'
14+
]
1015
},
1116
...base,
1217
{

packages/eslint-plugin-fiori-tools/jest.config.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ export default {
1212
// which deadlocks under Jest's --experimental-vm-modules.
1313
'^synckit$': '<rootDir>/test/__mocks__/synckit.cjs'
1414
},
15+
transform: {
16+
// Patch @babel/eslint-parser's index.js (see transformer header for rationale).
17+
// This rule must come before ts-jest's default `^.+\\.[jt]s$` so it wins for the
18+
// matched path; Jest applies the first matching transform.
19+
'@babel[\\\\/]eslint-parser[\\\\/]lib[\\\\/]index\\.js$':
20+
'<rootDir>/test/babel-eslint-parser.transformer.cjs',
21+
...baseConfig.transform
22+
},
23+
transformIgnorePatterns: [
24+
// Override jest.base's pattern to additionally allow @babel/eslint-parser through
25+
// the transform pipeline so our patcher above runs on it.
26+
'node_modules/(?!(?:.*?/)?(@sap-ux|@sap-ux-private|@sap/ux-cds-compiler-facade|@sap-devx[+/]yeoman-ui-types|@babel[+/]eslint-parser)/)'
27+
],
1528
coveragePathIgnorePatterns: [
1629
'src/types.ts',
1730
'src/language/annotations/types.ts',

packages/eslint-plugin-fiori-tools/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"format": "prettier --write '**/*.{js,json,ts,yaml,yml}' --ignore-path ../../.prettierignore",
2222
"lint": "eslint",
2323
"lint:fix": "eslint --fix",
24-
"test": "cross-env \"NODE_OPTIONS=--experimental-vm-modules\" jest --ci --forceExit --detectOpenHandles --colors --maxWorkers=50%"
24+
"test": "cross-env \"NODE_OPTIONS=--experimental-vm-modules\" jest --ci --forceExit --detectOpenHandles --colors --maxWorkers=50%",
25+
"tgz:package": "pnpm pack"
2526
},
2627
"devDependencies": {
2728
"@jest/globals": "30.3.0",
@@ -32,8 +33,9 @@
3233
"@types/semver": "7.7.1"
3334
},
3435
"dependencies": {
35-
"@babel/core": "7.29.0",
36-
"@babel/eslint-parser": "^7.28.5",
36+
"@babel/core": "8.0.0-rc.6",
37+
"@babel/eslint-parser": "8.0.0-rc.6",
38+
"@babel/parser": "8.0.0-rc.6",
3739
"@eslint/js": "10.0.1",
3840
"@eslint/json": "0.14.0",
3941
"@eslint/core": "1.1.1",
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
// Jest transformer that string-patches @babel/eslint-parser@8.0.0-rc.6/lib/index.js so
4+
// it imports @babel/parser statically instead of via createRequire(). The shipped parser
5+
// uses createRequire(import.meta.url).require('@babel/parser') which throws under Jest's
6+
// --experimental-vm-modules because the VM-modules runtime cannot satisfy a sync CJS-style
7+
// require for a pure-ESM module like @babel/parser@8. Production runtime is unaffected:
8+
// Node 22.12+ supports require(esm) natively, so the unpatched parser loads fine there.
9+
module.exports = {
10+
process(sourceText) {
11+
const importReplaced = sourceText.replace(
12+
"import { createRequire } from 'node:module';",
13+
"import * as babelParser from '@babel/parser';"
14+
);
15+
const requireRemoved = importReplaced.replace(
16+
/const require\$1 = createRequire\(import\.meta\.url\);\s*const babelParser = require\$1\(require\$1\.resolve\("@babel\/parser",\s*\{\s*paths:\s*\[require\$1\.resolve\("@babel\/core\/package\.json"\)\]\s*\}\)\);/,
17+
''
18+
);
19+
if (importReplaced === sourceText || requireRemoved === importReplaced) {
20+
throw new Error(
21+
'[babel-eslint-parser.transformer] Failed to patch @babel/eslint-parser/lib/index.js: ' +
22+
'expected createRequire-based @babel/parser load not found. ' +
23+
'The upstream source has likely changed — update the transformer.'
24+
);
25+
}
26+
return { code: requireRemoved };
27+
}
28+
};

0 commit comments

Comments
 (0)