@intlayer/docs 9.3.1 → 9.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/de/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/en/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/en-GB/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/es/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/fr/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/hi/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/id/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/it/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/ja/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/ko/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/pl/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/pt/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/ru/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/tr/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/uk/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/vi/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/zh/nextjs-multilingual-seo-comparison.md +10 -10
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/bundle_optimization.md +1 -1
- package/docs/ar/configuration.md +32 -9
- package/docs/ar/dictionary/content_file.md +0 -22
- package/docs/ar/dictionary/function_fetching.md +23 -0
- package/docs/ar/eslint.md +336 -0
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/bn/configuration.md +34 -9
- package/docs/bn/eslint.md +336 -0
- package/docs/cs/bundle_optimization.md +1 -1
- package/docs/cs/configuration.md +33 -9
- package/docs/cs/eslint.md +336 -0
- package/docs/de/bundle_optimization.md +1 -1
- package/docs/de/configuration.md +34 -9
- package/docs/de/dictionary/content_file.md +0 -22
- package/docs/de/dictionary/function_fetching.md +23 -0
- package/docs/de/eslint.md +336 -0
- package/docs/en/bundle_optimization.md +1 -1
- package/docs/en/configuration.md +34 -9
- package/docs/en/dictionary/content_file.md +0 -22
- package/docs/en/dictionary/function_fetching.md +23 -0
- package/docs/en/eslint.md +336 -0
- package/docs/en/packages/intlayer/getLocalizedPath.md +70 -19
- package/docs/en-GB/configuration.md +33 -9
- package/docs/en-GB/dictionary/content_file.md +0 -22
- package/docs/en-GB/dictionary/function_fetching.md +23 -0
- package/docs/en-GB/eslint.md +336 -0
- package/docs/en-GB/intlayer_with_create_react_app.md +32 -35
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/es/bundle_optimization.md +1 -1
- package/docs/es/configuration.md +35 -9
- package/docs/es/dictionary/content_file.md +0 -22
- package/docs/es/dictionary/function_fetching.md +23 -0
- package/docs/es/eslint.md +336 -0
- package/docs/fr/bundle_optimization.md +1 -1
- package/docs/fr/configuration.md +35 -9
- package/docs/fr/dictionary/content_file.md +0 -22
- package/docs/fr/dictionary/function_fetching.md +23 -0
- package/docs/fr/eslint.md +336 -0
- package/docs/hi/configuration.md +35 -9
- package/docs/hi/dictionary/content_file.md +0 -22
- package/docs/hi/dictionary/function_fetching.md +23 -0
- package/docs/hi/eslint.md +336 -0
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/hi/intlayer_with_vite+svelte.md +2 -2
- package/docs/id/configuration.md +35 -9
- package/docs/id/dictionary/content_file.md +0 -22
- package/docs/id/dictionary/function_fetching.md +23 -0
- package/docs/id/eslint.md +336 -0
- package/docs/it/bundle_optimization.md +1 -1
- package/docs/it/configuration.md +35 -9
- package/docs/it/dictionary/content_file.md +0 -22
- package/docs/it/dictionary/function_fetching.md +23 -0
- package/docs/it/eslint.md +336 -0
- package/docs/ja/configuration.md +30 -9
- package/docs/ja/dictionary/content_file.md +0 -22
- package/docs/ja/dictionary/function_fetching.md +23 -0
- package/docs/ja/eslint.md +336 -0
- package/docs/ja/intlayer_with_react_router_v7.md +1 -146
- package/docs/ja/intlayer_with_vite+react.md +5 -1
- package/docs/ko/configuration.md +31 -9
- package/docs/ko/dictionary/content_file.md +0 -22
- package/docs/ko/dictionary/function_fetching.md +23 -0
- package/docs/ko/eslint.md +336 -0
- package/docs/ko/intlayer_with_lynx+react.md +4 -0
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/ko/intlayer_with_storybook.md +5 -5
- package/docs/nl/configuration.md +33 -9
- package/docs/nl/eslint.md +336 -0
- package/docs/pl/bundle_optimization.md +1 -1
- package/docs/pl/configuration.md +34 -9
- package/docs/pl/dictionary/content_file.md +0 -22
- package/docs/pl/dictionary/function_fetching.md +23 -0
- package/docs/pl/eslint.md +336 -0
- package/docs/pl/intlayer_with_astro.md +1 -114
- package/docs/pl/migration_from_i18next_to_intlayer.md +4 -0
- package/docs/pl/migration_from_next-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_next-intl_to_intlayer.md +11 -5
- package/docs/pl/migration_from_nuxtjs_i18n_to_intlayer.md +8 -4
- package/docs/pl/migration_from_react-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_vue-i18n_to_intlayer.md +4 -0
- package/docs/pt/bundle_optimization.md +1 -1
- package/docs/pt/configuration.md +34 -9
- package/docs/pt/dictionary/content_file.md +0 -22
- package/docs/pt/dictionary/function_fetching.md +23 -0
- package/docs/pt/eslint.md +336 -0
- package/docs/pt/intlayer_with_astro.md +1 -114
- package/docs/ru/bundle_optimization.md +1 -1
- package/docs/ru/configuration.md +34 -9
- package/docs/ru/dictionary/content_file.md +0 -22
- package/docs/ru/dictionary/function_fetching.md +23 -0
- package/docs/ru/eslint.md +336 -0
- package/docs/tr/bundle_optimization.md +1 -1
- package/docs/tr/configuration.md +33 -9
- package/docs/tr/dictionary/content_file.md +0 -22
- package/docs/tr/dictionary/function_fetching.md +23 -0
- package/docs/tr/eslint.md +336 -0
- package/docs/uk/configuration.md +35 -9
- package/docs/uk/dictionary/content_file.md +0 -22
- package/docs/uk/dictionary/function_fetching.md +23 -0
- package/docs/uk/eslint.md +336 -0
- package/docs/uk/packages/angular-intlayer/exports.md +2 -2
- package/docs/ur/configuration.md +35 -9
- package/docs/ur/eslint.md +336 -0
- package/docs/vi/bundle_optimization.md +1 -1
- package/docs/vi/configuration.md +33 -9
- package/docs/vi/dictionary/content_file.md +0 -22
- package/docs/vi/dictionary/function_fetching.md +23 -0
- package/docs/vi/eslint.md +336 -0
- package/docs/zh/bundle_optimization.md +1 -1
- package/docs/zh/configuration.md +29 -9
- package/docs/zh/dictionary/content_file.md +0 -22
- package/docs/zh/dictionary/function_fetching.md +23 -0
- package/docs/zh/eslint.md +336 -0
- package/docs/zh/intlayer_with_create_react_app.md +4 -0
- package/docs/zh/intlayer_with_lynx+react.md +4 -0
- package/docs/zh/intlayer_with_nextjs_14.md +0 -2
- package/docs/zh/intlayer_with_nextjs_15.md +0 -2
- package/docs/zh/intlayer_with_nextjs_page_router.md +0 -2
- package/docs/zh/intlayer_with_nuxt.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +4 -0
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +4 -0
- package/docs/zh/intlayer_with_solid_start.md +1 -1
- package/docs/zh/intlayer_with_vite+vue.md +0 -2
- package/docs/zh-TW/bundle_optimization.md +1 -1
- package/docs/zh-TW/eslint.md +336 -0
- package/package.json +7 -7
- package/src/generated/docs.entry.ts +20 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-08-12
|
|
3
|
+
updatedAt: 2026-08-13
|
|
4
|
+
title: Wtyczka ESLint | Reguły lintera dla Intlayer
|
|
5
|
+
description: Wykrywaj zahardkodowane ciągi znaków, wywołania dynamiczne, których kompilator Intlayer nie jest w stanie zoptymalizować, oraz nieużywaną zawartość słowników dzięki eslint-plugin-intlayer. Działa z ESLint i oxlint w React, Vue, Svelte, Angular i Astro.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- ESLint
|
|
9
|
+
- oxlint
|
|
10
|
+
- Linting
|
|
11
|
+
- i18n
|
|
12
|
+
- Internacjonalizacja
|
|
13
|
+
- no-raw-text
|
|
14
|
+
- Zahardkodowane ciągi znaków
|
|
15
|
+
- Nieużywane tłumaczenia
|
|
16
|
+
- Martwa zawartość
|
|
17
|
+
- React
|
|
18
|
+
- Vue
|
|
19
|
+
- Svelte
|
|
20
|
+
- Angular
|
|
21
|
+
slugs:
|
|
22
|
+
- doc
|
|
23
|
+
- eslint
|
|
24
|
+
history:
|
|
25
|
+
- version: 9.3.1
|
|
26
|
+
date: 2026-08-12
|
|
27
|
+
changes: "Inicjalna historia"
|
|
28
|
+
author: aymericzip
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# Wtyczka ESLint x OXLint
|
|
32
|
+
|
|
33
|
+
`eslint-plugin-intlayer` wychwytuje rodzaje błędów i18n, których TypeScript nie jest w stanie wykryć:
|
|
34
|
+
|
|
35
|
+
1. **Zahardkodowany tekst**, który nigdy nie trafił do słownika.
|
|
36
|
+
2. **Dynamiczne wywołania**, które przechodzą sprawdzanie typów i działają, ale których kompilator Intlayer nie potrafi zoptymalizować.
|
|
37
|
+
3. **Martwa zawartość (Dead content)** — słowniki i pola, których nic w projekcie nie odczytuje (opcjonalne).
|
|
38
|
+
|
|
39
|
+
Nieznane klucze słowników, nieznane ścieżki pól oraz brakujące ustawienia regionalne stanowią już błędy kompilacji, więc wtyczka ich nie powiela.
|
|
40
|
+
|
|
41
|
+
## Instalacja
|
|
42
|
+
|
|
43
|
+
```bash packageManager="npm"
|
|
44
|
+
npm install --save-dev eslint-plugin-intlayer
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash packageManager="pnpm"
|
|
48
|
+
pnpm add --save-dev eslint-plugin-intlayer
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash packageManager="yarn"
|
|
52
|
+
yarn add --dev eslint-plugin-intlayer
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Wymaga ESLint w wersji 9 lub nowszej (flat config). ESLint 10 jest wspierany.
|
|
56
|
+
|
|
57
|
+
## Użycie
|
|
58
|
+
|
|
59
|
+
Wtyczka działa zarówno w ESLint, jak i [oxlint](https://oxc.rs) — te same reguły, te same opcje.
|
|
60
|
+
|
|
61
|
+
<Tabs defaultTab="eslint">
|
|
62
|
+
<Tab label="ESLint" value="eslint">
|
|
63
|
+
|
|
64
|
+
```javascript fileName="eslint.config.mjs"
|
|
65
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
66
|
+
|
|
67
|
+
export default [...intlayer.configs.recommended];
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Albo rozwiń konfigurację i sam ustaw poziomy zgłoszeń:
|
|
71
|
+
|
|
72
|
+
```javascript fileName="eslint.config.mjs"
|
|
73
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
74
|
+
|
|
75
|
+
export default [
|
|
76
|
+
...intlayer.configs.recommended,
|
|
77
|
+
{
|
|
78
|
+
rules: {
|
|
79
|
+
"intlayer/no-raw-text": "warn",
|
|
80
|
+
"intlayer/static-dictionary-key": "error",
|
|
81
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
82
|
+
"intlayer/enforce-adapter-import": "warn",
|
|
83
|
+
"intlayer/no-unused-content": "warn",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
</Tab>
|
|
90
|
+
<Tab label="oxlint" value="oxlint">
|
|
91
|
+
|
|
92
|
+
```json fileName=".oxlintrc.json"
|
|
93
|
+
{
|
|
94
|
+
"jsPlugins": ["eslint-plugin-intlayer"],
|
|
95
|
+
"rules": {
|
|
96
|
+
"intlayer/no-raw-text": "warn",
|
|
97
|
+
"intlayer/static-dictionary-key": "error",
|
|
98
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
99
|
+
"intlayer/enforce-adapter-import": "warn"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Dwa zastrzeżenia: obsługa wtyczek JS w oxlint jest w fazie alfa, a oxlint nie obsługuje niestandardowych parserów — pliki `.vue`, `.svelte`, `.astro` oraz szablony Angular nie są tam sprawdzane. Uruchamiaj oxlint na plikach JS/TS/JSX, a ESLint pozostaw dla reszty.
|
|
105
|
+
|
|
106
|
+
Reguła `no-unused-content` została celowo pominięta powyżej: wymaga ona katalogu roboczego i ścieżki do sprawdzanego pliku z kontekstu reguły, czego mostek wtyczek JS w fazie alfa nie gwarantuje. Uruchamiaj ją pod ESLintem.
|
|
107
|
+
|
|
108
|
+
</Tab>
|
|
109
|
+
</Tabs>
|
|
110
|
+
|
|
111
|
+
### Konfiguracje
|
|
112
|
+
|
|
113
|
+
| Konfiguracja | `no-raw-text` | `static-dictionary-key` | `no-dynamic-field-access` | `enforce-adapter-import` | `no-unused-content` |
|
|
114
|
+
| --------------- | --------------------------- | ----------------------- | ------------------------- | ------------------------ | ------------------- |
|
|
115
|
+
| `recommended` | warn | error | error | off | off |
|
|
116
|
+
| `strict` | error (+ literały poza JSX) | error | error | error | off |
|
|
117
|
+
| `contract-only` | off | error | error | off | off |
|
|
118
|
+
|
|
119
|
+
`recommended` celowo utrzymuje `no-raw-text` na poziomie `warn`: uruchomienie jej na istniejącej bazie kodu ujawnia wszystkie nieprzetłumaczone ciągi znaków naraz, co nie powinno blokować procesu budowania od pierwszego dnia.
|
|
120
|
+
|
|
121
|
+
`enforce-adapter-import` jest domyślnie wyłączona — włącz ją jawnie, jeśli tego potrzebujesz.
|
|
122
|
+
|
|
123
|
+
`no-unused-content` jest wyłączona w każdej konfiguracji, w tym `strict`. Jest to jedyna reguła, która odczytuje konfigurację Intlayer i przeszukuje pliki źródłowe na dysku, więc jej włączenie powinno być świadomym wyborem, a nie domyślnym zachowaniem zestawu.
|
|
124
|
+
|
|
125
|
+
## Reguły
|
|
126
|
+
|
|
127
|
+
### `no-raw-text`
|
|
128
|
+
|
|
129
|
+
Zgłasza tekst widoczny dla użytkownika, który nie jest zadeklarowany w słowniku. Używa tej samej metody detekcji co `intlayer extract`, dzięki czemu nazwy marek, klasy CSS i identyfikatory techniczne są ignorowane.
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
// ✗ Zgłoszone
|
|
133
|
+
<h1>Welcome to our documentation</h1>
|
|
134
|
+
<input placeholder="Enter your email address" />
|
|
135
|
+
|
|
136
|
+
// ✓ Prawidłowo
|
|
137
|
+
const { title } = useIntlayer("home");
|
|
138
|
+
<h1>{title}</h1>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Pliki deklaracji zawartości (`*.content.ts`, …) są pomijane.
|
|
142
|
+
|
|
143
|
+
Aby naprawić cały plik naraz, uruchom `npx intlayer extract`, a kompilator automatycznie przeniesie ciągi znaków do słownika.
|
|
144
|
+
|
|
145
|
+
**Opcje**
|
|
146
|
+
|
|
147
|
+
```javascript fileName="eslint.config.mjs"
|
|
148
|
+
{
|
|
149
|
+
"intlayer/no-raw-text": [
|
|
150
|
+
"warn",
|
|
151
|
+
{
|
|
152
|
+
// Atrybuty, których wartością jest tekst widoczny dla użytkownika.
|
|
153
|
+
// Domyślnie: title, placeholder, alt, aria-label, label
|
|
154
|
+
attributes: ["title", "placeholder", "alt", "aria-label", "label"],
|
|
155
|
+
|
|
156
|
+
// Elementy, których zawartość nigdy nie jest tekstem widocznym dla użytkownika.
|
|
157
|
+
// Domyślnie: code, pre, script, style
|
|
158
|
+
ignoreElements: ["code", "pre", "script", "style"],
|
|
159
|
+
|
|
160
|
+
// Wyrażenia regularne dla tekstu, który nigdy nie powinien być zgłaszany.
|
|
161
|
+
ignorePatterns: ["^Powered by"],
|
|
162
|
+
|
|
163
|
+
// Zgłaszaj także literały łańcuchowe poza markupem. Domyślnie: false
|
|
164
|
+
includeStringLiterals: false,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `static-dictionary-key`
|
|
171
|
+
|
|
172
|
+
Wymaga, aby klucz słownika był literałem łańcuchowym.
|
|
173
|
+
|
|
174
|
+
Kompilator może wstępnie załadować słownik tylko wtedy, gdy może bezpośrednio odczytać klucz w miejscu wywołania. W przypadku obliczanego klucza optymalizacja jest po cichu pomijana i zamiast tego dołączane są wszystkie słowniki.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// ✗ Zgłoszone
|
|
178
|
+
useIntlayer(dictionaryKey);
|
|
179
|
+
useIntlayer(`home-${suffix}`);
|
|
180
|
+
getTranslations({ namespace: page });
|
|
181
|
+
|
|
182
|
+
// ✗ Zmienna nadal nie jest literałem
|
|
183
|
+
const key = "home";
|
|
184
|
+
useIntlayer(key);
|
|
185
|
+
|
|
186
|
+
// ✓ Prawidłowo
|
|
187
|
+
useIntlayer("home");
|
|
188
|
+
getTranslations({ namespace: "home" });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Dotyczy to `useIntlayer`, `getIntlayer` oraz każdego adaptera kompatybilności (`useTranslation`, `useTranslations`, `formatMessage`, `<FormattedMessage id>`, `<Trans i18nKey>`, …).
|
|
192
|
+
|
|
193
|
+
### `no-dynamic-field-access`
|
|
194
|
+
|
|
195
|
+
Wymaga, aby pole odczytywane ze słownika było znane statycznie.
|
|
196
|
+
|
|
197
|
+
Kompilator usuwa pola, których użycia nie zarejestruje. Dostęp dynamiczny jest dla niego niewidoczny, więc odczyt może zwrócić `undefined` w czasie wykonywania.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// ✗ Zgłoszone
|
|
201
|
+
const content = useIntlayer("home");
|
|
202
|
+
content[fieldName];
|
|
203
|
+
|
|
204
|
+
const t = useTranslations("home");
|
|
205
|
+
t(messageKey);
|
|
206
|
+
|
|
207
|
+
// ✓ Prawidłowo
|
|
208
|
+
content.title;
|
|
209
|
+
content["title"];
|
|
210
|
+
content.items[0];
|
|
211
|
+
t("hero.title");
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `enforce-adapter-import`
|
|
215
|
+
|
|
216
|
+
Preferuje adapter kompatybilności `@intlayer/*` zamiast oryginalnego pakietu. Oryginalny pakiet rozwiązuje się do Intlayer tylko wtedy, gdy skonfigurowany jest alias bundlera; adapter działa zawsze. Możliwość automatycznej naprawy za pomocą `--fix`.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// ✗ Zgłoszone
|
|
220
|
+
import { useTranslation } from "react-i18next";
|
|
221
|
+
import { getTranslations } from "next-intl/server";
|
|
222
|
+
|
|
223
|
+
// ✓ Prawidłowo
|
|
224
|
+
import { useTranslation } from "@intlayer/react-i18next";
|
|
225
|
+
import { getTranslations } from "@intlayer/next-intl/server";
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `no-unused-content`
|
|
229
|
+
|
|
230
|
+
**Domyślnie wyłączona.** Zgłasza zawartość, której nic w projekcie nie odczytuje, oraz klucze słowników zadeklarowane w więcej niż jednym miejscu.
|
|
231
|
+
|
|
232
|
+
```typescript fileName="src/home.content.ts"
|
|
233
|
+
export default {
|
|
234
|
+
key: "home", // ✗ Zgłaszane, gdy żadne wywołanie w projekcie nie odpytuje o "home"
|
|
235
|
+
content: {
|
|
236
|
+
title: t({ pl: "Tytuł", en: "Title" }),
|
|
237
|
+
|
|
238
|
+
// ✗ Zgłaszane, gdy nic nie odczytuje `hero`
|
|
239
|
+
hero: {
|
|
240
|
+
subtitle: t({ pl: "Podtytuł", en: "Subtitle" }),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
W przeciwieństwie do innych reguł, ta nie jest w stanie ocenić sytuacji wyłącznie na podstawie sprawdzanego pliku — pole jest nieużywane tylko w kontekście całego projektu. Przy pierwszej deklaracji zawartości podczas działania lintera wczytuje konfigurację Intlayer, skanuje pliki źródłowe wskazane przez tę konfigurację (`build.traversePattern`, `compiler.transformPattern`) i uruchamia ten sam analizator użycia, który zasila `@intlayer/lsp` oraz przekreślenie „nieużywane” w rozszerzeniu VS Code. Wynik jest buforowany przez `cacheTtl` milisekund, więc skanowanie odbywa się raz na uruchomienie, a nie dla każdego pliku.
|
|
247
|
+
|
|
248
|
+
**Opcje**
|
|
249
|
+
|
|
250
|
+
```javascript fileName="eslint.config.mjs"
|
|
251
|
+
{
|
|
252
|
+
"intlayer/no-unused-content": [
|
|
253
|
+
"warn",
|
|
254
|
+
{
|
|
255
|
+
// Zgłaszaj klucze słowników, do których nic się nie odwołuje. Domyślnie: true
|
|
256
|
+
reportUnusedDictionaries: true,
|
|
257
|
+
|
|
258
|
+
// Zgłaszaj pola zawartości, których nic nie odczytuje. Domyślnie: true
|
|
259
|
+
reportUnusedFields: true,
|
|
260
|
+
|
|
261
|
+
// Zgłaszaj klucze zadeklarowane w więcej niż jednym miejscu. Domyślnie: true
|
|
262
|
+
reportDuplicateKeys: true,
|
|
263
|
+
|
|
264
|
+
// Wyrażenia regularne dla ścieżek pól, które nigdy nie powinny być zgłaszane.
|
|
265
|
+
ignoreFields: ["^meta"],
|
|
266
|
+
|
|
267
|
+
// Katalog główny projektu, od którego zaczyna się skanowanie. Domyślnie: katalog roboczy ESLint
|
|
268
|
+
baseDir: process.cwd(),
|
|
269
|
+
|
|
270
|
+
// Czas ponownego użycia skanu projektu (w ms). Domyślnie: 30000
|
|
271
|
+
cacheTtl: 30000,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Zmniejsz `cacheTtl`, gdy korzystasz z lintera działającego jako serwer edytora i chcesz szybciej widzieć zmiany; ustaw `baseDir`, gdy jedno uruchomienie lintera obejmuje kilka projektów Intlayer w monorepo.
|
|
278
|
+
|
|
279
|
+
> **Preferuje brak zgłoszenia w razie wątpliwości.** Fałszywy alarm w tym miejscu mógłby usunąć potrzebne tłumaczenie, dlatego nic nie jest zgłaszane, gdy słownik jest używany w sposób, którego analiza nie potrafi prześledzić: przekazanie całego obiektu zawartości, powiązana z niego funkcja tłumacząca (`const t = useTranslations("home")`), deklaracja dostępna przez bezpośredni import (`useDictionary(myDictionary)`), `nest()` z innego słownika lub lista pól, która stała się niepełna przez operator spread. Komponenty jednoplikowe (`.vue`, `.svelte`, `.astro`) są traktowane jako używające każdego pola wymienionych słowników, ponieważ ich bloki skryptów nie są tu parsowane.
|
|
280
|
+
|
|
281
|
+
`reportDuplicateKeys` odczytuje niescalone słowniki, które proces budowania zapisuje w `.intlayer/`, więc zachowuje milczenie do momentu, aż projekt zostanie zbudowany przynajmniej raz. Dwie deklaracje dzielące ten sam klucz są scalane, co jest poprawnym wzorcem — raport istnieje, ponieważ pole zdefiniowane po obu stronach po cichu zachowuje tylko jedną z dwóch wartości.
|
|
282
|
+
|
|
283
|
+
Analizator jest ładowany z `@intlayer/lsp`, który jest dystrybuowany jako ESM. Reguła wymaga zatem wersji Node obsługującej `require()` dla modułów ES — Node 20.19+ lub 22.12+. Na starszych wersjach reguła nic nie zgłasza, zamiast powodować błąd działania lintera.
|
|
284
|
+
|
|
285
|
+
## Frameworki
|
|
286
|
+
|
|
287
|
+
Każda reguła działa we wszystkich integracjach Intlayer, w tym wewnątrz szablonów Vue, Svelte i Angular. Wystarczy wskazać ESLintowi, który parser obsługuje dany typ pliku.
|
|
288
|
+
|
|
289
|
+
| Framework | Pliki | Parser |
|
|
290
|
+
| ------------------------- | ----------------- | --------------------------------- |
|
|
291
|
+
| React, Preact, Solid, Lit | `.jsx` `.tsx` | `typescript-eslint` |
|
|
292
|
+
| Next.js | `.jsx` `.tsx` | `typescript-eslint` |
|
|
293
|
+
| Vue, Nuxt | `.vue` | `vue-eslint-parser` |
|
|
294
|
+
| Svelte, SvelteKit | `.svelte` | `svelte-eslint-parser` |
|
|
295
|
+
| Angular | `.ts` | `typescript-eslint` |
|
|
296
|
+
| Szablony Angular | `.component.html` | `@angular-eslint/template-parser` |
|
|
297
|
+
| Astro | `.astro` | `astro-eslint-parser` |
|
|
298
|
+
|
|
299
|
+
```javascript fileName="eslint.config.mjs"
|
|
300
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
301
|
+
import tseslint from "typescript-eslint";
|
|
302
|
+
import vueParser from "vue-eslint-parser";
|
|
303
|
+
import svelteParser from "svelte-eslint-parser";
|
|
304
|
+
import angularTemplateParser from "@angular-eslint/template-parser";
|
|
305
|
+
|
|
306
|
+
export default [
|
|
307
|
+
...intlayer.configs.recommended,
|
|
308
|
+
|
|
309
|
+
{
|
|
310
|
+
files: ["**/*.{ts,tsx,jsx}"],
|
|
311
|
+
languageOptions: { parser: tseslint.parser },
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
files: ["**/*.vue"],
|
|
315
|
+
languageOptions: {
|
|
316
|
+
parser: vueParser,
|
|
317
|
+
parserOptions: { parser: tseslint.parser },
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
files: ["**/*.svelte"],
|
|
322
|
+
languageOptions: {
|
|
323
|
+
parser: svelteParser,
|
|
324
|
+
parserOptions: { parser: tseslint.parser },
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
files: ["**/*.component.html"],
|
|
329
|
+
languageOptions: { parser: angularTemplateParser },
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Instaluj tylko te parsery, których wymaga Twój projekt.
|
|
335
|
+
|
|
336
|
+
> **Znane ograniczenie.** W szablonach Vue i Angular wyrażenie takie jak `{{ content[key] }}` nie jest sprawdzane przez `no-dynamic-field-access`. Odczyty dynamiczne zapisane w bloku script są wykrywane w normalny sposób.
|
|
@@ -300,120 +300,7 @@ Integracja z Astro dodaje oprogramowanie pośredniczące Vite, które pomaga w r
|
|
|
300
300
|
|
|
301
301
|
</Step>
|
|
302
302
|
|
|
303
|
-
<Step number={
|
|
304
|
-
|
|
305
|
-
Kontynuuj budowanie swojej aplikacji, korzystając z wybranego frameworka.
|
|
306
|
-
|
|
307
|
-
- Intlayer + React: [Intlayer z React](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_vite+react.md)
|
|
308
|
-
- Intlayer + Vue: [Intlayer z Vue](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_vite+vue.md)
|
|
309
|
-
- Intlayer + Svelte: [Intlayer z Svelte](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_vite+svelte.md)
|
|
310
|
-
- Intlayer + Solid: [Intlayer z Solid](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_vite+solid.md)
|
|
311
|
-
- Intlayer + Preact: [Intlayer z Preact](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_vite+preact.md)
|
|
312
|
-
</Step>
|
|
313
|
-
|
|
314
|
-
<Step number={17} title="Wyodrębnij zawartość swoich komponentów" isOptional={true}>
|
|
315
|
-
|
|
316
|
-
Jeśli masz istniejącą bazę kodu, transformacja tysięcy plików może być czasochłonna.
|
|
317
|
-
|
|
318
|
-
Aby ułatwić ten proces, Intlayer proponuje [kompilator](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/compiler.md) / [ekstraktor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/cli/extract.md), aby przetransformować komponenty i wyodrębnić zawartość.
|
|
319
|
-
|
|
320
|
-
Aby go skonfigurować, możesz dodać sekcję `compiler` w pliku `intlayer.config.ts`:
|
|
321
|
-
|
|
322
|
-
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
323
|
-
import { type IntlayerConfig } from "intlayer";
|
|
324
|
-
|
|
325
|
-
const config: IntlayerConfig = {
|
|
326
|
-
// ... Reszta Twojej konfiguracji
|
|
327
|
-
compiler: {
|
|
328
|
-
/**
|
|
329
|
-
* Wskazuje, czy kompilator powinien być włączony.
|
|
330
|
-
*/
|
|
331
|
-
enabled: true,
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Definiuje ścieżkę plików wyjściowych
|
|
335
|
-
*/
|
|
336
|
-
output: ({ fileName, extension }) => `./${fileName}${extension}`,
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Wskazuje, czy komponenty powinny zostać zapisane po transformacji. W ten sposób kompilator można uruchomić tylko raz, aby przetransformować aplikację, a następnie go usunąć.
|
|
340
|
-
*/
|
|
341
|
-
saveComponents: false,
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Prefiks klucza słownika
|
|
345
|
-
*/
|
|
346
|
-
dictionaryKeyPrefix: "",
|
|
347
|
-
},
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
export default config;
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
<Tabs>
|
|
354
|
-
<Tab value='Polecenie wyodrębniania'>
|
|
355
|
-
|
|
356
|
-
Uruchom ekstraktor, aby przetransformować komponenty i wyodrębnić zawartość
|
|
357
|
-
|
|
358
|
-
```bash packageManager="npm"
|
|
359
|
-
npx intlayer extract
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
```bash packageManager="pnpm"
|
|
363
|
-
pnpm intlayer extract
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
```bash packageManager="yarn"
|
|
367
|
-
yarn intlayer extract
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
```bash packageManager="bun"
|
|
371
|
-
bun x intlayer extract
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
</Tab>
|
|
375
|
-
<Tab value='Kompilator Babel'>
|
|
376
|
-
|
|
377
|
-
> Since v9, the `intlayerCompiler` is included in the `intlayer` plugin. So you don't need to add it manually.
|
|
378
|
-
|
|
379
|
-
Zaktualizuj `vite.config.ts`, aby dołączyć wtyczkę `intlayerCompiler`:
|
|
380
|
-
|
|
381
|
-
```ts fileName="vite.config.ts"
|
|
382
|
-
import { defineConfig } from "vite";
|
|
383
|
-
import { intlayer, intlayerCompiler } from "vite-intlayer";
|
|
384
|
-
|
|
385
|
-
export default defineConfig({
|
|
386
|
-
plugins: [
|
|
387
|
-
intlayer(),
|
|
388
|
-
intlayerCompiler(), // Adds the compiler plugin
|
|
389
|
-
],
|
|
390
|
-
});
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
```bash packageManager="npm"
|
|
394
|
-
npm run build # Lub npm run dev
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
```bash packageManager="pnpm"
|
|
398
|
-
pnpm run build # Or pnpm run dev
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
```bash packageManager="yarn"
|
|
402
|
-
yarn build # Or yarn dev
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
```bash packageManager="bun"
|
|
406
|
-
bun run build # Or bun run dev
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
</Tab>
|
|
410
|
-
</Tabs>
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
</Step>
|
|
415
|
-
|
|
416
|
-
</Steps>
|
|
303
|
+
<Step number={8} title="Sitemap i Robots.txt">
|
|
417
304
|
|
|
418
305
|
#### Mapa witryny
|
|
419
306
|
|
|
@@ -98,6 +98,10 @@ Następujące kroki są minimalne wymagane aby uruchomić istniejącą aplikacj
|
|
|
98
98
|
|
|
99
99
|
Zainstaluj pakiety rdzenia Intlayer i adapter compat:
|
|
100
100
|
|
|
101
|
+
</Step>
|
|
102
|
+
|
|
103
|
+
</Steps>
|
|
104
|
+
|
|
101
105
|
## Pełna migracja
|
|
102
106
|
|
|
103
107
|
Poniższe kroki są opcjonalne i można je wykonywać stopniowo. Odblokowują one pełny zestaw funkcji Intlayer: edytor wizualny, CMS, pliki zawartości z typami, automatyczne tłumaczenie oparte na AI i wiele więcej.
|
|
@@ -335,13 +335,17 @@ Intlayer uses module augmentation to provide full TypeScript intellisense for yo
|
|
|
335
335
|
|
|
336
336
|
---
|
|
337
337
|
|
|
338
|
-
##
|
|
338
|
+
## Konfiguracja Git
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
Dodaj wygenerowany przez Intlayer katalog do pliku `.gitignore`:
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
```plaintext fileName=".gitignore"
|
|
343
|
+
# Ignoruj pliki wygenerowane przez Intlayer
|
|
344
|
+
.intlayer
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
343
348
|
|
|
344
|
-
<Step number={1} title="Zainstaluj zależności">
|
|
345
349
|
## Idź dalej
|
|
346
350
|
|
|
347
351
|
- **Visual Editor** — Zarządzaj tłumaczeniami wizualnie w przeglądarce: [Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_visual_editor.md)
|
|
@@ -312,15 +312,21 @@ export default config;
|
|
|
312
312
|
|
|
313
313
|
---
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
Zainstaluj pakiety rdzenia Intlayer i adapter compat `@intlayer/next-intl`:
|
|
316
316
|
|
|
317
|
-
|
|
317
|
+
## Co można usunąć po migracji
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
Po wdrożeniu `@intlayer/next-intl` można usunąć następujący boilerplate `next-intl`:
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
| Plik / wzorzec | Dlaczego już nie jest potrzebny |
|
|
322
|
+
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
323
|
+
| `src/i18n.ts` → eksport `getRequestConfig` | Intlayer kompiluje słowniki w czasie budowania; nie ma ładowania wiadomości dla każdego żądania. Zachowaj plik tylko jeśli eksportuje również pomocniki routingu `createNavigation`. |
|
|
324
|
+
| Wywołanie `loadMessages()` / `getMessages()` w layout | `NextIntlClientProvider` z `@intlayer/next-intl` czyta ze skompilowanych danych wyjściowych; prop `messages` nie jest wymagany. |
|
|
325
|
+
| Importy `locales/{locale}/*.json` w layout | Pakiety JSON są potrzebne tylko jeśli nadal używasz pluginu `syncJSON`. Po migracji do plików `.content.ts` możesz usunąć folder JSON. |
|
|
322
326
|
|
|
323
|
-
|
|
327
|
+
Gdy będziesz gotowy, aby pójść dalej, Intlayer **automatycznie odkrywa wszystkie pliki `.content.ts` i `.content.json` gdziekolwiek w twoim codebase** (domyślnie gdziekolwiek wewnątrz `./src`). Możesz umieścić plik `about.content.ts` tuż obok `about/page.tsx` i Intlayer podciągnie go w czasie budowania bez żadnej dodatkowej konfiguracji — bez importów, bez rejestracji, bez scentralizowanego pliku indeksu. Sprawia to, że współlokalizowanie tłumaczeń ze stronami i komponentami jest całkowicie pozbawione tarcia.
|
|
328
|
+
|
|
329
|
+
---
|
|
324
330
|
|
|
325
331
|
## Konfiguracja TypeScript
|
|
326
332
|
|
|
@@ -307,13 +307,17 @@ Intlayer używa module augmentation, aby zapewnić pełny TypeScript intellisens
|
|
|
307
307
|
|
|
308
308
|
---
|
|
309
309
|
|
|
310
|
-
##
|
|
310
|
+
## Konfiguracja Git
|
|
311
311
|
|
|
312
|
-
|
|
312
|
+
Dodaj wygenerowany przez Intlayer katalog do `.gitignore`:
|
|
313
313
|
|
|
314
|
-
|
|
314
|
+
```plaintext fileName=".gitignore"
|
|
315
|
+
# Ignoruj pliki wygenerowane przez Intlayer
|
|
316
|
+
.intlayer
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
315
320
|
|
|
316
|
-
<Step number={1} title="Zainstaluj zależności">
|
|
317
321
|
## Idź dalej
|
|
318
322
|
|
|
319
323
|
- **Visual Editor** — Zarządzaj tłumaczeniami wizualnie w przeglądarce: [Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_visual_editor.md)
|
|
@@ -361,13 +361,17 @@ Intlayer używa module augmentation, aby zapewnić pełny intellisense TypeScrip
|
|
|
361
361
|
|
|
362
362
|
---
|
|
363
363
|
|
|
364
|
-
##
|
|
364
|
+
## Konfiguracja Git
|
|
365
365
|
|
|
366
|
-
|
|
366
|
+
Dodaj wygenerowany przez Intlayer katalog do `.gitignore`:
|
|
367
367
|
|
|
368
|
-
|
|
368
|
+
```plaintext fileName=".gitignore"
|
|
369
|
+
# Ignoruj pliki wygenerowane przez Intlayer
|
|
370
|
+
.intlayer
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
369
374
|
|
|
370
|
-
<Step number={1} title="Zainstaluj zależności">
|
|
371
375
|
## Idź dalej
|
|
372
376
|
|
|
373
377
|
- **Visual Editor** — Zarządzaj tłumaczeniami wizualnie w przeglądarce: [Intlayer Visual Editor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_visual_editor.md)
|
|
@@ -99,6 +99,10 @@ Następujące kroki są minimalne wymagane aby uruchomić istniejącą aplikacj
|
|
|
99
99
|
|
|
100
100
|
Zainstaluj pakiety rdzenia Intlayer i adapter compat:
|
|
101
101
|
|
|
102
|
+
</Step>
|
|
103
|
+
|
|
104
|
+
</Steps>
|
|
105
|
+
|
|
102
106
|
## Pełna migracja
|
|
103
107
|
|
|
104
108
|
Poniższe kroki są opcjonalne i mogą być wykonywane stopniowo. Odblokowują pełny zestaw funkcji Intlayer: edytor wizualny, CMS, pliki zawartości z typami, tłumaczenie wspierane przez AI i wiele więcej.
|
|
@@ -159,7 +159,7 @@ pnpm add -D webpack-bundle-analyzer
|
|
|
159
159
|
bun add -d webpack-bundle-analyzer
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
```typescript fileName="webpack.config.ts
|
|
162
|
+
```typescript fileName="webpack.config.ts"
|
|
163
163
|
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
|
|
164
164
|
|
|
165
165
|
export default {
|