Prettier-eslint: Run inside .vue components?

Created on 14 Jun 2017  路  30Comments  路  Source: prettier/prettier-eslint

Is it possible to run prettier-eslint inside .vue component?

I've set:

"eslint.options": { "extensions": [ ".js", ".vue" ] }

but it didn't help.

enhancement help wanted no-issue-activity

Most helpful comment

Sweet @arpowers! Would you like to work on implementing it? I don't need it so I will not be working on it personally.

All 30 comments

Does prettier support vue? Does eslint? I'm not at all familiar with this. But it seems like it'd be cool and I'd be happy to accept a pull request :-)

eslint supports Vue using the html plugin as in some sense the .vue files are structured as html files with template, style and script tags. atom's prettier plugin is able to do fix .vue files so it i think this is definitely a possibility

Yes it does, but for some reason it's not following the settings on .eslint.json, it's using default Prettier settings.

If i save on a .js file, .eslint.json is used, but on a .vue file, .eslint.json is being ignored.

need this feature as well +1

Sweet @arpowers! Would you like to work on implementing it? I don't need it so I will not be working on it personally.

You can use this workaround for now.

We have support for prettier-eslint in Vetur for a while: https://vuejs.github.io/vetur/formatting.html#prettier

I hope this will be easier to implement/get working now that 8.4.0 is out.

We now forward text and filePath to prettier and let it figure out if it can fix the text. eslint only runs if there's no filePath provided or if filePath is provided, the extension of filePath must match eslints extensions configuration.

In the next release Prettier will support printing JS and CSS in .vue files out-of-the-box! 馃挜

If you're using version 8.4.0 or later of prettier-eslint, prettier should run on .vue files when prettier supports it, however you will need to configure eslint to handle .vue files. I believe there's eslint-plugin-html and eslint-plugin-script-tags to handle running eslint on code in <script> tags. Don't forget to add .vue to eslints extensions config.

You can use eslint-plugin-vue or just vue-eslint-parser and it _should_ "just work" now.

@azz What update made this "just work?" I banged my head against this two days ago for hours and it just wouldn't work. Today it is working!

Specifically, eslint-plugin-prettier was trying to parse .vue files using babylon-parser so every .vue file would fail with a syntax error. Now I'm having success with this .eslintrc and I don't think the parserOptions have anything to do with it.

{
  "parserOptions": {
    "parser": "babel-eslint",
    "ecmaVersion": 2017,
    "sourceType": "module"
  },
  "plugins": ["vue", "prettier"],
  "extends": ["standard", "plugin:vue/essential", "plugin:prettier/recommended"]
}

Before, I had to use this .eslintrc and not involve prettier as a plugin, but only as a config:

{
  "parserOptions": {
    "parser": "babel-eslint",
    "ecmaVersion": 2017,
    "sourceType": "module"
  },
  "plugins": ["vue"],
  "extends": ["standard", "plugin:vue/essential", "prettier"]
}

Do you know why prettier is correctly parsing the .vue files now?

EDIT: Ahh, it's this! That's what solved my problem. I was facing the issue right before you fixed it.

Please note that prettier-eslint runs prettier for any text, with or without filePath. We let prettier decide if it should do anything with the text.

Then we check if the eslint config we get have any extensions configured and if it does, we only run eslint for text without a filePath or if filePath have any of the configured extensions.

What I'm getting at here is that to have prettier-eslint run eslint with a vue plugin, you need to make sure that .vue is configured as an extension in your eslint config.

Maybe eslint-plugin-vue takes care of adding .vue as an extension in the config?

This is the update that fixed my issue. Great timing!

https://github.com/prettier/eslint-plugin-prettier/pull/76

Closing this as you should be able to do this now.

Prettier can handle .vue files and eslint can too, with eslint-plugin-vue.

.vue files are still not being supported as of now. Specifically, if we include an .eslintrc.json say {"extends": ["standard", "plugin:vue/essential"]}, some Standard rules like "semi": ["error", "never"] will work while other rules like "space-before-function-paren": ["error", "always"] will not. This issue has been raised before in https://github.com/prettier/prettier-atom/issues/282 and https://github.com/prettier/prettier-atom/issues/155.

