eslint import/no-extraneous-dependencies не может разрешить зависимость

Я скомпилировал код javascript в app.js с помощью бранча.

eslint выдает следующий результат, однако в моем браузере все работает отлично.

Ошибка

error: 'frontend' should be listed in the project's dependencies. Run 'npm i -S frontend' to add it (import/no-extraneous-dependencies) at templates/base.html:41:9:
  39 |       <script src="{% static 'handlebars/templates.js' %}"></script>
  40 |       <script>
> 41 |         require('frontend/js/index');
     |         ^
  42 |       </script>
  43 |     {% endblock javascript %}
  44 |     {% block events %}


error: Unable to resolve path to module 'frontend/js/index' (import/no-unresolved) at templates/base.html:41:17:
  39 |       <script src="{% static 'handlebars/templates.js' %}"></script>
  40 |       <script>
> 41 |         require('frontend/js/index');
     |                 ^
  42 |       </script>
  43 |     {% endblock javascript %}
  44 |     {% block events %}

Моя среда

Brunch: 2.10.10
Node.js: 6.11.2
NPM: 3.10.10
Operating system: Fedora 26
Code editor: emacs

Код

Код Javascript живет внутри шаблона django

{% load staticfiles i18n %}
{% load static %}
<!DOCTYPE html>
<html lang="en" ng-app>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>{% block title %}CRM{% endblock title %}</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
    {% block css %}
      {% if debug %}
        <link href="{% static 'vendor.css' %}" rel="stylesheet">
        <link href="{% static 'app.css' %}"   rel="stylesheet">
      {% else %}
        <link href="{% static 'vendor.min.css' %}"rel="stylesheet">
        <link href="{% static 'app.min.css' %}"  rel="stylesheet">
      {% endif %}
    {% endblock css %}
  </head>

  <body "page-top">
    {% include 'includes/header.html' %}
    {% block content %}
    {% endblock content %}

    {% block javascript %}
      {% if debug %}
        <script src="{% static 'vendor.js' %}"></script>
        <script src="{% static 'app.js' %}"></script>
        <script src="//localhost:35729/livereload.js"></script>
      {% else %}
        <script src="{% static 'vendor.min.js' %}"></script>
        <script src="{% static 'app.min.js' %}"></script>
      {% endif %}
      <script src="{% static 'handlebars/templates.js' %}"></script>
      <script>
        require('frontend/js/index');
      </script>
    {% endblock javascript %}
    {% block events %}
    {% endblock events %}
  </body>
</html>

Скомпилированный app.js находится в .frontend/app.js.

(function() {
  'use strict';

  var globals = typeof global === 'undefined' ? self : global;
  if (typeof globals.require === 'function') return;

  var modules = {};
  var cache = {};
  var aliases = {};
  var has = {}.hasOwnProperty;

  var expRe = /^\.\.?(\/|$)/;
  var expand = function(root, name) {
    var results = [], part;
    var parts = (expRe.test(name) ? root + '/' + name : name).split('/');
    for (var i = 0, length = parts.length; i < length; i++) {
      part = parts[i];
      if (part === '..') {
        results.pop();
      } else if (part !== '.' && part !== '') {
        results.push(part);
      }
    }
    return results.join('/');
  };

  var dirname = function(path) {
    return path.split('/').slice(0, -1).join('/');
  };

  var localRequire = function(path) {
    return function expanded(name) {
      var absolute = expand(dirname(path), name);
      return globals.require(absolute, path);
    };
  };

  var initModule = function(name, definition) {
    var hot = hmr && hmr.createHot(name);
    var module = {id: name, exports: {}, hot: hot};
    cache[name] = module;
    definition(module.exports, localRequire(name), module);
    return module.exports;
  };

  var expandAlias = function(name) {
    return aliases[name] ? expandAlias(aliases[name]) : name;
  };

  var _resolve = function(name, dep) {
    return expandAlias(expand(dirname(name), dep));
  };

  var require = function(name, loaderPath) {
    if (loaderPath == null) loaderPath = '/';
    var path = expandAlias(name);

    if (has.call(cache, path)) return cache[path].exports;
    if (has.call(modules, path)) return initModule(path, modules[path]);

    throw new Error("Cannot find module '" + name + "' from '" + loaderPath + "'");
  };

  require.alias = function(from, to) {
    aliases[to] = from;
  };

  var extRe = /\.[^.\/]+$/;
  var indexRe = /\/index(\.[^\/]+)?$/;
  var addExtensions = function(bundle) {
    if (extRe.test(bundle)) {
      var alias = bundle.replace(extRe, '');
      if (!has.call(aliases, alias) || aliases[alias].replace(extRe, '') === alias + '/index') {
        aliases[alias] = bundle;
      }
    }

    if (indexRe.test(bundle)) {
      var iAlias = bundle.replace(indexRe, '');
      if (!has.call(aliases, iAlias)) {
        aliases[iAlias] = bundle;
      }
    }
  };

  require.register = require.define = function(bundle, fn) {
    if (bundle && typeof bundle === 'object') {
      for (var key in bundle) {
        if (has.call(bundle, key)) {
          require.register(key, bundle[key]);
        }
      }
    } else {
      modules[bundle] = fn;
      delete cache[bundle];
      addExtensions(bundle);
    }
  };

  require.list = function() {
    var list = [];
    for (var item in modules) {
      if (has.call(modules, item)) {
        list.push(item);
      }
    }
    return list;
  };

  var hmr = globals._hmr && new globals._hmr(_resolve, require, modules, cache);
  require._cache = cache;
  require.hmr = hmr && hmr.wrap;
  require.brunch = true;
  globals.require = require;
})();

