vite-plugin-eslint icon indicating copy to clipboard operation
vite-plugin-eslint copied to clipboard

How to stop `vite-plugin-eslint` from expecting ESLint config from NPM library that is linked via `npm link`?

Open agm1984 opened this issue 1 year ago • 2 comments

I have this problem where I have an NPM library of components, freshly made. I imported it into a Vue application that explodes instantly after I do npm link in the node_module and npm link <module name> in the Vue application.

This error was a major nightmare at first because I was struggling to understand NPM link and struggling to discover what the correct way to import components from the library was. I think I have everything settled now, but the only way I can make it work is to disable eslint in the Vue application.

Naively, I don't understand why eslint in the Vue application is checking external files. Like, worry about your own project eslint-bro. As I dig deeper, I think I did try to put an ES Lint config into the NPM library (which it should ultimately have anyway), but I think that's different problem or alternate solution.

I think it might be better to make a way to instruct eslint() to ignore symlinks. I thnk it has something to do with that because, here's the error:

6:28:36 a.m. [vite] Internal server error: No ESLint configuration found in /Users/username/dev/someorg/someorg-ui-libraries/designsystems-lib/dist/config.
  Plugin: vite-plugin-eslint
  File: /Users/username/dev/someorg/someorg-ui-libraries/designsystems-lib/dist/config/config.esm.js
      at CascadingConfigArrayFactory._finalizeConfigArray (/Users/username/dev/someorg/someorg-vueapp/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3977:19)
      at CascadingConfigArrayFactory.getConfigArrayForFile (/Users/username/dev/someorg/someorg-vueapp/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3768:21)
      at CLIEngine.isPathIgnored (/Users/username/dev/someorg/someorg-vueapp/node_modules/eslint/lib/cli-engine/cli-engine.js:989:18)
      at ESLint.isPathIgnored (/Users/username/dev/someorg/someorg-vueapp/node_modules/eslint/lib/eslint/eslint.js:681:26)
      at TransformContext.transform (file:///Users/username/dev/someorg/someorg-vueapp/node_modules/vite-plugin-eslint/dist/index.mjs:1:1868)
      at Object.transform (file:///Users/username/dev/someorg/someorg-vueapp/node_modules/vite/dist/node/chunks/dep-c167897e.js:43372:44)
      at async loadAndTransform (file:///Users/username/dev/someorg/someorg-vueapp/node_modules/vite/dist/node/chunks/dep-c167897e.js:41090:29)

Also here is the Vite config that reproduces it:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import eslint from 'vite-plugin-eslint';
import Components from 'unplugin-vue-components/vite';
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
    server: {
        port: 4000,
    },

    plugins: [
        vue(),
        eslint(),
        Components(),
    ],

    test: {
        environment: 'jsdom',
    },

    resolve: {
        alias: [{
            find: '@', replacement: path.resolve(__dirname, 'src'),
        }],
    },
});

I looked at the ES Lint options object, because it appears you can pass it in via eslint(), but it also seems you need to declare every key. I don't see anything about passing only one key like exclude or something like that.

It seems a fix would be related to ignoring directories that aren't my Vue application, ie: /Users/username/dev/someorg/someorg-vueapp/

Is there a way to solve this? There seems to be in Webpack, but I don't see a Vite equivalent 'quickfix'.

agm1984 avatar Mar 29 '23 13:03 agm1984

Update: I fixed it with this:

import eslint from 'vite-plugin-eslint';

...

        eslint({
            // with pure default, eslint tries to lint external directories symlinked via `npm link`
            include: [
                `${path.resolve(__dirname, '')}/**/*.js`,
                `${path.resolve(__dirname, '')}/**/*.vue`,
            ],
        }),

I barely have any seat time on it so far, but it isn't erroring out anymore. It also worked with ${path.resolve(__dirname, '')}/** but that was throwing errors in my CSS file, so I peeled it back to include only opted-in file types.

This is the default:

include
Type: string | string[]
Default: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.vue', '**/*.svelte']

You can see all I did was change **/ to ${path.resolve(__dirname, '')}/**

Also after further thinking, I noticed that because I haven't published my NPM library yet, there is no entry for it in the package.json file, so it is currently plausible that this issue stems from the fact that some files have code such as:

import thing from '@external/place';

But it gets confused by the fact that the package is symlinked via npm link while not being declared in package.json. After I publish I can see if that also fixes it, but if not, my current solution here is shaping up as a concise fix.

NOTE: If direction from this issue is unclear, it may be ok to close it as there is a "workaround" available.

agm1984 avatar Mar 29 '23 16:03 agm1984

I had a similar issue, i solved it with:

      eslint({
        exclude: [/virtual:/, /node_modules/]
      } as any),

amcdnl avatar Apr 12 '23 15:04 amcdnl