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

Bad formatting closing script-tag in vue-files #79

Closed
Alex-Sokolov opened this issue Jan 17, 2018 · 21 comments
Closed

Bad formatting closing script-tag in vue-files #79

Alex-Sokolov opened this issue Jan 17, 2018 · 21 comments

Comments

@Alex-Sokolov
Copy link

Alex-Sokolov commented Jan 17, 2018

What version of eslint are you using?
"eslint": "4.15.0",

What version of prettier are you using?
"prettier": "1.10.2",

What version of eslint-plugin-prettier are you using?
"eslint-plugin-prettier": "2.5.0",

Please paste any applicable config files that you're using (e.g. .prettierrc or .eslintrc files)

const resolve = require('path').resolve;

module.exports = {
  root: true,
  parserOptions: {
    parser: 'babel-eslint'
  },
  env: {
    browser: true,
    node: true,
    jest: true
  },
  extends: [
    'standard',
    'prettier',
    'plugin:vue/base',
    'plugin:vue/essential',
    'plugin:vue/strongly-recommended',
    'plugin:vue/recommended'
  ],
  plugins: ['html', 'variables', 'prettier'],
  rules: {
    'prettier/prettier': 'error',
    'import/no-unresolved': 'error',
    'variables/only-ascii-variables': 'error'
  },
  settings: {
    'import/resolver': {
      webpack: {
        config: {
          resolve: {
            alias: {
              '~': __dirname
            }
          }
        }
      }
    }
  }
};
"prettier": {
    "printWidth": 120,
    "tabWidth": 2,
    "useTabs": false,
    "semi": true,
    "singleQuote": true,
    "trailingComma": "none",
    "bracketSpacing": true
  },

What source code are you linting?
https://pastebin.com/Hzik4pNs

What did you expect to happen?
Formatting correct

What actually happened?
After updating eslint-plugin-prettier from 2.4.0 to 2.5.0 and run eslint --fix --ext .js,.vue --ignore-path .gitignore .
image

@azz
Copy link
Member

azz commented Jan 17, 2018

This odd because the prettier output is fine.

@not-an-aardvark
Copy link
Member

Does this still happen if you remove eslint-plugin-html?

@azz
Copy link
Member

azz commented Jan 17, 2018

Oh I think I see what is happening, the contents of the <script> tag are being passed to prettier and prettier is told it is a vue file (from #76). Prettier will then treat the string that is JS as vue (HTML), and thus formatted as-is (minus chomping the trailing newline).

What should be happening is this plugin should pass the entire file contents to prettier.

@Alex-Sokolov
Copy link
Author

Alex-Sokolov commented Jan 17, 2018

@azz yes, but I have pre-commit hook and that stop me :)