(function() {
var global = typeof window === 'undefined' ? this : window;
var process;
var __makeRelativeRequire = function(require, mappings, pref) {
  var none = {};
  var tryReq = function(name, pref) {
    var val;
    try {
      val = require(pref + '/node_modules/' + name);
      return val;
    } catch (e) {
      if (e.toString().indexOf('Cannot find module') === -1) {
        throw e;
      }

      if (pref.indexOf('node_modules') !== -1) {
        var s = pref.split('/');
        var i = s.lastIndexOf('node_modules');
        var newPref = s.slice(0, i).join('/');
        return tryReq(name, newPref);
      }
    }
    return none;
  };
  return function(name) {
    if (name in mappings) name = mappings[name];
    if (!name) return;
    if (name[0] !== '.' && pref) {
      var val = tryReq(name, pref);
      if (val !== none) return val;
    }
    return require(name);
  }
};
require.register("frontend/js/config.js", function(exports, require, module) {
'use strict';

// -------------------------------------------------------
// Common config values should go here
// =======================================================
var common = {};

// -------------------------------------------------------
// Local config
// =======================================================
var local = Object.assign({}, common, {
  api: {
    host: 'http://localhost:8000/api/v1/'
  }
});

// -------------------------------------------------------
// Development config
// =======================================================
var development = Object.assign({}, common, {
  api: {
    host: 'http://development.com/api/v1/'
  }
});

// -------------------------------------------------------
// Staging config
// =======================================================
var staging = Object.assign({}, common, {
  api: {
    host: 'http://staging.com/api/v1/'
  }
});

// -------------------------------------------------------
// Production config
// =======================================================
var production = Object.assign({}, common, {
  api: {
    host: 'http://production.com/api/v1/'
  }
});

/**
 * Returns the configuration based on domain
 * @returns {object}
 */
function getConfig() {
  switch (window.location.hostname) {
    case 'localhost':
    case '127.0.0.1':
      return local;
    case 'dev.yourdomain.com':
      return development;
    case 'staging.yourdomain.com':
      return staging;
    case 'yourdomain.com':
      return production;
    default:
      throw new Error('Unknown environment: ' + String(window.location.hostname));
  }
}

/**
 * Define actual configuration to be used
 */
var config = Object.assign({}, getConfig());

/**
 * Returns the configuration parameter
 * @param {str} key - config's key
 */
function getItem(key) {
  return key in config ? config[key] : null;
}

/**
 * Sets the configuration parameter
 * @param {str} key - config's key
 * @param {str|number|boolean} value - config's key value
 */
function setItem(key, value) {
  config[key] = value;
}

config = Object.assign(config, {
  getItem: getItem,
  setItem: setItem
});

module.exports = config;

});

require.register("frontend/js/index.js", function(exports, require, module) {
"use strict";

(function () {
  function init() {
    // put your initialization code here
    // console.log('Init');
  }

  return init;
})()();

});

require.alias("process/browser.js", "process");process = require('process');require.register("___globals___", function(exports, require, module) {


// Auto-loaded modules from config.npm.globals.
window.jQuery = require("jquery");
window["$"] = require("jquery");
window.bootstrap = require("bootstrap");
window.selectpicker = require("bootstrap-select");
window.datepicker = require("bootstrap-datepicker");


});})();require('___globals___');


//# sourceMappingURL=app.js.map

.eslintrc.js

module.exports = {
  env: {
    'browser': true,
    'commonjs': true,
    'es6': true,
    'jquery': true
  },
  plugins: [
    'html',
    'import'
  ],
  extends: [
    'airbnb-base',
    'plugin:import/errors',
    'plugin:import/warnings'
  ],
  rules: {
    'comma-dangle': ['error', 'never'],
    'no-alert': 'off'
  }
};

Я понимаю, что могу полностью отключить правила, но как правильно решить этот вопрос?

Думаю, мне нужно что-то сделать с преобразователем импорта eslint, но не уверен, что из их документации.


person DmitrySemenov    schedule 06.10.2017    source источник


Ответы (1)


eslint понимает, что каждый пакет, который не имеет относительного импорта, должен существовать в вашем node_modules, так же как обычный запрос будет работать в узле, и поэтому вы получаете эту ошибку.

конфигурация вашего проекта может позволить вам потребовать этот модуль без добавления ./ в его путь, но это не поведение по умолчанию для модулей javascript.

person jenriquer    schedule 06.10.2017