首页 > 技术文章 > Vite Vue3项目eslint配置遇到的问题

Jingge 2021-06-24 15:43 原文

问题一:vite项目无法使用vue/airbnb

创建了一个Vite Vue3 ts项目,eslint配置采用@vue/airbnb,然而eslint却不生效。

module.exports = { 
    extends: [
        'plugin:vue/vue3-essential',
        '@vue/airbnb',
        '@vue/typescript/recommended',
      ],
}

查看eslint日志,发现报错了

Error: Cannot find module '@vue/cli-service/webpack.config.js'

原来 @vue/eslint-config-airbnb是专门为vue cli设计的,它依赖@vue/cli-service,所以vite项目不能使用。

解决方法,参照@vue/eslint-config-airbnb,修改自己的配置

查看了@vue/eslint-config-airbnb源码,发现它是扩展了airbnb-base,重写了'import/extensions'和'no-param-reassign'规则

  • import/extensions,导入js,mjs,jsx,ts,tsx模块时可以不写后缀名
  • no-param-reassign, 允许修改state,acc,e参数的属性
    另外还添加了'import/resolver'和'import/extensions'的settings。

vue/eslint-config-airbnb/index.js

module.exports = {
  extends: [
    require.resolve('eslint-config-airbnb-base'),
  ],
  settings: {
    'import/resolver': {
      // https://github.com/benmosher/eslint-plugin-import/issues/1396
      [require.resolve('eslint-import-resolver-node')]: {},
      [require.resolve('eslint-import-resolver-webpack')]: {
        config: require.resolve('@vue/cli-service/webpack.config.js'),
      },
    },
    'import/extensions': [
      '.js',
      '.jsx',
      '.mjs',
      '.ts',
      '.tsx',
    ],
  },
  rules: {
    'import/extensions': ['error', 'always', {
      js: 'never',
      mjs: 'never',
      jsx: 'never',
      ts: 'never',
      tsx: 'never',
    }],
    'no-param-reassign': ['error', {
      props: true,
      ignorePropertyModificationsFor: [
        'state', // for vuex state
        'acc', // for reduce accumulators
        'e', // for e.returnvalue
      ],
    }],
  },
};

参考@vue/eslint-config-airbnb源码修改了我的eslint配置

module.exports = {
    extends: [
        'plugin:vue/vue3-recommended',
        '@vue/typescript/recommended',
        'airbnb-base',
      ],
    rules: {
        'import/extensions': ['error', 'always', {
          js: 'never',
          mjs: 'never',
          jsx: 'never',
          ts: 'never',
          tsx: 'never',
        }],
        'no-param-reassign': ['error', {
          props: true,
          ignorePropertyModificationsFor: [
            'state', // for vuex state
            'acc', // for reduce accumulators
            'e', // for e.returnvalue
          ],
        }],
}

结果发现导入ts模块时会报import/no-unresolved错误,另外import/extensions也没有生效。

问题二:无法识别ts模块

image

解决办法:

  • 安装 eslint-import-resolver-typescript
npm i -D eslint-plugin-import @typescript-eslint/parser eslint-import-resolver-typescript

  • 修改.eslintrc.js配置文件, 添加如下配置。
plugins: ['import'],
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx'],
    },
    'import/resolver': {
      typescript: {
        // always try to resolve types under `<root>@types`
        // directory even it doesn't contain any source code, like `@types/unist`
        alwaysTryTypes: true,

        // Choose from one of the "project" configs
        // below or omit to use <root>/tsconfig.json by default

        // use <root>/path/to/folder/tsconfig.json
        project: '/',
      },
    },
  },

最终的eslint配置

module.exports = {
  env: {
    node: true,
    browser: true,
    es2021: true,
    jest: true,
  },
  extends: [
    // 'eslint:recommended',
    'plugin:vue/vue3-recommended',
    '@vue/typescript/recommended',
    'airbnb-base',
  ],
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 12,
    parser: '@typescript-eslint/parser',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: ['import'],
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx'],
    },
    'import/resolver': {
      typescript: {
        // always try to resolve types under `<root>@types`
        // directory even it doesn't contain any source code, like `@types/unist`
        alwaysTryTypes: true,

        // Choose from one of the "project" configs
        // below or omit to use <root>/tsconfig.json by default

        // use <root>/path/to/folder/tsconfig.json
        project: '/',
      },
    },
  },
  rules: {
    'import/extensions': ['error', 'always', {
      js: 'never',
      mjs: 'never',
      jsx: 'never',
      ts: 'never',
      tsx: 'never',
    }],
    'no-param-reassign': ['error', {
      props: true,
      ignorePropertyModificationsFor: [
        'state', // for vuex state
        'acc', // for reduce accumulators
        'e', // for e.returnvalue
      ],
    }],
  },
};

推荐阅读