Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forEach is undefined when running import/namespace #3099

Open
guoliang opened this issue Nov 11, 2024 · 11 comments
Open

forEach is undefined when running import/namespace #3099

guoliang opened this issue Nov 11, 2024 · 11 comments

Comments

@guoliang
Copy link

I'm trying to update to ESLint 9 and switch over to the flat config.

I'm getting the following error from eslint-import-plugin. Not sure why this is happening, so any help is appreciated.

[error] TypeError: Cannot read properties of undefined (reading 'forEach')
Occurred while linting /Users/abc/Development/infor/mashup-2/client/src/app/app-wizard/app-wizard.component.html:1
Rule: "import/namespace"
    at Program (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint-plugin-import/lib/rules/namespace.js:85:18)
    at ruleErrorHandler (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/linter.js:1084:48)
    at /Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/node-event-generator.js:337:14)
    at runRules (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/linter.js:1128:40)
    at #flatVerifyWithoutProcessors (/Users/abc/Development/infor/mashup-2/client/node_modules/eslint/lib/linter/linter.js:1911:31)

My flat eslint.config.js looks as following

const eslint = require("@eslint/js");
const tseslint = require("typescript-eslint");
const angular = require("angular-eslint");
const importPlugin = require("eslint-plugin-import");

const eslintConfigPrettier = require("eslint-config-prettier");

