| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 | "use strict";//var fs = require("fs");var assign = require("object-assign");var loaderUtils = require("loader-utils");var objectHash = require("object-hash");var createCache = require("loader-fs-cache");var pkg = require("./package.json");var cache = createCache("eslint-loader");var engines = {};/** * Class representing an ESLintError. * @extends Error */class ESLintError extends Error {  /**   * Create an ESLintError.   * @param {string} messages - Formatted eslint errors.   */  constructor(messages) {    super();    this.name = "ESLintError";    this.message = messages;    this.stack = "";  }  /**   * Returns a stringified representation of our error. This method is called   * when an error is consumed by console methods   * ex: console.error(new ESLintError(formattedMessage))   * @return {string} error - A stringified representation of the error.   */  inspect() {    return this.message;  }}/** * printLinterOutput * * @param {Object} eslint.executeOnText return value * @param {Object} config eslint configuration * @param {Object} webpack webpack instance * @return {void} */function printLinterOutput(res, config, webpack) {  // skip ignored file warning  if (    !(      res.warningCount === 1 &&      res.results[0].messages[0] &&      res.results[0].messages[0].message &&      res.results[0].messages[0].message.indexOf("ignore") > 1    )  ) {    // quiet filter done now    // eslint allow rules to be specified in the input between comments    // so we can found warnings defined in the input itself    if (res.warningCount && config.quiet) {      res.warningCount = 0;      res.results[0].warningCount = 0;      res.results[0].messages = res.results[0].messages.filter(function(        message      ) {        return message.severity !== 1;      });    }    // if enabled, use eslint auto-fixing where possible    if (      config.fix &&      (res.results[0].output !== res.src ||        res.results[0].fixableErrorCount > 0 ||        res.results[0].fixableWarningCount > 0)    ) {      var eslint = require(config.eslintPath);      eslint.CLIEngine.outputFixes(res);    }    if (res.errorCount || res.warningCount) {      // add filename for each results so formatter can have relevant filename      res.results.forEach(function(r) {        r.filePath = webpack.resourcePath;      });      var messages = config.formatter(res.results);      if (config.outputReport && config.outputReport.filePath) {        var reportOutput;        // if a different formatter is passed in as an option use that        if (config.outputReport.formatter) {          reportOutput = config.outputReport.formatter(res.results);        } else {          reportOutput = messages;        }        var filePath = loaderUtils.interpolateName(          webpack,          config.outputReport.filePath,          {            content: res.results              .map(function(r) {                return r.source;              })              .join("\n")          }        );        webpack.emitFile(filePath, reportOutput);      }      // default behavior: emit error only if we have errors      var emitter = res.errorCount ? webpack.emitError : webpack.emitWarning;      // force emitError or emitWarning if user want this      if (config.emitError) {        emitter = webpack.emitError;      } else if (config.emitWarning) {        emitter = webpack.emitWarning;      }      if (emitter) {        if (config.failOnError && res.errorCount) {          throw new ESLintError(            "Module failed because of a eslint error.\n" + messages          );        } else if (config.failOnWarning && res.warningCount) {          throw new ESLintError(            "Module failed because of a eslint warning.\n" + messages          );        }        emitter(new ESLintError(messages));      } else {        throw new Error(          "Your module system doesn't support emitWarning. " +            "Update available? \n" +            messages        );      }    }  }}/** * webpack loader * * @param  {String|Buffer} input JavaScript string * @param {Object} map input source map * @return {void} */module.exports = function(input, map) {  var webpack = this;  var userOptions = assign(    // user defaults    (webpack.options && webpack.options.eslint) || webpack.query || {},    // loader query string    loaderUtils.getOptions(webpack)  );  var eslintPkgPath = "eslint/package.json";  var userEslintPath = eslintPkgPath;  if (userOptions.eslintPath) {    userEslintPath = userOptions.eslintPath + "/package.json";  }  var eslintVersion;  try {    eslintVersion = require(require.resolve(userEslintPath)).version;  } catch (_) {    // ignored  }  if (!eslintVersion) {    try {      eslintVersion = require(require.resolve(eslintPkgPath)).version;    } catch (_) {      // ignored    }  }  var config = assign(    // loader defaults    {      cacheIdentifier: JSON.stringify({        "eslint-loader": pkg.version,        eslint: eslintVersion || "unknown version"      }),      eslintPath: "eslint"    },    userOptions  );  if (typeof config.formatter === "string") {    try {      config.formatter = require(config.formatter);      if (        config.formatter &&        typeof config.formatter !== "function" &&        typeof config.formatter.default === "function"      ) {        config.formatter = config.formatter.default;      }    } catch (_) {      // ignored    }  }  var cacheDirectory = config.cache;  var cacheIdentifier = config.cacheIdentifier;  delete config.cacheIdentifier;  // Create the engine only once per config  var configHash = objectHash(config);  if (!engines[configHash]) {    var eslint = require(config.eslintPath);    engines[configHash] = new eslint.CLIEngine(config);  }  var engine = engines[configHash];  if (config.formatter == null || typeof config.formatter !== "function") {    config.formatter = engine.getFormatter("stylish");  }  webpack.cacheable();  var resourcePath = webpack.resourcePath;  var cwd = process.cwd();  // remove cwd from resource path in case webpack has been started from project  // root, to allow having relative paths in .eslintignore  if (resourcePath.indexOf(cwd) === 0) {    resourcePath = resourcePath.substr(cwd.length + 1);  }  // return early if cached  if (config.cache) {    var callback = webpack.async();    return cache(      {        directory: cacheDirectory,        identifier: cacheIdentifier,        options: config,        source: input,        transform: function() {          return lint(engine, input, resourcePath);        }      },      function(err, res) {        if (err) {          return callback(err);        }        try {          printLinterOutput(            assign({}, res || {}, { src: input }),            config,            webpack          );        } catch (e) {          err = e;        }        return callback(err, input, map);      }    );  }  printLinterOutput(lint(engine, input, resourcePath), config, webpack);  webpack.callback(null, input, map);};function lint(engine, input, resourcePath) {  return engine.executeOnText(input, resourcePath, true);}
 |