BenoitZugmeyer / eslint-plugin-html

An ESLint plugin to extract and lint scripts from HTML files.
ISC License
436 stars 51 forks source link

Cannot read property 'map' of undefined #28

Closed rebers closed 8 years ago

rebers commented 8 years ago

Hi guys,

I'm trying to use your extremely useful plugin in the default Vue.js webpack template. It comes preconfigured and is required in its latest version (@1.5.1). Using Atom, normal JS files lint just well, but in .vue components I receive the following error:

Error: Cannot read property 'map' of undefined
TypeError: Cannot read property 'map' of undefined
    at /Users/robin/Development/skappbar.dev/node_modules/eslint-plugin-html/src/index.js:86:39
    at Array.forEach (native)
    at Object.postprocess (/Users/robin/Development/skappbar.dev/node_modules/eslint-plugin-html/src/index.js:85:19)
    at processText (/Users/robin/Development/skappbar.dev/node_modules/eslint/lib/cli-engine.js:252:30)
    at CLIEngine.executeOnText (/Users/robin/Development/skappbar.dev/node_modules/eslint/lib/cli-engine.js:761:26)
    at Object.cli.execute (/Users/robin/Development/skappbar.dev/node_modules/eslint/lib/cli.js:181:36)
    at lintJob (/Users/robin/.atom/packages/linter-eslint/lib/worker.js:35:10)
    at /Users/robin/.atom/packages/linter-eslint/lib/worker.js:69:20
    at Emitter.emit (/Users/robin/.atom/packages/linter-eslint/node_modules/process-communication/node_modules/sb-event-kit/lib/emitter.js:70:19)
    at /Users/robin/.atom/packages/linter-eslint/node_modules/process-communication/node_modules/sb-communication/lib/main.js:22:23

While typing / saving the file.

The file is the default Hello.vue from the webpack template:

<template>
  <div class="hello">
    <h1>{{ msg }}<span>hello World!!!</span></h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // note: changing this line won't causes changes
      // with hot-reload because the reloaded component
      // preserves its current state and we are modifying
      // its initial state.
      msg: 'Hello World!',
    };
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
h1 {
  color: #42b983;
  span {
      color: red;
  }
}
</style>

My package.json:

{
  "name": "skappbar.dev",
  "version": "1.0.0",
  "description": "XXX",
  "author": "XXX",
  "private": true,
  "scripts": {
    "dev": "node build/dev-server.js",
    "build": "node build/build.js",
    "unit": "karma start test/unit/karma.conf.js --single-run",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run unit && npm run e2e",
    "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
  },
  "dependencies": {
    "vue": "^1.0.21",
    "babel-runtime": "^6.0.0"
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-eslint": "^6.1.2",
    "babel-loader": "^6.0.0",
    "babel-plugin-transform-runtime": "^6.0.0",
    "babel-preset-es2015": "^6.0.0",
    "babel-preset-stage-2": "^6.0.0",
    "babel-register": "^6.0.0",
    "chai": "^3.5.0",
    "chromedriver": "^2.21.2",
    "connect-history-api-fallback": "^1.1.0",
    "cross-spawn": "^2.1.5",
    "css-loader": "^0.23.0",
    "eslint": "^2.10.2",
    "eslint-config-airbnb-base": "^3.0.1",
    "eslint-friendly-formatter": "^2.0.5",
    "eslint-loader": "^1.3.0",
    "eslint-plugin-html": "^1.3.0",
    "eslint-plugin-import": "^1.8.1",
    "eventsource-polyfill": "^0.9.6",
    "express": "^4.13.3",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.4",
    "function-bind": "^1.0.2",
    "html-webpack-plugin": "^2.8.1",
    "http-proxy-middleware": "^0.12.0",
    "inject-loader": "^2.0.1",
    "isparta-loader": "^2.0.0",
    "json-loader": "^0.5.4",
    "karma": "^0.13.15",
    "karma-coverage": "^0.5.5",
    "karma-mocha": "^0.2.2",
    "karma-phantomjs-launcher": "^1.0.0",
    "karma-sinon-chai": "^1.2.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "0.0.24",
    "karma-webpack": "^1.7.0",
    "lolex": "^1.4.0",
    "mocha": "^2.4.5",
    "nightwatch": "^0.8.18",
    "ora": "^0.2.0",
    "phantomjs-prebuilt": "^2.1.3",
    "sass-loader": "^4.0.0",
    "selenium-server": "2.53.0",
    "shelljs": "^0.6.0",
    "sinon": "^1.17.3",
    "sinon-chai": "^2.8.0",
    "url-loader": "^0.5.7",
    "vue-hot-reload-api": "^1.2.0",
    "vue-html-loader": "^1.0.0",
    "vue-loader": "^8.3.0",
    "vue-style-loader": "^1.0.0",
    "webpack": "^1.12.2",
    "webpack-dev-middleware": "^1.4.0",
    "webpack-hot-middleware": "^2.6.0",
    "webpack-merge": "^0.8.3"
  }
}

Using it on node a v6.3.1 and everything else runs smoothly.