let recommendedImport = {};
if (importPlugin.flatConfigs) {
	recommendedImport = { ...importPlugin.flatConfigs.recommended };
}
module.exports = [
	recommendedImport,
	eslintConfigPrettier,
	...tseslint.config(
		{
			files: ["**/*.ts"],
			extends: [
				eslint.configs.recommended,
				...tseslint.configs.recommended,
				...tseslint.configs.stylistic,
				...angular.configs.tsRecommended,
			],
			processor: angular.processInlineTemplates,
			rules: {
				"@angular-eslint/component-class-suffix": [
					"error",
					{
						suffixes: ["Base", "Component", "Container"],
					},
				],
				"@angular-eslint/directive-selector": [
					"error",
					{
						type: "attribute",
						prefix: "eir",
						style: "kebab-case",
					},
				],
				"@angular-eslint/component-selector": [
					"error",
					{
						type: "element",
						style: "kebab-case",
					},
				],

				"@typescript-eslint/no-wrapper-object-types": "error",
				"@typescript-eslint/no-unsafe-function-type": "error",
				"@typescript-eslint/no-empty-object-type": "off",
				"@typescript-eslint/no-restricted-types": [
					"error",
					{
						types: {
							Object: {
								message: "Avoid using the `Object` type. Did you mean `object`?",
								fixWith: "object",
							},
							Function: {
								message:
									"Avoid using the `Function` type. Prefer a specific function type, like `() => void`.",
							},
							Boolean: {
								message: "Avoid using the `Boolean` type. Did you mean `boolean`?",
							},
							Number: {
								message: "Avoid using the `Number` type. Did you mean `number`?",
							},
							String: {
								message: "Avoid using the `String` type. Did you mean `string`?",
							},
							Symbol: {
								message: "Avoid using the `Symbol` type. Did you mean `symbol`?",
							},
						},
					},
				],
				"@typescript-eslint/explicit-module-boundary-types": [
					"warn",
					{ allowArgumentsExplicitlyTypedAsAny: true },
				],
				"@typescript-eslint/explicit-function-return-type": [
					"error",
					{
						allowExpressions: true,
					},
				],
				"@typescript-eslint/no-explicit-any": "off",
				"@typescript-eslint/no-empty-function": ["warn", { allow: ["arrowFunctions", "methods"] }],
				"@typescript-eslint/no-empty-interface": ["error", { allowSingleExtends: true }],
				"@typescript-eslint/no-unused-vars": [
					"warn",
					{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
				],
				"@typescript-eslint/no-unused-expressions": [
					"error",
					{ allowTernary: true, allowShortCircuit: true },
				],
				eqeqeq: "error",
				"import/no-duplicates": "off",
				"import/no-unresolved": ["off", { commonjs: true, amd: true }],
			},
		},
		{
			files: ["**/*.html"],
			extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
			rules: {
				"@angular-eslint/template/banana-in-box": "error",
				"@angular-eslint/template/eqeqeq": "error",
			},
		},
	),
];
@ljharb
Copy link
Member

ljharb commented Nov 11, 2024

What version of the import plugin are you using?

@ljharb
Copy link
Member

ljharb commented Nov 11, 2024

it's possible it's coming from the angular eslint parser - can you narrow it down to what source code is causing the problem?

@guoliang
Copy link
Author

@ljharb
I'm using eslint-import-plugin: 2.31.0

Modified the setup also. Seems like I need to import it as following to get it to work

...
const importPlugin = require("eslint-plugin-import");

module.exports = [
	eslintConfigPrettier,
	...tseslint.config(
		{
			files: ["**/*.ts"],
			extends: [
				eslint.configs.recommended,
				...tseslint.configs.recommended,
				...tseslint.configs.stylistic,
				...angular.configs.tsRecommended,
			],
			plugins: {
				import: importPlugin,
			},

...

@ljharb
Copy link
Member

ljharb commented Nov 11, 2024

So you did get it to work? or are you saying it doesn't when you include the import rules?

@wmaurer
Copy link

wmaurer commented Dec 10, 2024

eslint-plugin-import is a must have for every project I work on :-)

However it's not working for me on a new nx/angular project. It could very well be something related to angular-eslint, but I'm having trouble tracking it down.

I have a minimal repro here:
https://github.com/wmaurer/eslint-plugin-import-bug

After cloning and npm install, run npm run lint and the following error should show:

Occurred while linting /home/wayne/projects/wmaurer/eslint-plugin-import-bug/apps/eslint-plugin-import-bug/src/app/app.component.html:1
Rule: "import/namespace"
TypeError: Cannot read properties of undefined (reading 'forEach')

@michaelfaith
Copy link
Contributor

I have a minimal repro here: https://github.com/wmaurer/eslint-plugin-import-bug

Looiking at the error, it appears to be linting an html file. The recommended config doesn't apply any file filtering. So if you're running it on a directory that includes html files you'd want to limit it to only lint js/ts files.

Try updating your config to something like this

const nx = require('@nx/eslint-plugin');
const importPlugin = require('eslint-plugin-import');

module.exports = [
  ...nx.configs['flat/base'],
  ...nx.configs['flat/typescript'],
  ...nx.configs['flat/javascript'],
-  importPlugin.flatConfigs.recommended,
+  {
+     files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
+   ...importPlugin.flatConfigs.recommended,
+ },
  {
    ignores: ['**/dist'],
  },
  {
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    rules: {
      '@nx/enforce-module-boundaries': [
        'error',
        {
          enforceBuildableLibDependency: true,
          allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?js$'],
          depConstraints: [
            {
              sourceTag: '*',
              onlyDependOnLibsWithTags: ['*'],
            },
          ],
        },
      ],
    },
  },
  {
    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
    // Override or add rules here
    rules: {},
  },
];

@wmaurer
Copy link

wmaurer commented Dec 11, 2024

@michaelfaith Thank-you very much, that's solved my problem!

If anybody else uses this plugin on an angular project, they're going to bump into this problem. What do you think would be the best?
a) Apply file filtering to the recommended config
b) Document your solution in the README

@michaelfaith
Copy link
Contributor

@michaelfaith Thank-you very much, that's solved my problem!

If anybody else uses this plugin on an angular project, they're going to bump into this problem. What do you think would be the best? a) Apply file filtering to the recommended config b) Document your solution in the README

Since changing the recommended config would be a breaking change (and require a new major version bump), documentation is probably the best option for now.

@ljharb
Copy link
Member

ljharb commented Dec 11, 2024

You should be using an angular-specific eslint parser in an angular project, and you definitely need to be targeting files by extension in your own project.

@wmaurer
Copy link

wmaurer commented Dec 13, 2024

Thanks, with this solution, our issue is resolved.
If you would accept a short addition to the README with guidance for others then I will open a PR.

@ljharb
Copy link
Member

ljharb commented Dec 13, 2024

That'd be great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants