简体   繁体   English

eslint:如何仅对接触过的文件进行 lint

[英]eslint: howto lint only touched files

I have recently added eslint , as webpack loader, in a codebase that was never parsed with a linter before.我最近在以前从未用 linter 解析过的代码库中添加了eslint作为 webpack 加载器。

Obviously the amount of errors triggered are endless: there is any chance to configure eslint to parse only the touched files?显然,触发的错误数量是无穷无尽的:有没有机会配置 eslint 来仅解析触及的文件? I would like the linter to parse every file in which developers make changes and those only.我希望 linter 解析开发人员在其中进行更改的每个文件,并且仅解析这些文件。

This is the loader I am using so far (in case can be of interest), very standard configuration:这是我目前使用的加载器(以防万一),非常标准的配置:

{test: /\.(jsx|js)$/, loader: "eslint-loader?{cache: true}", exclude: /node_modules/}

Thank you谢谢

I accomplished it by using a watcher;我通过使用观察者完成了它; this is the solution in the details:这是详细的解决方案:

dependencies for the Webpack configuration: Webpack 配置的依赖项:

var logger = require('reliable-logger');
var watch = require('watch');
var CLIEngine =  require('eslint').CLIEngine

watcher and linter configuration and start; watcher 和 linter 配置和启动; I am pasting it with all the todos, as it is:我将它与所有待办事项一起粘贴,因为它是:

var configureLinterAndWatchFiles = function() {
var changedFiles = [];
var formatter;
var report;
var SEPARATOR = "////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////";

// TODO I got the feeling that one of those settings is breaking the
//   linter (probably the path resolving?)
var linter =  new CLIEngine({
    // TODO do I need this? Looks like I don't...
    // envs: ["node"],
    // TODO what is the default?
    useEslintrc: true,
    // TODO I find weird that I get no error with this: configFile: "../.eslintrc1111"
    //  make sure that the configuration file is correctly picked up
    configFile: ".eslintrc",
    // TODO useless if your root is src
    // ignorePath: "node_modules"
    // TODO probably both useless... the first I still don't get it,
    //   the second you are enforcing the filtering yourself by checks
    // cache: false,
    // extensions: [".js", ".jsx"]
});

var fileUpdatedFn = function(f) {
    // TODO I would prefer much more to get the list of changed files from
    //   git status (how to?). Here I am building my own
    // resetting the array only for debug purpose
    // changedFiles = [];
    if(/.js$/.test(f) || /.jsx$/.test(f)) {
        changedFiles.push(f);
        logger.info(SEPARATOR);
        report = linter.executeOnFiles(changedFiles);
        logger.info(formatter(report.results));
    }
};

// get the default formatter
formatter = linter.getFormatter();

watch.watchTree('src', function(f, curr, prev) {
    if (typeof f == "object" && prev === null && curr === null) {
    // Finished walking the tree
    } else if (prev === null) {
    // f is a new file
    } else if (curr.nlink === 0) {
    // f was removed
    } else {
        // f was changed
        fileUpdatedFn(f);
    }
});

}; };

in module.exports, as last line:在 module.exports 中,作为最后一行:

module.exports = function(callback, options){
  // ... more code ...
  configureLinterAndWatchFiles();
}

That should be it.应该是这样。 As I pointed out in a comment:正如我在评论中指出的那样:

I wonder, though, if the cache flag (eslint.org/docs/developer-guide/nodejs-api#cliengine) was the best to be used for the problem.不过,我想知道缓存标志 (eslint.org/docs/developer-guide/nodejs-api#cliengine) 是否最适合用于解决该问题。 From here (github.com/adametry/gulp-eslint/issues/…): "--cache flag will skip over any files that had no problems in the previous run unless they have been modified": not sure if that is my case but is of interest.从这里(github.com/adametry/gulp-eslint/issues/...):“--cache 标志将跳过上次运行中没有问题的任何文件,除非它们已被修改”:不确定这是否是我的情况但很有趣。

Definitively I'm a little late for the party, but I faced the very same issue today & it seems like there is still no common solution for that.毫无疑问,我参加聚会有点晚了,但我今天遇到了同样的问题,而且似乎仍然没有通用的解决方案。

I ended up monkey patching webpack's devServer with this:我最终用这个猴子修补了 webpack 的devServer

  const { exec } = require('child_process');
  
  // ...
  
  devServer: {
    hot: false,
    inline: false,
    publicPath: '/',
    historyApiFallback: true,
    disableHostCheck: true,
    after: (app, server, compiler) => {
      compiler.hooks.watchRun.tap(
        'EsLint-upon-save',
        () => {
          // This should only work in dev environment
          if (process.env.NODE_ENV !== 'development') {
            return;
          }
        
          // Credits to:
          // https://stackoverflow.com/a/43149576/9430588
          const filesChanged = Object.keys(compiler.watchFileSystem.watcher.mtimes);
          
          // Might be empty
          if (!filesChanged.length) {
            return;
          }

          filesChanged.forEach((changedFileAbsolutePath) => {
            const extension = changedFileAbsolutePath.split('.').pop();

            if (extension === 'js' || extension === 'jsx') {
              exec(`npx eslint --fix --fix-type suggestion,layout ${changedFileAbsolutePath}`); 
            }
          });
        }
      );
    }
  },

It's surely quite quick & dirty type of solution, however it seems to work fine with eslint@7.7.0 .这肯定是一种非常快速和肮脏的解决方案,但是它似乎与eslint@7.7.0一起工作得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM