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

ESLint error: Cannot read property 'externals' of undefined #1448

Closed
fsih opened this issue Aug 8, 2019 · 14 comments · Fixed by #1705
Closed

ESLint error: Cannot read property 'externals' of undefined #1448

fsih opened this issue Aug 8, 2019 · 14 comments · Fixed by #1705

Comments

@fsih
Copy link

fsih commented Aug 8, 2019

I'm using

    "eslint-import-resolver-webpack": "^0.11.1",
    "eslint-plugin-import": "^2.18.2",

I'm trying to add

    settings: {
        'import/resolver': 'webpack'
    }

to my .eslintrc.js, as recommended in the readme at https://www.npmjs.com/package/eslint-import-resolver-webpack

However, running eslint is failing with
TypeError: Cannot read property 'externals' of undefined

@ljharb
Copy link
Member

ljharb commented Aug 8, 2019

Where’s your webpack config? What version of webpack do you have?

@fsih
Copy link
Author

fsih commented Aug 8, 2019

"webpack": "^4.6.0",
The folder structure is

root/
    webpack.config.js
    src/
        .eslintrc.js

@ljharb
Copy link
Member

ljharb commented Aug 8, 2019

why is your eslint and webpack config not in the same dir, the root of the project?

@fsih
Copy link
Author

fsih commented Aug 9, 2019

We have another .eslintrc.js in root/. Only what’s in src needs the webpack resolver since everything else we have uses normal Node.js resolution.

@ljharb
Copy link
Member

ljharb commented Aug 9, 2019

If you copy/move the webpack config into src, does eslint work again?

@fsih
Copy link
Author

fsih commented Aug 9, 2019

If I copy/move the webpack config to src, I get the same 'TypeError: Cannot read property 'externals' of undefined'

Sorry, let me give more context. This bug looks a lot like #1219, which was supposedly fixed, but is still happening when using the latest version of eslint-import-resolver-webpack and eslint-plugin-import.

Here's the output from running
~/Git/scratch-gui $ DEBUG="eslint-plugin-import:resolver:webpack" eslint . --ext .js,.jsx

...  
eslint-plugin-import:resolver:webpack Config path from settings: undefined +2ms
  eslint-plugin-import:resolver:webpack Config path resolved to: /Users/dd/Git/scratch-gui/node_modules/scratch-paint/webpack.config.js +0ms
  eslint-plugin-import:resolver:webpack Using config:  undefined +3ms
TypeError: Cannot read property 'externals' of undefined
Occurred while linting /Users/dd/Git/scratch-gui/src/containers/paint-editor-wrapper.jsx:1
    at Object.exports.resolve (/Users/dd/Git/scratch-gui/node_modules/eslint-import-resolver-webpack/index.js:112:42)
    at v2 (/Users/dd/Git/scratch-gui/node_modules/eslint-module-utils/resolve.js:94:23)
    at withResolver (/Users/dd/Git/scratch-gui/node_modules/eslint-module-utils/resolve.js:99:16)
    at fullResolve (/Users/dd/Git/scratch-gui/node_modules/eslint-module-utils/resolve.js:116:22)
    at Function.relative (/Users/dd/Git/scratch-gui/node_modules/eslint-module-utils/resolve.js:61:10)
    at remotePath (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:401:30)
    at captureDependency (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:442:15)
    at /Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:480:7
    at Array.forEach (<anonymous>)
    at Function.ExportMap.parse (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:461:12)
    at Function.ExportMap.for (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:353:25)
    at Function.ExportMap.get (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/ExportMap.js:315:23)
    at processBodyStatement (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/rules/namespace.js:67:47)
    at Array.forEach (<anonymous>)
    at Program (/Users/dd/Git/scratch-gui/node_modules/eslint-plugin-import/lib/rules/namespace.js:96:14)
    at listeners.(anonymous function).forEach.listener (/Users/dd/Git/scratch-gui/node_modules/eslint/lib/util/safe-emitter.js:45:58)

From Config path resolved to: /Users/dd/Git/scratch-gui/node_modules/scratch-paint/webpack.config.js it looks like it's trying to use the webpack.config.js file of one of its dependencies, rather than ours (scratch-gui), which is causing it to try to access a property of an undefined config.

@dustinkeeton
Copy link

Did you ever figure out the answer to this? Having a similar if not the same issue.

@migueloller
Copy link
Contributor

migueloller commented Mar 12, 2020

This issue will happen if, for example, you're missing a Babel plugin. To see what's actually going on, run ESLint with the --debug flag. This allowed me to discover I was missing a dev dependency that was required for ESLint to parse the JavaScript files.

What should be solved here is the opaque error. It should actually show what really happened, without having to run it with --debug.

EDIT: This wasn't the underlying issue. The actual issue is here.

@migueloller
Copy link
Contributor

migueloller commented Mar 12, 2020

Ok, after looking more into this, the actual issue is that if a webpack config returns an array and neither of the configurations has a resolve key, then the webpack config is undefined and it blows up. The code that does that is here: https://github.com/benmosher/eslint-plugin-import/blob/efd6be15a71a39f82b610f0e24804214dc6630d2/resolvers/webpack/index.js#L116-L118

This seems to just be a bug with the webpack resolver.

A workaround is to add an empty resolver field to your webpack config, i.e., resolver: {}. What do the maintainers think should be done here? Have different logic when reading the config or perhaps provide a descriptive error message explaining why when there's an array the resolver needs the resolve field? Would happily submit a PR with the maintainer's guidance.

@ljharb
Copy link
Member

ljharb commented Mar 12, 2020

I mean, if you're using the webpack resolver, but your webpack config has no resolvers in it, that seems confusing?

Why are you using the webpack resolver if webpack isn't changing how it resolves any paths?

@migueloller
Copy link
Contributor

That's a good question. In my case, the ESLint config is at the top-level of a monorepo and is used to lint multiple packages. Some of these packages use webpack, others don't. Of the ones that do, some of them use the resolve field, other's don't.

@ljharb
Copy link
Member

ljharb commented Mar 12, 2020

Makse sense - it seems reasonable for the webpack resolver to be a noop (altho, it should probably log a console warning) when there's no webpack config with a resolve. Want to make a PR?

@migueloller
Copy link
Contributor

Sure! As for the current implementation, do you have any suggestion for making the resolver be a noop? Should I just default it to an empty config in this current error case and log a warning?

@ljharb
Copy link
Member

ljharb commented Mar 12, 2020

That seems reasonable to me.

migueloller added a commit to migueloller/eslint-plugin-import that referenced this issue Mar 29, 2020
@ljharb ljharb closed this as completed in 95c12fc Apr 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants