Error when used with eslint-plugin-graphql in v2.5.0
Closed this issue ยท 12 comments
What version of eslint
are you using?
4.15.0
What version of prettier
are you using?
1.10.2
What version of eslint-plugin-prettier
are you using?
2.5.0
Please paste any applicable config files that you're using (e.g. .prettierrc
or .eslintrc
files)
Relevant rules:
{
'prettier/prettier': [
1,
{
printWidth: 120,
trailingComma: 'es5',
singleQuote: true,
semi: false,
},
],
'graphql/template-strings': [
2,
{
env: 'literal',
schemaJson: require('./graphql/schema.json'),
},
],
}
What source code are you linting?
This seems to happen for any .graphql
file while using eslint-plugin-graphql
(I'm on version 1.4.1).
What did you expect to happen?
It should lint correctly.
What actually happened?
In eslint-plugin-prettier
2.4.0
everything works, but since 2.5.0
I get the following error:
Syntax Error: Unexpected Name "ESLintPluginGraphQLFile" (1:1)
> 1 | ESLintPluginGraphQLFile`#import "./redacted-file-name.graphql"
| ^
Assuming this has to do with the plugin now passing the filename to prettier, and eslint-plugin-graphql causes graphql files to have a weird filename reported somehow?
Could you provide the contents of your graphql
file? (If the file is confidential, you could also provide a different file that causes the same error.)
It's the same with any file. Example:
query TaskCount($organizationShortName: ID!, $filter: String!, $sort: [String], $skip: Int) {
organization: organizationByShortName(shortName: $organizationShortName) {
id
tasks(filter: $filter, sort: $sort, skip: $skip) {
totalCount
}
}
}
It seems like this is happening because eslint-plugin-graphql
uses a processor on a graphql
file to allow it to be read as JavaScript, so the text received by eslint-plugin-prettier
is JavaScript rather than graphql. However, since eslint-plugin-prettier
is passing the .graphql
file extension to prettier
, prettier
is trying to parse the JavaScript as GraphQL, resulting in a parse error.
A similar problem would probably occur when using other processors (e.g. eslint-plugin-markdown
), because prettier would get the embedded JavaScript and treat it as a markdown file due to the filename.
This makes me think that maybe it wasn't a good idea to pass the filename to prettier
to change the parsing mode. Essentially, there are two types of filenames:
- JavaScript variants, where the can be parsed directly as JavaScript with some syntax extensions determined by the file extension (e.g.
.jsx
,.vue
) - File formats containing embedded JavaScript, where the JavaScript is extracted by a processor (e.g.
.html
,.md
,.ejs
,.graphql
*)
Passing the filename to prettier
works well for the first case, but not for the second case.
*GraphQL doesn't actually have embedded JavaScript, but it's handled by a processor in the same way.
Yeah, if that's the case it seems like there could be a number of similar problems with other file types. ๐
@not-an-aardvark @eldh I'm running into this exact same problem and curious if there are any work arounds?
As a workaround, you could downgrade to eslint-plugin-prettier@2.4.0
.
I'd like to solve this issue, but I'm not sure what the best solution would be. We could add a configuration option for users to avoid passing in the filename to prettier
, but that doesn't seem very user-friendly (it would probably be pretty difficult to explain to users what the option does). Maybe it would be a good idea to add something to ESLint core so that rules can tell when a processor is being run, but that seems a bit leaky too.
Yeah I've pinned version to 2.4.0 for now.
Good call. The work around was right there in the original issue description. Sorry for not reading more closely and thanks for the quick responses.
Hi, I've the same issue with the 5.6.2 version.
Is something planned about this?
Thanks.
I haven't figured out a better solution, so I think the best way forward might just be to add an option to eslint-plugin-prettier
like processedFileExtensions: ['graphql', ...]
that would prevent it from using prettier
's filetype inference on files with the given extensions.
I found that its also possible to work around this problem without downgrading eslint-plugin-prettier
by instead using its configuration option to specify the parser:
rules: {
'prettier/prettier': [1, {
parser: 'babylon',
}],
},
Not sure if this has any unintended side effects - I assume not, since you would not need to use anything except a javascript parser from within eslint (which only deals with javascript).
After doing some deep pondering trying to wrangle this. I believe I understand what is going on and the best way for fix this.
I don't think there needs to be a processedFileExtensions
option. Instead people can disable the prettier rule for a subset of files using eslint overrides. Add an overrides section to the bottom of your eslint config, after your rules: {}
like so:
{
"rules": {},
"overrides": [
{
"files": ["*.graphql", "*.gql"],
"rules": {
"prettier/prettier": "off"
}
}
]
}
This shall disable the prettier rules for graphql, instead of forcing the parser to be potentially incorrect for all files.
The problem occurs because eslint-plugin-graphql registers an eslint processor that runs over .graphql
and .gql
files which transforms those files into a block of JS that eslint can understand (basically wrapping the file content in a tagged template literal so it becomes valid JS). This processor runs for all files before all rules, and there is no way to say "only allow this parser for a subset of rules". This is reasonable as processors are designed to extract javascripty parts from a file rather than teach eslint about a whole new language and you'd want all existing rules to run over those pieces of extracted JS.
I don't think there is any value in forcing the parser for graphql files as the processor is not considered autofixable and the processor currently swallows up all linting issues that aren't their own rules. Thus issues raised by the prettier/prettier rule would never be visible and would never be autofixed. There is no point in running prettier over these files if the results will never be exposed. If eslint-plugin-graphql fixes their code to expose rule violations other than their own then it would be straightforward to enable prettier, but forcing the 'babylon' parser, for graphql and gql:
{
"rules": {},
"overrides": [
{
"files": ["*.graphql", "*.gql"],
"rules": {
"prettier/prettier": ["error", {"parser": "babylon"}]
}
}
]
}