feat(lint): Wave 3 ESLint i18n Plugin 啟用 (warn 模式)
All checks were successful
E2E Health Check / e2e-health (push) Successful in 18s

安裝 eslint-plugin-i18next:
- 檢測 JSX 中硬編碼字串
- markupOnly: true (只檢查 JSX)
- 忽略技術屬性: data-testid, className, href, src

階段一: warn 模式 (當前)
階段二: error 模式 (待統帥批准)

發現 10+ 遺留警告,待修復

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-31 18:54:47 +08:00
parent dd526684ab
commit 83a0845858
3 changed files with 46 additions and 2 deletions

View File

@@ -2,10 +2,12 @@
* AWOOOI Web ESLint Configuration
* ================================
* Extends @awoooi/eslint-config/react
* Wave 3: i18n enforcement via eslint-plugin-i18next
*/
module.exports = {
extends: ['@awoooi/eslint-config/react', 'next/core-web-vitals'],
plugins: ['i18next'],
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
@@ -17,8 +19,26 @@ module.exports = {
// Allow console for debugging (TODO: integrate unified logger)
'no-console': 'off',
// i18n enforcement - no hardcoded strings in JSX
// (Custom rule would require eslint-plugin-i18n-json setup)
// Wave 3: i18n enforcement - 禁止 JSX 中的硬編碼字串
// 階段一: warn 模式 (2026-03-31)
// 階段二: error 模式 (待統帥批准)
'i18next/no-literal-string': ['warn', {
// 允許技術識別符 (服務名/API 路徑)
markupOnly: true,
// 忽略特定屬性
ignoreAttribute: [
'data-testid',
'className',
'href',
'src',
'alt',
'name',
'type',
'placeholder', // 部分 placeholder 可能需要 i18n視情況調整
],
// 忽略特定函數調用
ignoreCallee: ['console.log', 'console.error', 'console.warn', 't', 'tRisk', 'tBlast'],
}],
// TypeScript strict rules
'@typescript-eslint/no-explicit-any': 'warn',

View File

@@ -34,6 +34,7 @@
"autoprefixer": "^10.4.0",
"eslint": "^8.57.0",
"eslint-config-next": "^14.1.0",
"eslint-plugin-i18next": "^6.1.3",
"playwright": "^1.58.2",
"postcss": "^8.4.0",
"tailwindcss": "^3.4.0",

23
pnpm-lock.yaml generated
View File

@@ -93,6 +93,9 @@ importers:
eslint-config-next:
specifier: ^14.1.0
version: 14.2.35(eslint@8.57.1)(typescript@5.9.3)
eslint-plugin-i18next:
specifier: ^6.1.3
version: 6.1.3
playwright:
specifier: ^1.58.2
version: 1.58.2
@@ -2293,6 +2296,10 @@ packages:
eslint-import-resolver-webpack:
optional: true
eslint-plugin-i18next@6.1.3:
resolution: {integrity: sha512-z/h4oBRd9wI1ET60HqcLSU6XPeAh/EPOrBBTyCdkWeMoYrWAaUVA+DOQkWTiNIyCltG4NTmy62SQisVXxoXurw==}
engines: {node: '>=18.10.0'}
eslint-plugin-import@2.32.0:
resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==}
engines: {node: '>=4'}
@@ -2884,6 +2891,9 @@ packages:
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash@4.17.23:
resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
@@ -3378,6 +3388,10 @@ packages:
resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==}
engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'}
requireindex@1.1.0:
resolution: {integrity: sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==}
engines: {node: '>=0.10.5'}
reselect@5.1.1:
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
@@ -6173,6 +6187,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-i18next@6.1.3:
dependencies:
lodash: 4.17.23
requireindex: 1.1.0
eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1):
dependencies:
'@rtsao/scc': 1.1.0
@@ -6846,6 +6865,8 @@ snapshots:
lodash.merge@4.6.2: {}
lodash@4.17.23: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
@@ -7325,6 +7346,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
requireindex@1.1.0: {}
reselect@5.1.1: {}
resolve-from@4.0.0: {}