-
-
Notifications
You must be signed in to change notification settings - Fork 70
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
feat: support localization for rule messages #128
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
- Repo: eslint/eslint | ||
- Start Date: 2024-12-09 | ||
- RFC PR: (leave this empty, to be filled in later) | ||
- Authors: [gweesin](https://github.com/gweesin) | ||
|
||
# Support Localization of Rule Messages | ||
|
||
## Summary | ||
|
||
<!-- One-paragraph explanation of the feature. --> | ||
|
||
This RFC proposes adding support for localization of rule messages in ESLint. The goal is to allow users to provide translations for rule messages, enabling ESLint to display messages in different languages based on user preferences. This feature aims to improve the accessibility and usability of ESLint for non-English speaking users. | ||
|
||
## Motivation | ||
|
||
<!-- Why are we doing this? What use cases does it support? What is the expected | ||
outcome? --> | ||
|
||
The primary motivation for this feature is to make ESLint more accessible to a global audience. Currently, ESLint rule messages are only available in English, which can be a barrier for non-English speaking users. By allowing rule messages to be localized, we can improve the user experience for developers who prefer to work in their native language. This change will help ESLint reach a broader audience and make it easier for developers around the world to understand and fix linting issues in their code. | ||
|
||
## Detailed Design | ||
|
||
<!-- | ||
This is the bulk of the RFC. | ||
|
||
Explain the design with enough detail that someone familiar with ESLint | ||
can implement it by reading this document. Please get into specifics | ||
of your approach, corner cases, and examples of how the change will be | ||
used. Be sure to define any new terms in this section. | ||
--> | ||
|
||
To implement localization of rule messages in ESLint, we will support two ways to define the localization information: | ||
|
||
1. Support for plugin definition messages with locale files. | ||
plugins can define localized messages directly within their rule definitions so that all the messages can be supported in the same repository. This approach allows plugin authors to provide translations for their rule messages without relying on external files. | ||
|
||
Example: | ||
|
||
```js | ||
module.exports = { | ||
meta: { | ||
messages: { | ||
someMessageId: { | ||
en: "Default message in English", | ||
es: "Mensaje predeterminado en español" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of overloading message IDs like this. I'd rather introduce another key, |
||
} | ||
} | ||
}, | ||
create(context) { | ||
return { | ||
Identifier(node) { | ||
context.report({ | ||
node, | ||
messageId: "someMessageId" | ||
}); | ||
} | ||
}; | ||
} | ||
}; | ||
``` | ||
|
||
2. Support a way using `eslint.config.js` file to configure message info by message ID. | ||
This way should allow users to provide some plugins to update other plugins' messages. This approach allows users to customize the messages for rules provided by plugins. | ||
|
||
Example: | ||
|
||
```js | ||
module.exports = { | ||
locale: "es", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does Does it only apply to files matching There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just define the expected language the user wants to see in the lint error messages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I think I was unclear. If you have a config like this: {
files: ["**/*.js"],
locale: "es"
} That config is only applied when the file being linted matches |
||
rules: [/* ... */], | ||
messages: { | ||
"plugin/ruleId": { | ||
someMessageId: "Mensaje predeterminado en español" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you intending for people to include their own translations in config files? Or pulling in from somewhere else? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also pointing out that message ids aren't generally public api of a plugin. This approach would change that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think we should provide three ways to include translations:
So it is part of the way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This seems to be a challenge, but I'd like to avoid making a breaking change for this if possible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I think for this to work, we need to just say that message IDs are part of the public API. Unless we want to force every rule to maintain its own translations, I think that's our only option. |
||
} | ||
} | ||
}; | ||
Comment on lines
+68
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you clarify this structure? Does this mean that provided There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the locale means user want to use 'es' language, and the messages means some plugins haven't support a language message so that user can override it by theirself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gweesin please add that description into the RFC. |
||
``` | ||
|
||
and eslint will use the message info to replace the message in the rule if the message ID is found in the configuration. | ||
|
||
for corner cases, we need to consider the following: | ||
|
||
1. If a translation is missing for a specific language, ESLint should fall back to the default English message. | ||
2. ESLint should support original flat rules structure and the new structure with localized messages. | ||
|
||
## Documentation | ||
|
||
<!-- | ||
How will this RFC be documented? Does it need a formal announcement | ||
on the ESLint blog to explain the motivation? | ||
--> | ||
|
||
1. Update the official ESLint documentation to include information on how to create and use localization files. | ||
2. Provide examples and guidelines for contributing translations, including third party integrations. | ||
|
||
## Drawbacks | ||
|
||
<!-- | ||
Why should we *not* do this? Consider why adding this into ESLint | ||
might not benefit the project or the community. Attempt to think | ||
about any opposing viewpoints that reviewers might bring up. | ||
|
||
Any change has potential downsides, including increased maintenance | ||
burden, incompatibility with other tools, breaking existing user | ||
experience, etc. Try to identify as many potential problems with | ||
implementing this RFC as possible. | ||
--> | ||
|
||
1. Increased Maintenance Burden: Adding support for localization will increase the complexity of the ESLint codebase. Maintaining translations and ensuring they are up-to-date with rule changes will require additional effort from both the core team and contributors. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also increases the download size. |
||
2. It's better to use a module to handle the localization such as typescript using `@types/some-module` but it's not possible to use a module to handle the localization in ESLint. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What part isn't possible? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to scan the entire node_modules directory to locate the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I can research it further to see if this approach is worth pursuing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see. Yes, we don't want ESLint to scan the |
||
3. Potential for Incomplete Translations: There is a risk that some languages may have incomplete translations, leading to a mix of localized and default English messages. | ||
This could confuse users and reduce the overall effectiveness of the feature. | ||
|
||
## Backwards Compatibility Analysis | ||
|
||
<!-- | ||
How does this change affect existing ESLint users? Will any behavior | ||
change for them? If so, how are you going to minimize the disruption | ||
to existing users? | ||
--> | ||
|
||
This change should not affect existing ESLint users who do not use the localization feature. Users who do not provide translations will continue to see the default English messages. To minimize disruption, ESLint should provide clear documentation on how to create and use localization files, as well as guidelines for contributing translations. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Backwards compatibility analysis should consider plugin compatibility as well as end user / config compatibility. What's the implication to plugin authors who haven't set up the locale-based message ids in their rules? |
||
|
||
## Alternatives | ||
|
||
<!-- | ||
What other designs did you consider? Why did you decide against those? | ||
|
||
This section should also include prior art, such as whether similar | ||
projects have already implemented a similar feature. | ||
--> | ||
|
||
1. TypeScript `--locale` option: This option allows users to specify the locale for the TypeScript compiler, which affects the language service features. However, this approach is limited to the TypeScript compiler and does not provide a general solution for localization in ESLint. | ||
> [TypeScript compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html#compiler-options) | ||
> https://github.com/eslint/eslint/issues/9870#issuecomment-359228967 | ||
|
||
why not? because almost all the messages are provided by third party plugins, so it's not possible to handle the localization in the core. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why can't we consider an approach where translations are provided by third party plugins? |
||
|
||
2. Is it possible to check `@locale/module` in the same way as `@type/module`? | ||
|
||
## Open Questions | ||
|
||
<!-- | ||
This section is optional, but is suggested for a first draft. | ||
|
||
What parts of this proposal are you unclear about? What do you | ||
need to know before you can finalize this RFC? | ||
|
||
List the questions that you'd like reviewers to focus on. When | ||
you've received the answers and updated the design to reflect them, | ||
you can remove this section. | ||
--> | ||
|
||
## Help Needed | ||
|
||
<!-- | ||
This section is optional. | ||
|
||
Are you able to implement this RFC on your own? If not, what kind | ||
of help would you need from the team? | ||
--> | ||
|
||
I sure I can implement this RFC on my own. | ||
|
||
## Frequently Asked Questions | ||
|
||
<!-- | ||
This section is optional but suggested. | ||
|
||
Try to anticipate points of clarification that might be needed by | ||
the people reviewing this RFC. Include those questions and answers | ||
in this section. | ||
--> | ||
|
||
## Related Discussions | ||
|
||
<!-- | ||
This section is optional but suggested. | ||
|
||
If there is an issue, pull request, or other URL that provides useful | ||
context for this proposal, please include those links here. | ||
--> | ||
|
||
- https://github.com/eslint/eslint/issues/19210 | ||
- https://github.com/eslint/eslint/issues/9870 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note, you'll need to provide a description of how this would be implemented for the RFC to move forward.