i18next / i18next-parser

Parse your code to extract translation keys/values and manage your catalog files
MIT License
488 stars 199 forks source link

Add react node customization options to JsxLexer #803

Closed josh-egan closed 1 year ago

josh-egan commented 1 year ago

šŸš€ Feature Proposal

The JsxLexer currently has a hard-coded value of 'Trans'which it looks for when it is parsing. See https://github.com/i18next/i18next-parser/blob/ee4092d6e43a25b3a8d1890db102beae0bf7a0d7/src/lexers/jsx-lexer.js#L91. I would like to propose making this customizable through options. I propose that the behavior be made to work similarly to how the JavascriptLexer allows specifying custom namespace functions. See https://github.com/i18next/i18next-parser/blob/c729ddd218930951e2a50c35c2b5a5c78b0b9ddf/src/lexers/javascript-lexer.js#L10-L13

This option could perhaps be called componentFunctions, but I don't feel strongly about the name, whatever makes sense. I would propose that ['Trans'] be the default value for this option, which could be overridden through the config file.

Motivation

Because this library requires the use of string literals for parsing, this creates an environment where it is easy to make mistakes when typing out a namespace. In our experience, it is a common mistake to have a typo in the namespace string. This ends up creating a new namespace file. Ideally these mistakes would be caught during the development or code review process, but they fail silently and are hard to spot and some engineers aren't particularly thorough in their code reviews. So these errors continue to slip into our code base.

Since our code base uses Typescript, I have written a wrapper around useTranslation that uses type safety to ensure that the string provided is one of our defined namespaces. I have given the wrapper function a custom name (useTranslate) to avoid name collisions with the original function that may accidentally lead to auto-importing the wrong module. Now, I would like to do the same with the <Trans> component. I have written a custom wrapper component that is type safe. I would love to make the custom component use a different name so that we don't have a name collision, which will inevitably lead to auto-importing the wrong module.

Example

If this feature is implemented, the options would be specified in the config file. For example:

{
  ...,
    lexers: {
      js: [
        {
          lexer: 'JsxLexer',
          functions: ['t'],
          namespaceFunctions: ['useTranslation', 'useTranslate'],
          componentFunctions: ['Trans', 'Translate'],
        },
      ],
    },
}
karellm commented 1 year ago

Deployed as 7.8.0