YakovL
YakovL

Reputation: 8365

How do I fix "No ESLint configuration found" for files outside the folder with .eslintrc.js? (takes place only when I try to use a enum value)

The app structure

I'm creating a fullstack app (Node.js + TypeScript + Vue, other bits are irrelevant) and I have the following folder structure:

<project root>
  model/
  front/
    src/
    node_modules/
    package.json
    .eslintrc.js     // note where it is
    ...
  back/
  node_modules/
  package.json
  ...

Since front/ was based on the app created with vue-cli and I like having node_modules of frontend separate from those of backend, the structure of front/ is standart for a vue app.

The common model (for front and back)

I have TS model common for front and back and it is stored in

model/
  objects.ts
  api.ts

To use api.ts in the frontend part, I have front/src/store/api.ts which reads as just

// re-export from fullstack common model
export * from '../../../model/api'

That worked fine with interfaces defined in model/api.ts (and model/objects.ts), for instance I can use

import { TestApiResponse } from '../api'
...
const testUser: TestApiResponse = response.data;

in front/src/store/modules/user.ts.

The problem

I've tried to also introduce

export enum Endpoints {
  TestApi = 'testApi',
}

to use it in both front and back, like the interfaces, the whole minimal api.ts looks like

import { UserBase } from './objects'

export enum Endpoints {
  TestApi = 'testApi',
}

export interface TestApiResponse extends UserBase {}

That by itself doesn't break anything. I can also write

import { Endpoints, TestApiResponse } from '../api'

in user.ts and the project still compiles (both npm run serve and npm run build work without errors).

But once I also substitute (in user.ts)

const response = await axios.get(Vue.prototype.$apiRoot + 'testApi');

with

const response = await axios.get(Vue.prototype.$apiRoot + Endpoints.TestApi);

both dev server (npm run serve) and npm run build start to show

Failed to compile.

../model/api.ts Module build failed (from ./node_modules/eslint-loader/index.js):
Error: No ESLint configuration found in <project root>\model.
at CascadingConfigArrayFactory._finalizeConfigArray (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:432:19)
at CascadingConfigArrayFactory.getConfigArrayForFile (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:271:21)
at CLIEngine.isPathIgnored (<project root>\front\node_modules\eslint\lib\cli-engine\cli-engine.js:951:18)
at CLIEngine.executeOnText (<project root>\front\node_modules\eslint\lib\cli-engine\cli-engine.js:868:38)
at lint (<project root>\front\node_modules\eslint-loader\index.js:278:17) at transform (<project root>\front\node_modules\eslint-loader\index.js:252:18)
at <project root>\front\node_modules\loader-fs-cache\index.js:127:18 at ReadFileContext.callback (<project root>\front\node_modules\loader-fs-cache\index.js:31:14)
at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:273:13)

The main difference is that I use enum values unlike just types before (adding let e: Endpoints; doesn't produce an error). The other bit that most likely contributes to the problem: <project root>/model/api.ts is outside <project root>/front/ which contains .eslintrc.js (using values of a enum from, say, front/src/router/index.ts doesn't produce errors). Any ideas why is this so and/or how can I fix this?

(I've tried to just copy .eslintrc.js to the root folder or to model/ but that haven't fixed the issue)

PS here's .eslintrc.js generated by vue cli:

module.exports = {
  root: true,
  env: {
    node: true
  },
  'extends': [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript/recommended'
  ],
  parserOptions: {
    ecmaVersion: 2020
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

PPS Well, I've tried to move .eslintrc.js to the root folder, but in this case npm run serve shows

Module build failed (from ./node_modules/eslint-loader/index.js):
Error: Failed to load config "@vue/typescript/recommended" to extend from.
Referenced from: <project root>\.eslintrc.js
    at configMissingError (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:265:9)
    at ConfigArrayFactory._loadExtendedShareableConfig (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:826:23)
    at ConfigArrayFactory._loadExtends (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:731:25)
    at ConfigArrayFactory._normalizeObjectConfigDataBody (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:660:25)
    at _normalizeObjectConfigDataBody.next (<anonymous>)
    at ConfigArrayFactory._normalizeObjectConfigData (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:596:20)
    at _normalizeObjectConfigData.next (<anonymous>)
    at createConfigArray (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:340:25)
    at ConfigArrayFactory.loadInDirectory (<project root>\front\node_modules\eslint\lib\cli-engine\config-array-factory.js:433:16)
    at CascadingConfigArrayFactory._loadConfigInAncestors (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:328:46)      
    at CascadingConfigArrayFactory._loadConfigInAncestors (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:347:20)      
    at CascadingConfigArrayFactory._loadConfigInAncestors (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:347:20)      
    at CascadingConfigArrayFactory._loadConfigInAncestors (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:347:20)      
    at CascadingConfigArrayFactory._loadConfigInAncestors (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:347:20)      
    at CascadingConfigArrayFactory.getConfigArrayForFile (<project root>\front\node_modules\eslint\lib\cli-engine\cascading-config-array-factory.js:272:18)       
    at CLIEngine.isPathIgnored (<project root>\front\node_modules\eslint\lib\cli-engine\cli-engine.js:951:18)

Moreover, if I copy (instead of moving) .eslintrc.js to the root folder, I see the same errors (after restarting npm run serve). I guess, I have to install something into the root package.json, but I'm not sure what exactly (front/node_modules/@vue/ doesn't contain typescript/recommended). In if I remove the , '@vue/typescript/recommended' bit from .eslintrc in the root, I get

<project root>\model\api.ts
  4:8  error  Parsing error: Unexpected token enum

hmm.. presumably I have to configure eslint to work with TS from scratch at this point... I've tried to follow some bits from here:

  1. npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
  2. added to .eslintrc plugins: [ '@typescript-eslint' ], and to extends there 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended'

but got Unexpected token enum again. Not sure how to sort this out.

Perhaps it's not a good idea to setup eslint via vue cli in a fullstack project.

Upvotes: 4

Views: 5098

Answers (1)

mcmimik
mcmimik

Reputation: 1853

I had a similar problem, maybe the plugin you're looking for is called @vue/eslint-config-typescript - at least installing it helped me (although I had to pick up a version that was compatible with other dependencies).

But it's not just about the plugin, it's about the fact that ESLint follows the principle of Сascading and Hierarchy:

There are two ways to use configuration files.

The first way to use configuration files is via .eslintrc.* and package.json files. ESLint automatically looks for them in the directory of the file to be linted, and in successive parent directories all the way up to the root directory of the filesystem (/) [...]

So all you have to do is move your .eslintrc.js from the front folder to the <project root> folder, like this:

<project root>
  .eslintrc.js // works for all subdirectories, incl. "model/"
  model/
  front/
    src/
    node_modules/
    package.json
  back/
  node_modules/
  package.json

Upvotes: 1

Related Questions