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

Is that possible to use babel-eslint for js and @typescript-eslint/parser for ts at the same time? #49

Closed
JounQin opened this issue Jul 8, 2019 · 10 comments · Fixed by #116
Labels

Comments

@JounQin
Copy link

JounQin commented Jul 8, 2019

As title.

@Trendymen
Copy link

I have the same question, i only want typescript-eslint to lint <script lang="ts"> but even i have a normal config intent to only check normal .js file and <script>without lang="ts" in .vue,then set a override to only lint .ts .tsx and .vue files, the typescript-eslint will also lint <script>without lang="ts" because the files prop is [ts,.tsx,.vue] and now the normal config will not lint .vue files,are there some way to let typescript-eslint only to lint <script lang="ts"> in .vue files and other .ts .tsx files?

Below is my eslint config file

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    "plugin:vue/strongly-recommended",
    "@vue/prettier",
  ],
  parserOptions: {
    ecmaVersion: 2020
  },
  overrides:[{
    files: ['*.ts', '*.tsx',"*.vue"],
    parserOptions: {
      ecmaVersion: 2020,
      ecmaFeatures: {
        jsx: true
      }
    },
    extends: [
      "plugin:vue/strongly-recommended",
      "@vue/typescript/recommended",
      "@vue/prettier",
      "@vue/prettier/@typescript-eslint"
    ]
  }],
};

@ota-meshi
Copy link
Member

I don't know why you need it. Why do you need to mix lang="ts" and lang="js"?
I think it should be all ts or all js (in one project).

Can you tell me why you need it?

@darionco
Copy link

darionco commented Dec 3, 2020

As I explained in #75 in this comment, the problem comes when migrating a code base from JS to TS, my linting will fail for either all JS code or all TS code, it would be nice to be able to lint both at the same time.

@ota-meshi
Copy link
Member

Thank you for your comment.

Do you want to migrate all files to TS? If you're migrating all your files, I don't think you need to lint to the unmigrated files.
Why run the linter with a mixture of JS and TS?

@shameleo
Copy link

shameleo commented Dec 3, 2020

The same situation (migration)
I can't migrate all files at once (obviously). Team members can't learn typescript all together at once. So somebody, sometimes going to continue developing using JS for a while. Migration is background task. I have multipage app, so pages and corresponding .vue files are mostly independent.
I think many people will have similar case now, as typescript has more sense after Vue 3 released.

@tillsanders
Copy link

tillsanders commented Dec 3, 2020

I have another situation where this would come in handy. Most of the code base is in TypeScript, but some complex components rely on mixins which are a pain with TypeScript. So until the entire code base is moved to Vue 3, I simply keep them in JavaScript. They are however, actively maintained so linting would be nice because at the moment, they are completely excluded.

@ota-meshi
Copy link
Member

Thank you for your comments.
I've never mixed JS and TS, or stepped through the migration to TS, so your comments were helpful to me.
I was able to understand that this feature is useful.
However, I open the PR in my priority. Thank you for your understanding.

@mercs600
Copy link

mercs600 commented Mar 1, 2021

any updates or work arounds here ?

@Robula
Copy link

Robula commented Mar 18, 2021

In a modern world of monorepo's quite a lot of us are mixing JS/TS code together either in the same project or in the same repo. A root level ESLint configuration (for IDE level linting) is a pain to get right. As it stands we do something like this:

module.exports = {
  root: true,

  // Base JS rules
  extends: [
    "eslint:recommended"
  ],

  overrides: [
    {
      // TypeScript
      files: ["**/*.ts"],
      parser: "@typescript-eslint/parser",
      plugins: ["@typescript-eslint"],
      parserOptions: {
        tsconfigRootDir: __dirname,
        project: "tsconfig.eslint.json"
      },
      extends: [
        "plugin:@typescript-eslint/recommended",
        "plugin:@typescript-eslint/recommended-requiring-type-checking"
      ],
    },
    // Vue - This override will apply typescript linting rules across both TS Vue and JS Vue files which is a problem.
    {
      files: ["**/*.vue"],
      extends: [
        "plugin:vue/essential",
        "@vue/typescript/recommended"
      ],
    }
  ]

The issue is obvious here, because of the Single File Components with the .vue extension we cannot ask ESLint to distinguish between those .vue files that have TS code or those that have JS code.

We need .vts .vjs file extensions! :)

@mjeanroy
Copy link

Hi,

I encountered the same issue while working on a big codebase, not entirely migrated to TypeScript.
I solved it using a little hack that I would like to share.

First of all, I wrote a simple plugin, the main goal of this plugin is to override the preprocessor of vue-eslint-plugin in order to change the extension for .vue files with lang="ts".

The basic idea is here:

const parser = require('vue-sfc-parser');
const vueEslintPluginProcessor = require('eslint-plugin-vue/lib/processor');

module.exports = Object.assign({}, vueEslintPluginProcessor, {
    preprocess(text, filename) {
        const parseResult = parser.parseComponent(text);
        const script = parseResult.script;
        const lang = script ? script.lang || 'js' : 'js';
        if (lang === 'js') {
            return vueEslintPluginProcessor.preprocess(text);
        }

        const name = filename.replace(/\.vue$/, `.${lang}vue`);
        return [
            {text, filename: name},
        ];
    },
});

Then, I can use this "new" extension (i.e I chose .tsvue, but you can probably use .vuets or .vts) in my eslint configuration:

module.exports = {
  root: true,

  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    extraFileExtensions: [
      '.vue'
    ]
  },

  plugins: [
    'vue',
    'tsvue'
  ],

  extends: [
    'plugin:vue/essential'
  ],

  overrides: [
    {
      files: [
        '*.tsvue'
      ],

      parser: 'vue-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
        extraFileExtensions: [
          '.tsvue'
        ]
      },

      plugins: [
        'vue',
        '@typescript-eslint'
      ],

      extends: [
        'plugin:vue/essential',
        'plugin:@typescript-eslint/recommended',
        'plugin:@typescript-eslint/eslint-recommended'
      ]
    }
  ]
}

The only thing to do next is to override the --ext of my lint task to add .tsvue extension (since it is not included by default by vue-cli):

{
  "name": "vue-tsvue-sample-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "private": true,
  "scripts": {
    "lint": "vue-cli-service --ext .js,.ts,.vue,.tsvue lint"
  },
  "author": "Mickael Jeanroy",
  "license": "MIT",
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "4.19.0",
    "@typescript-eslint/parser": "4.19.0",
    "@vue/cli-plugin-eslint": "4.5.12",
    "@vue/cli-plugin-typescript": "4.5.12",
    "@vue/cli-service": "4.5.12",
    "eslint-plugin-tsvue": "*",
    "vue-eslint-parser": "7.6.0",
    "typescript": "4.2.3"
  }
}

And that's it!
I can now lint .vue files without being polluted by TS Lint issue in non TS script.

You can find a small repository here: https://github.com/mjeanroy/eslint-plugin-tsvue-sample

  • Checkout the repository and run pnpm install to install dependencies and link pnpm workspaces
  • Go in the app directory
  • Run pnpm run lint, you should get 2 warnings related to the TS component
  • Run pnpm run lint:broken to get the "classic" configuration, you should get 4 warnings (2 more warning related to the TS lint issues on the JS component).

This solution is clearly a hack, and will probably only live until my codebase will be entirely migrated.
Note that this solution should work with any languages (not specific to TypeScript).

If that interests some of you, I can open source my custom eslint preprocessor so that is will be usable.

And if that solution interests eslint-plugin-vue maintainer, I can open an issue in this repository to start discussing about it.

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

Successfully merging a pull request may close this issue.

9 participants