feat: support localisation of rule messages#141
Conversation
| This is a similar situation to JavaScript libraries which don't want to maintain TypeScript definitions. | ||
| In this case, contributors can maintain the types in [DefinitelyTyped](http://github.com/DefinitelyTyped/DefinitelyTyped). | ||
|
|
||
| This RFC proposes an equivalent monorepo, tentatively called "_eslint-translations_". |
There was a problem hiding this comment.
Really interesting idea, and not only addresses the problem of plugin authors "not wanting to maintain" their own translations, but also plugin authors that just haven't had the chance to add them yet (also a similar use case for Definitely Type).
One question I'd have is, who are you proposing is responsible for maintaining this new monorepo, and who would own the npm scope? While the DT repo is intentionally self serve, I'm sure it took a lot of engineering effort to build out the tooling to make it that way. Who would be doing that initial build-out? You have the governance listed in open questions, but I think there's more than ongoing maintenance / governance that would need to be figured out.
There was a problem hiding this comment.
At the very least, I hope this could be an eslint-community project, for the same reasons mentioned in RFC #91. That means the npm scope @eslint-translations/* could be owned and managed in the way as @eslint-community/*.
In terms of maintenance: I'm happy to assist myself, but I don't have any 'reputation' amongst the eslint community: the open-source projects I maintain are all unrelated to eslint, I only contribute occasional PRs to eslint plugins. With that said, I would certainly volunteer to do the initial build-out and ongoing maintenance, if everyone is happy with this.
| **Case 2:** If translations cannot be found in the rule itself, we need to: | ||
|
|
||
| - check if `@eslint-translations/{packageName}` exists with `require.resolve` | ||
| - if yes, read that package and check if it contains a matching language |
There was a problem hiding this comment.
What would the structure of these language packages look like? Is it a single default export with similar shape as the message_translations prop under meta?
There was a problem hiding this comment.
yes, I think that's the only thing that needs to be exported. Either:
export default {
'es': { avoidName: 'Evite utilizar variables llamadas {{name}}' },
'zh-Hans': { avoidName: '避免使用名为{{name}}的变量' },
}or perhaps a seperate file for each language. For example es.js[on]:
export default {
avoidName: 'Evite utilizar variables llamadas {{name}}'
}There was a problem hiding this comment.
My comment above was incorrect. A third-party translation package also needs to define the rule name, since messageIds are not globally-unique.
So the structure would be more like:
// es-ES.js
export default {
'optimal-quantifier-concatenation': {
avoidName: 'Evite utilizar variables llamadas {{name}}'
},
'no-constant-condition': {
error: 'condición constante inesperada'
}
}There was a problem hiding this comment.
Would it make sense to include some mention of that (and maybe this example) in the RFC text?
|
Thanks for the RFC @k-yle! I'm not sure I see a strong benefit in introducing a framework for translating rule messages while the rest of ESLint, including core, CLI, built-in formatters, etc., would remain untranslated. ESLint contains a wide range of messages, many of which aren't even grouped in conceptual units, and just appear as standalone strings in the codebase ("Oops! Something went wrong! :("). From what I've seen, this pattern is fairly common across many software projects. If internationalization is a goal, I think it would make more sense to start from the core outward: establish a machanism for translating ESLint's own messages first, and then consider rules and plugins. Even then, I'm unsure whether the added maintenance cost would be justified. For example, our non-English sites like https://zh-hans.eslint.org/ receive very little traffic despite the enthusiasm some contributors have for providing translations. Anyway, this is just my opinion, and I'd be interested to hear how others feel about this proposal. |
|
From my experience, users very rarely encounter eslint's core messages, except when updating the configuration file, which they might do once every few months. On the other hand, rule-messages are seen hundreds of times per day. So rule-messages are significantly more important than core-messages, and arguably even more important than docs. Another key point: eslint rules are effectively a teaching resource for junior engineers. If you don't speak English well, it's time-consuming to understand a complex error, and it's very tempting just to click Fix with AI in your IDE, instead of reading the message and learning. Regarding your maintenance cost concerns @fasttime: could you please clarify whether you're refering to the (very minimal) changes required in eslint-core, or the complexity of the seperate translations repository? |
|
Thanks for looking into this. While I understand the idea behind this, I just don't think it's practical given the nature of the ESLint ecosystem. Creating a DefinitelyTyped-style solution is just maintenance overhead with very little overall benefit. Whenever rule messages change, there would be a lag between that and when the separately-managed packages were updated. Plus, I think it's much easier for someone who doesn't know english to paste the error message into Google, find the documentation, and then have the browser translate the documentation into their preferred language. That will actually give the useful context they are looking for. So overall, I'm 👎 to this proposal. |
|
okay, would a much simpler proposal have any chance of proceeding? For example, if we completely remove the third-party translation idea, any only allow plugins to define That part of the proposal is quite trivial to implement in eslint-core, and gives plugins authors full control over whether they want to allow translations. |

This is an RFC for eslint/eslint#19210, which superseeds #128. Copying the document's first section:
Summary
This RFC proposes adding localisation support for rule messages. This allows rules to define messages in multiple langauges, not just English.
Translations could be defined by plugin authors, or in a third-party package, similar to the
@types/*ecosystem.For example, instead of:
Someone who prefers Japanese would see:
(example from eslint-plugin-regexp)