@not-an-aardvark after exclude html from plugins start work (and vue rules start working with big amount of vue/* errors)

@Gomah
Copy link

Gomah commented Jan 24, 2018

Updating eslint-plugin-html to 4.0.2 fixes it for me 👍

@phouri
Copy link

phouri commented Feb 1, 2018

Updating eslint-plugin-html to 4.0.2 did not solve for me unfortunately :/

Still getting this error, eslintrc is :

parserOptions: {
    parser: 'babel-eslint',
    ecmaVersion: 2017,
    sourceType: 'module'
  },
  env: {
    browser: true,
    es6: true,
  },
  // extends: ['prettier', ],
  extends: [
    'plugin:vue/essential',
    'prettier',
    'eslint:recommended',
  ],
  // required to lint *.vue files
  plugins: [
    'html',
    'prettier',
    'import'
  ],

Also //eslint-ignore-next-line doesn't work, seems like it does think the js file is indeed html, any idea how to fix?

@Gomah
Copy link

Gomah commented Feb 2, 2018

I actually removed eslint-plugin-html (see why) & opted for the following config with vue:

module.exports = {
  root: true,
  parserOptions: {
    parser: 'babel-eslint',
  },
  env: {
    browser: true,
    node: true,
  },
  extends: [
    'airbnb-base',
    'plugin:prettier/recommended',
    'plugin:vue/recommended',
  ],
  plugins: ['prettier', 'vue'],
  rules: {
    'prettier/prettier': ['error', { singleQuote: true, trailingComma: 'es5' }],
    'import/extensions': [
      'error',
      'always',
      {
        js: 'never',
        vue: 'never',
      },
    ],
    'vue/max-attributes-per-line': [
      2,
      {
        singleline: 3,
        multiline: {
          max: 1,
          allowFirstLine: false,
        },
      },
    ],
  },
  settings: {
    'import/core-modules': [
      'vuex',
      'vue',
      'vue-server-renderer',
      'vue-router',
      'vuex-router-sync',
      'webpack-node-externals',
    ],
    'import/resolver': {
      webpack: {
        config: {
          resolve: {
            extensions: ['.js', '.vue'],
            alias: {
              '~': __dirname,
              '@': __dirname,
            },
          },
        },
      },
    },
  },
};

@jay-hankins
Copy link

jay-hankins commented Mar 23, 2018

I'm seeing this as well, and I'm not using eslint-plugin-html.

.eslintrc.js:

module.exports = {
  root: true,
  parserOptions: {
    parser: 'babel-eslint',
    sourceType: 'module'
  },
  env: {
    browser: true,
  },
  extends: [
    "airbnb-base",
    "plugin:vue/recommended",
    "plugin:prettier/recommended",
  ],
  // // required to lint *.vue files
  // plugins: [
  //   'html'
  // ],
  // check if imports actually resolve
  settings: {
    'import/resolver': {
      webpack: {
        config: 'build/webpack.base.conf.js'
      }
    }
  },
  // add your custom rules here
  rules: {
    // don't require .vue extension when importing
    'import/extensions': ['error', 'always', {
      js: 'never',
      vue: 'never'
    }],
    // disallow reassignment of function parameters
    // disallow parameter object manipulation except for specific exclusions
    'no-param-reassign': ['error', {
      props: true,
      ignorePropertyModificationsFor: [
        'state', // for vuex state
        'acc', // for reduce accumulators
        'e' // for e.returnvalue
      ]
    }],
    // allow optionalDependencies
    'import/no-extraneous-dependencies': ['error', {
      optionalDependencies: ['test/unit/index.js']
    }],
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    // ignore max length
    'max-len': 0,
  }
}

@Xotic750
Copy link

Xotic750 commented Apr 16, 2018

We are also having this problem. From the cli we are not seeing any error, but in our webpack build we get the following for every vue file in the project.

/Users/grahamfairweather/ProReNataJournal/Byxelkrok/Modules/Calendar/Components/ToggleLayersSelector.vue
  233:3  error  Delete `⏎`  prettier/prettier
"babel-eslint": "^8.2.3",
"eslint-plugin-html": "^4.0.3",
"eslint-plugin-prettier": "^2.6.0",
"eslint-plugin-vue": "^4.4.0",
"prettier": "^1.12.0",

If I can give more information to assist, please just ask (assuming that this is the plugin that is at fault?).

@h2jorm
Copy link

h2jorm commented Apr 23, 2018

@Xotic750 I met the same problem with you and now have solved it by changing the vue-loader option in webpack.

// wrong config
{
  test: /\.vue$/,
  loader: [
    {
      loader: 'vue-loader',
      options: {
        loaders: {
          // ...
          js: ['babel-loader', 'eslint-loader'],
        },
      },
    },
  ],
},

// right config
{
  test: /\.vue$/,
  loader: [
    {
      loader: 'vue-loader',
      options: {
        loaders: {
          // ...
        },
      },
    },
    'eslint-loader',
  ],
},

Do not add eslint-loader in vue-loader options but outside. May this info helps you.

@Xotic750
Copy link

@leeching Thanks, that's very interesting. It's quite different information to what our team gleaned several months back. Initial tests look promising, but we continue to test. May I ask where you found this information?

@h2jorm
Copy link

h2jorm commented Apr 24, 2018

@Xotic750 This is just my personal practice.

@ryo-utsunomiya
Copy link

I moved eslint-loader to 'pre' loader and fixed this problem.

// webpack.config.js
module.exports = {
  // ... other options
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        exclude: /node_modules/
      }
    ]
  }
}

see:
https://vue-loader-v14.vuejs.org/en/workflow/linting.html
https://webpack.js.org/configuration/module/#rule-enforce

@fzred
Copy link

fzred commented Jun 22, 2018

+1,We are also having this problem.
.eslintrc.js

{
  "extends": [
    "plugin:prettier/recommended"
  ],
  "plugins": [
    "html"
  ],
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "rules": {
    "no-multiple-empty-lines": 2,
    "prettier/prettier": [
      "error",
      {
        "singleQuote": true,
        "semi": false
      }
    ]
  }
}

@busheezy
Copy link

same issue as frzed

@mkapiczy
Copy link

+1

I get exactly the same issue. Moving eslint-loader to 'pre' loaders did not help, and getting rid of the loader helps but then linting rules are not applied.

@marcoeh
Copy link

marcoeh commented Sep 13, 2018

+1

@lawrsp
Copy link

lawrsp commented Sep 17, 2018

+1
"eslint-plugin-html": "4.0.5",

@BPScott
Copy link
Member

BPScott commented Sep 27, 2018

Hi folks.

There are potentially three issues here, based around how if you have eslint-plugin-vue enabled, eslint-plugin-html enabled, or both plugins enabled. Before I delve into the scenarios, lets talk about ESLint processors...

Processors allow ESLint read some file that has JS embedded into it (such as fenced code blocks in markdown or
<script> tags in a html file) extract those blocks of JS and pass them into other ESLint rules. This is what eslint-plugin-html does for .vue files - it extracts the <script> block and passes just that into ESLint. eslint-plugin-vue, however passes the whole vue file as-is into ESLint as it provides rules around formatting your <template> block too.

This leaves eslint-plugin-prettier in a bit of a quandry - it needs to pick a parser to use to read the vue file. If you're using eslint-plugin-vue we should use the vue parser as we're acting upon a whole vue file. However if you're using eslint-plugin-html then we should use the babylon parser as we're acting upon just the JS code extracted from the script tag. If you're using both then all bets are off and I'm not sure what you'll be acting upon and you'll end up in @Gomah's state where you're inadvertently not running any linting for your vue <template> and <style> elements.


If you are using just eslint-plugin-vue: You should be good. eslint-plugin-prettier will receive a full vue file and will format it with the vue parser.

If you are using just eslint-plugin-html: Currently this will break as eslint-plugin-prettier will just the <script> part and try to format it with the vue parser. We could change this to force the use of the babylon parser, but then we'd break everybody using just eslint-plugin-vue.

If you are using both plugins: This will break for the same reason as above.


I think the correct solution to this is for eslint-plugin-html to drop their support of .vue files, and to instead tell people to use eslint-plugin-vue if they want to lint their vue files. That will also allow them to lint their template and style sections, rather than just the JS section.

@BPScott
Copy link
Member

BPScott commented Sep 30, 2018

If you're using eslint-plugin-html and NOT eslint-plugin-vue then you can force the prettier within eslint to use the babylon parser (as you're acting on a blob of javascript not a whole vue file) by customising the your prettier options within eslint:

Within your .eslintrc, modify your prettier/prettier rule to add a config that overrides the prettier parser for vue files:

{
  "rules": {
    "prettier/prettier": [
      "error",
      {
        "overrides": [{ "files": "*.vue", "options": { "parser": "babylon" } }]
      }
    ]
  }
}

@BPScott BPScott mentioned this issue Sep 30, 2018
Merged
@BPScott
Copy link
Member

BPScott commented Sep 30, 2018

Going to close this as v2.7 should work with eslint-plugin-vue out the box, and people using eslint-plugin-html can force use of the babylon parser using the above config.

@BPScott BPScott closed this as completed Sep 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests