Skip to content

Commit

Permalink
feat(no-unlocalized-strings): remove default configuration (#78)
Browse files Browse the repository at this point in the history
* remove default configuration
* ignore non letter strings by default
* allow numbers in uppercase regex
* merge ignoreAttribute, ignoreProperty, and ignoreVariable into ignoreNames
*remove strictAttribute option
  • Loading branch information
timofei-iatsenko authored Nov 14, 2024
1 parent e249254 commit 32c823c
Showing 5 changed files with 318 additions and 511 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ yarn add eslint-plugin-lingui --dev

### Recommended Setup

To enable all of the recommended rules for our plugin, add the following config:
To enable all the recommended rules for our plugin, add the following config:

```js
import pluginLingui from 'eslint-plugin-lingui'
@@ -47,6 +47,8 @@ export default [
]
```

We also recommend enabling the [no-unlocalized-strings](docs/rules/no-unlocalized-strings.md) rule. It’s not enabled by default because it needs to be set up specifically for your project. Please check the rule's documentation for example configurations.

### Custom setup

Alternatively, you can load the plugin and configure only the rules you want to use:
242 changes: 98 additions & 144 deletions docs/rules/no-unlocalized-strings.md
Original file line number Diff line number Diff line change
@@ -5,18 +5,78 @@ Ensures that all string literals, templates, and JSX text are wrapped using `<Tr
> [!IMPORTANT]
> This rule may require TypeScript type information. Enable this feature by setting `{ useTsTypes: true }`.
This rule is designed to **match all** JSXText, StringLiterals, and TmplLiterals, and then exclude some of them based on attributes, property names, variable names, and so on.

The rule doesn’t come with built-in ignore settings because each project is unique and needs different configurations. You can use the following config as a starting point and then adjust it for your project:

<!-- prettier-ignore -->
```json5
{
"no-unlocalized-strings": [
"error",
{
"ignore": [
// Ignore strings that don’t start with an uppercase letter
// or don't contain two words separated by whitespace
"^(?![A-Z].*|\\w+\\s\\w+).+$",
// Ignore UPPERCASE literals
// Example: const test = "FOO"
"^[A-Z0-9_-]+$"
],
"ignoreNames": [
// Ignore matching className (case-insensitive)
{ "regex": { "pattern": "className", "flags": "i" } },
// Ignore UPPERCASE names
// Example: test.FOO = "ola!"
{ "regex": { "pattern": "^[A-Z0-9_-]+$" } },
"styleName",
"src",
"srcSet",
"type",
"id",
"width",
"height",
"displayName",
"Authorization"
],
"ignoreFunctions": [
"cva",
"cn",
"track",
"Error",
"console.*",
"*headers.set",
"*.addEventListener",
"*.removeEventListener",
"*.postMessage",
"*.getElementById",
"*.dispatch",
"*.commit",
"*.includes",
"*.indexOf",
"*.endsWith",
"*.startsWith",
"require"
],
// Following settings require typed linting https://typescript-eslint.io/getting-started/typed-linting/
"useTsTypes": true,
"ignoreMethodsOnType": [
// Ignore specified methods on Map and Set types
"Map.get",
"Map.has",
"Set.has"
]
}
]
}
```

## Options

### `useTsTypes`

Enables the rule to use TypeScript type information. Requires [typed linting](https://typescript-eslint.io/getting-started/typed-linting/) to be configured.

This option automatically excludes built-in methods such as `Map` and `Set`, and cases where string literals are used as TypeScript constants, e.g.:

```ts
const a: 'abc' = 'abc'
```

### `ignore`

Specifies patterns for string literals to ignore. Strings matching any of the provided regular expressions will not trigger the rule.
@@ -28,17 +88,17 @@ Example for `{ "ignore": ["rgba"] }`:
const color = <div style={{ color: 'rgba(100, 100, 100, 0.4)' }} />
```

### `ignoreFunction`
### `ignoreFunctions`

Specifies functions whose string arguments should be ignored.

Example of `correct` code with this option:

```js
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunction": ["showIntercomMessage"]}]*/
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunctions": ["showIntercomMessage"]}]*/
showIntercomMessage('Please write me')

/*eslint lingui/no-unlocalized-strings: ["error", { "ignoreFunction": ["cva"] }]*/
/*eslint lingui/no-unlocalized-strings: ["error", { "ignoreFunctions": ["cva"] }]*/
const labelVariants = cva('text-form-input-content-helper', {
variants: {
size: {
@@ -49,131 +109,60 @@ const labelVariants = cva('text-form-input-content-helper', {
})
```

This option also supports member expressions. Example for `{ "ignoreFunction": ["console.log"] }`:
This option also supports member expressions. Example for `{ "ignoreFunctions": ["console.log"] }`:

```js
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunction": ["console.log"]}]*/
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunctions": ["console.log"]}]*/
console.log('Log this message')
```

You can use patterns (processed by [micromatch](https://www.npmjs.com/package/micromatch)) to match function calls.

```js
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunction": ["console.*"]}]*/
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunctions": ["console.*"]}]*/
console.log('Log this message')
```

```js
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunction": ["*.headers.set"]}]*/
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunctions": ["*.headers.set"]}]*/
context.headers.set('Authorization', `Bearer ${token}`)
```

Dynamic segments are replaced with `$`, you can target them as

```js
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunction": ["foo.$.set"]}]*/
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreFunctions": ["foo.$.set"]}]*/
foo[getName()].set('Hello')
```

### `ignoreAttribute`

Specifies JSX attributes that should be ignored. By default, the attributes `className`, `styleName`, `type`, `id`, `width`, and `height` are ignored.

Example for `{ "ignoreAttribute": ["style"] }`:

```jsx
/*eslint lingui/no-unlocalized-strings: ["error", {"ignoreAttribute": ["style"]}]*/
const element = <div style={{ margin: '1rem 2rem' }} />
```

#### `regex`

Defines regex patterns for ignored attributes.

Example:

```json
{
"no-unlocalized-strings": [
"error",
{
"ignoreAttribute": [
{
"regex": {
"pattern": "classname",
"flags": "i"
}
}
]
}
]
}
```

Example of **correct** code:

```jsx
const element = <div wrapperClassName="absolute top-1/2 left-1/2" />
```

### `strictAttribute`

Specifies JSX attributes that should always be checked, regardless of other `ignore` settings or defaults.

Example for `{ "strictAttribute": ["alt"] }`:
### `ignoreNames`

```jsx
/*eslint lingui/no-unlocalized-strings: ["error", {"strictAttribute": ["alt"]}]*/
const element = <img alt="IMAGE" />
```

#### `regex`

Defines regex patterns for attributes that must always be checked.

Example:
List of identifier names to ignore across attributes, properties, and variables. Use this option to exclude specific names, like "className", from being flagged by the rule. This option covers any of these contexts: JSX attribute names, variable names, or property names.

```json
{
"no-unlocalized-strings": [
"error",
{
"strictAttribute": [
{
"regex": {
"pattern": "^desc.*"
}
}
]
}
]
}
```
Example for `{ "ignoreNames": ["style"] }`:

Examples of **incorrect** code:
Example of `correct` code with this option:

```jsx
const element = <div description="IMAGE" />
```

### `ignoreProperty`

Specifies object property names whose values should be ignored. By default, UPPERCASED properties and `className`, `styleName`, `type`, `id`, `width`, `height`, and `displayName` are ignored.

Example for `{ "ignoreProperty": ["myProperty"] }`:
/* eslint lingui/no-unlocalized-strings: ["error", {"ignoreNames": ["style"]}] */
// ignored by JSX sttribute name
const element = <div style={{ margin: '1rem 2rem' }} />
// ignored by variable name
const style = 'Ignored value!'

```jsx
const obj = { myProperty: 'Ignored value' }
obj.myProperty = 'Ignored value'
/* eslint lingui/no-unlocalized-strings: ["error", {"ignoreNames": ["displayName"]}] */
// ignored by property name
const obj = { displayName: 'Ignored value' }
obj.displayName = 'Ignored value'

class MyClass {
myProperty = 'Ignored value'
displayName = 'Ignored value'
}
```

#### `regex`

Defines regex patterns for ignored properties.
Defines regex patterns for ignored names.

Example:

@@ -182,7 +171,7 @@ Example:
"no-unlocalized-strings": [
"error",
{
"ignoreProperty": [
"ignoreNames": [
{
"regex": {
"pattern": "classname",
@@ -195,9 +184,16 @@ Example:
}
```

Examples of **correct** code:
Example of **correct** code:

```jsx
// ignored by JSX attribute name
const element = <div wrapperClassName="absolute top-1/2 left-1/2" />

// ignored by variable name
const wrapperClassName = 'Ignored value'

// ignored by property name
const obj = { wrapperClassName: 'Ignored value' }
obj.wrapperClassName = 'Ignored value'

@@ -206,46 +202,6 @@ class MyClass {
}
```

### `ignoreVariable`

Specifies variable name whose values should be ignored. By default, UPPERCASED variables are ignored.

Example for `{ "ignoreVariable": ["myVariable"] }`:

```jsx
const myVariable = 'Ignored value'
```

#### `regex`

Defines regex patterns for ignored variables.

Example:

```json
{
"no-unlocalized-strings": [
"error",
{
"ignoreVariable": [
{
"regex": {
"pattern": "classname",
"flags": "i"
}
}
]
}
]
}
```

Examples of **correct** code:

```jsx
const wrapperClassName = 'Ignored value'
```

### `ignoreMethodsOnTypes`

Uses TypeScript type information to ignore methods defined on specific types.
@@ -264,5 +220,3 @@ interface Foo {
const foo: Foo
foo.get('Some string')
```

The following methods are ignored by default: `Map.get`, `Map.has`, `Set.has`.
Loading

0 comments on commit 32c823c

Please sign in to comment.