Any idea on why this is happening and how it can be fixed would be greatly appreciated.

rebers commented 8 years ago

Restarting Atom did the trick!

judocode commented 8 years ago

I get this issue when trying to run eslint through webpack for .vue files.

eslint versions:

"eslint": "^3.5.0",
"eslint-config-airbnb-base": "^7.1.0",
"eslint-loader": "^1.5.0",
"eslint-plugin-html": "^1.5.2",
"eslint-plugin-import": "^1.15.0",

webpack versions: "webpack": "^1.12.2",

.eslintrc.js file:

module.exports = {
  root: true,
  parserOptions: {
    sourceType: 'module'
  },

  extends: 'airbnb-base',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  rules: {
    'import/no-unresolved': 0,

    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
    // allow console.log in dev.
    'no-console': process.env.NODE_ENV === 'production' ? 2 : 0,

    'no-param-reassign': 0,
    'default-case': 0,

    // Sometimes we add propery starting with `_` e.g _type to make
    // sure we dont colide with an existing object property named type.
    'no-underscore-dangle': 0,

    'no-unused-vars': [1, {'vars': 'local', 'args': 'none'}],
  },
}

webpack config:

module: {
    preLoaders: [
      { test: /\.vue$/, loader: 'eslint', exclude: /node_modules/ }
    ],
},
eslint: {
    failOnWarning: false,
    failOnError: true
},
rebers commented 8 years ago

I indeed still get this error every now and then, but a quick restart fixes this.

It's definitely a bug, I just don't know how to reproduce it yet.

BenoitZugmeyer commented 8 years ago

Working on it.

BenoitZugmeyer commented 8 years ago

I can't reproduce the error. This setup seems to work as expected:

~/tmp/test-eslint-plugin-html-issue-28 % webpack
Hash: 396f0bfb9d565b6f60f0
Version: webpack 1.12.2
Time: 682ms
    + 1 hidden modules

ERROR in ./foo.vue

/home/alk/tmp/test-eslint-plugin-html-issue-28/foo.vue
  3:1  error    Unexpected var, use let or const instead  no-var
  3:5  warning  'foo' is defined but never used           no-unused-vars

✖ 2 problems (1 error, 1 warning)

ERROR in ./foo.vue
Module build failed: Error: Module failed because of a eslint error.

/home/alk/tmp/test-eslint-plugin-html-issue-28/foo.vue
  3:1  error    Unexpected var, use let or const instead  no-var
  3:5  warning  'foo' is defined but never used           no-unused-vars

✖ 2 problems (1 error, 1 warning)

@jrenton would you mind providing a gist like this one so I can better figure out what's wrong? you can fork it for instance. The npm shrinkwrap would provide valuable informations about your setup too.

judocode commented 8 years ago

@BenoitZugmeyer Thanks for looking into this. I determined the root of the problem was due to the odd way in which eslint is referenced. I created a pull request #33 here that fixes it.

BenoitZugmeyer commented 8 years ago

I did require ESLint this way because I feared to have issues when ESLint is installed globally and the plugin locally or conversely. But it turns out you have to install plugins globally when ESLint is installed globally anyway, so it's kind of pointless.

If it fixes your issue, then great, let's simplify this!

BenoitZugmeyer commented 8 years ago

Sorry, I am not satisfied by this fix. Let's find something else!

blade254353074 commented 8 years ago

How is it now?

BenoitZugmeyer commented 8 years ago

@blade254353074 I found why it could fail (that's probably because webpack or atom is messing with the require module cache), but I still didn't reproduce. If anyone could provide steps to reproduce consistently, it would help me a lot.

judocode commented 8 years ago

@BenoitZugmeyer Why are you not satisfied with the fix? I provided the configuration to reproduce above.

blade254353074 commented 8 years ago

@BenoitZugmeyer OK

blade254353074 commented 8 years ago

@BenoitZugmeyer

https://github.com/blade254353074/multi-vue

eslint is related to:

You can start with npm run dev, then you can see: The error

BenoitZugmeyer commented 8 years ago

@jrenton yes, you gave me partial configuration to reproduce, and I replied to you with a gist using it but still didn't manage to reproduce, so I asked you for more information but you didn't answer my request. require("eslint") doesn't satisfy me because you can't be sure it'll return the eslint currently loaded. For example, if you are using npm link to install this plugin, require("eslint") will either raise a Cannot find module 'eslint' or load another instance of eslint.

@blade254353074 thank you very much, I can reproduce now. Working on it!

BenoitZugmeyer commented 8 years ago

@blade254353074 ok so the issue was caused by loading both eslint and standard (which in turn loads eslint again) in the same process. I pushed a patch that should fix this, could you confirm? It probably fixes other issues mentioned here too.

blade254353074 commented 8 years ago

@BenoitZugmeyer Okay, I can test it right now.

blade254353074 commented 8 years ago

@BenoitZugmeyer I think the error was resolved. Dev environment looks fine to me. Thank you.

BenoitZugmeyer commented 8 years ago

Ok let's close this issue. Let me know if someone have still this error.