I have done some digging and found the reason being https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L110 always returns true for .vue extension. This is because eslintConfig.extensions in https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L100 is always undefined which is traced to https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L228. Since eslintOptions does not contain the property extensions, https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L231 will never return a config with the extension property.

One way to get around is to pass in an overide through https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L62. However I don't see anyway we can do this by modifying our .eslintrc.json. In fact, adding a "extensions" property will cause our .eslintrc.json to become invalid. But for users of prettier-atom, the only thing we actually have control of is our .eslintrc.json. So @zimme suggestion is certainly not helpful.

Will someone look at this and push a fix soon?

I've reviewed several issues and pull requests on eslint, and it seems like supporting file extensions in .eslintrc is not gonna happen anytime soon (https://github.com/eslint/eslint/issues/2274#issuecomment-344997647, https://github.com/eslint/eslint/issues/7324, https://github.com/eslint/eslint/issues/8920#issuecomment-359017152).

It seems to me that the best way to support this would be to have https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L100 check options.extensions instead of eslintConfig.extensions. Then prettier-eslint-cli can use the --ext argument to specify extensions, like eslint does.

Since, as @yongjun21 pointed out, eslintConfig.extensions is always undefined, this should be completely backwards compatible.

If nobody objects, I'd be happy to contribute these changes.

What happens if you run eslint on a .vue file without having any eslint plugins that can handle parsing a .vue file... would that error or would it destroy the file.

If it errors, we should be able to catch and ignore that and just add .vue to the default list of supported files.

Another approach might be to look that the loaded plugins and add .vue to extensions if any plugin that handles .vue is loaded.

~I just checked. Running the formatter on a .vue file when no vue eslint plugins are enabled does not error out. Just runs Prettier.~
My apologies. Did not read your question closely. Running eslint without vue plugins causes a bunch of Parsing error: Unexpected token <

So if we check if .vue and running eslint gives us parser error we just return the output from prettier and ignore the eslint error, we should be able to add .vue to the default files.

edit: or give a helpful error message that you need to install an eslint plugin that supports .vue parsing.

That would definitely solve the problem for .vue files (which would be just great for me!), but not the root issue of checking the non-existent eslintConfig.extensions property. Fixing that would make it work for any file extensions the user chooses.

eslintConfig.extensions does exist if you send it in as an option from prettier-eslint-cli or any editor integration or other consumers of the api, which the might not be doing today.

eslintConfig is all the options provided in the arguments with some values overwritten by what's available in the config file that we find.

So we should be able to add --extensions to prettier-eslint-cli and then the editor integrations need to provide that too.

So you're saying we should add extensions to eslintConfig after it's created around here? https://github.com/prettier/prettier-eslint-cli/blob/master/src/format-files.js#L68-L74
Makes sense, and should be easy.

I actually prefer simply modifying https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L100 to include .vue as a supported file type. However that will require doing something similar to https://github.com/prettier/prettier-eslint/blob/master/src/index.js#L123 forcing parser to be vue-eslint-parser if linting .vue files.

However, it seems this will have silently fail if user did not install vue-eslint-parser or eslint-plugin-vue. Including vue-eslint-parser in prettier-eslint's package.json not enough, the parser need to be somewhere anywhere in the user's project directory or it parent chain (on a side note, it probably applies to this also). We need better way to inform what the user need to do to support .vue and .ts file types.

eslint-plugin-vue seems to have vue-eslint-parser as a dependency. I'm fine with adding vue-eslint-parser as a dependency to this project and add .vue to default eslint files.

Maybe it's better to use eslint-plugin-vue or both instead, but we need to make sure we can use them without activating any linting rules. That should be up to each user.

Someone with better understanding of eslint internal can probably help here. Because I'm not sure if including the parser as a dependency of prettier-eslint will help. When lookup for vue-eslint-parser is done, is it originating from 1 the file that is being linted, 2 the location of .eslintrc, or 3 the eslint engine location, or some combinations of these?

Found a way to address the parser lookup issue by using require.resolve. I have set up a PR. Maintainer may comment if this solution suits the project.

Stale issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

m-diiorio picture m-diiorio  路  6Comments

chrisdrackett picture chrisdrackett  路  10Comments

cellog picture cellog  路  3Comments

kripod picture kripod  路  5Comments

Dimomir picture Dimomir  路  5Comments