@itcase/config 1.6.86 → 1.7.0
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/README.md +14 -2
- package/lint-staged/common.js +77 -0
- package/lint-staged/index.js +3 -38
- package/lint-staged/lintStaged.js +5 -0
- package/lint-staged/lintStagedMonorepo.js +7 -0
- package/package.json +1 -2
- package/lint-staged-ts/index.js +0 -46
package/README.md
CHANGED
|
@@ -23,8 +23,8 @@ npm install --save-dev @itcase/config
|
|
|
23
23
|
- В git только `.husky/config`; обёртки и `_run.sh` создаёт `itcase-config-husky-install` при `npm i`
|
|
24
24
|
|
|
25
25
|
- **Lint-staged** — запуск линтеров для измененных файлов
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
26
|
+
- `lintStaged` — eslint, stylelint; `tsc --noEmit`, если в staged есть `.ts`/`.tsx`
|
|
27
|
+
- `lintStagedMonorepo` — то же, но typecheck через `npm run typecheck` по workspaces
|
|
28
28
|
- обе конфигурации блокируют коммит, если в `package.json` есть локальные зависимости `file:` / `link:`
|
|
29
29
|
|
|
30
30
|
- **PostCSS** — обработка CSS
|
|
@@ -41,6 +41,18 @@ npm install --save-dev @itcase/config
|
|
|
41
41
|
- `svgr/index.js` — базовая конфигурация
|
|
42
42
|
- `svgr/webpack.js` — интеграция с Webpack
|
|
43
43
|
|
|
44
|
+
## Подключение Lint-staged
|
|
45
|
+
|
|
46
|
+
В корне проекта `lint-staged.config.mjs`:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import { lintStaged } from '@itcase/config/lint-staged/index.js'
|
|
50
|
+
|
|
51
|
+
export default lintStaged
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Для монорепозитория с `npm run typecheck` — `lintStagedMonorepo`.
|
|
55
|
+
|
|
44
56
|
## Подключение Commitlint
|
|
45
57
|
|
|
46
58
|
1. Установите зависимости в проекте:
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
|
|
5
|
+
const checkNoFileDependencies = join(
|
|
6
|
+
dirname(fileURLToPath(import.meta.url)),
|
|
7
|
+
'checkNoFileDependencies.js',
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
function existingFiles(files) {
|
|
11
|
+
return files.filter((file) => existsSync(file))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function eslintCommand(files) {
|
|
15
|
+
return `npx eslint --fix --color ${files.join(' ')}`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function stylelintCommand(files) {
|
|
19
|
+
return `npx stylelint --fix --color --formatter verbose ${files.join(' ')}`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function packageJsonCommand(files) {
|
|
23
|
+
// Проверяем, есть ли package.json в корне репозитория
|
|
24
|
+
const rootPackageJson = resolve(process.cwd(), 'package.json')
|
|
25
|
+
const isRoot = files.some((file) => resolve(file) === rootPackageJson)
|
|
26
|
+
if (existsSync(rootPackageJson) && isRoot) {
|
|
27
|
+
// lint-staged автоматически добавляет изменения задач в index
|
|
28
|
+
return 'npm install --package-lock-only'
|
|
29
|
+
}
|
|
30
|
+
return 'true' // Пропускаем, если не найден
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Создает конфигурацию lint-staged с общими правилами.
|
|
35
|
+
* Один glob на JS/TS — typecheck и eslint в одной группе.
|
|
36
|
+
* `tsc` срабатывает только если в staged есть .ts/.tsx, поэтому JS-пакету
|
|
37
|
+
* отдельный конфиг не нужен.
|
|
38
|
+
* @param {Object} [options]
|
|
39
|
+
* @param {string} [options.typecheckCommand] Команда typecheck, если в staged есть .ts/.tsx
|
|
40
|
+
* @returns {Object} Конфигурация lint-staged
|
|
41
|
+
*/
|
|
42
|
+
function createLintStagedConfig({
|
|
43
|
+
typecheckCommand = 'tsc --noEmit --pretty',
|
|
44
|
+
} = {}) {
|
|
45
|
+
return {
|
|
46
|
+
// На любой staged-файл: если в package.json есть file:/link: — exit 1, коммит не пройдёт
|
|
47
|
+
'*': () => `node ${JSON.stringify(checkNoFileDependencies)}`,
|
|
48
|
+
'*.(js|jsx|ts|tsx)': (files) => {
|
|
49
|
+
const existing = existingFiles(files)
|
|
50
|
+
const tsFiles = existing.filter((file) => /\.(ts|tsx)$/.test(file))
|
|
51
|
+
const commands = []
|
|
52
|
+
|
|
53
|
+
if (typecheckCommand && tsFiles.length > 0) {
|
|
54
|
+
commands.push(typecheckCommand)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (existing.length > 0) {
|
|
58
|
+
commands.push(eslintCommand(existing))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return commands.length ? commands : 'true'
|
|
62
|
+
},
|
|
63
|
+
'*.css': (files) => {
|
|
64
|
+
const existing = existingFiles(files)
|
|
65
|
+
if (!existing.length) return 'true'
|
|
66
|
+
return stylelintCommand(existing)
|
|
67
|
+
},
|
|
68
|
+
'*.mdx': (files) => {
|
|
69
|
+
const existing = existingFiles(files)
|
|
70
|
+
if (!existing.length) return 'true'
|
|
71
|
+
return eslintCommand(existing)
|
|
72
|
+
},
|
|
73
|
+
'package.json': packageJsonCommand,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { createLintStagedConfig }
|
package/lint-staged/index.js
CHANGED
|
@@ -1,39 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
1
|
+
import { lintStaged } from './lintStaged.js'
|
|
2
|
+
import { lintStagedMonorepo } from './lintStagedMonorepo.js'
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
7
|
-
'checkNoFileDependencies.js',
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
// eslint-disable-next-line import/no-default-export
|
|
11
|
-
export default {
|
|
12
|
-
// На любой staged-файл: если в package.json есть file:/link: — exit 1, коммит не пройдёт
|
|
13
|
-
'*': () => `node ${JSON.stringify(checkNoFileDependencies)}`,
|
|
14
|
-
'*.(js|jsx|ts|tsx)': (files) => {
|
|
15
|
-
const existing = files.filter((file) => existsSync(file))
|
|
16
|
-
if (!existing.length) return 'true'
|
|
17
|
-
return `npx eslint --fix --color ${existing.join(' ')}`
|
|
18
|
-
},
|
|
19
|
-
'*.css': (files) => {
|
|
20
|
-
const existing = files.filter((file) => existsSync(file))
|
|
21
|
-
if (!existing.length) return 'true'
|
|
22
|
-
return `npx stylelint --fix --color --formatter verbose ${existing.join(' ')}`
|
|
23
|
-
},
|
|
24
|
-
'*.mdx': (files) => {
|
|
25
|
-
const existing = files.filter((file) => existsSync(file))
|
|
26
|
-
if (!existing.length) return 'true'
|
|
27
|
-
return `npx eslint --fix --color ${existing.join(' ')}`
|
|
28
|
-
},
|
|
29
|
-
'package.json': (files) => {
|
|
30
|
-
// Проверяем, есть ли package.json в корне репозитория
|
|
31
|
-
const rootPackageJson = resolve(process.cwd(), 'package.json')
|
|
32
|
-
const isRoot = files.some((file) => resolve(file) === rootPackageJson)
|
|
33
|
-
if (existsSync(rootPackageJson) && isRoot) {
|
|
34
|
-
// lint-staged автоматически добавляет изменения задач в index
|
|
35
|
-
return 'npm install --package-lock-only'
|
|
36
|
-
}
|
|
37
|
-
return 'true' // Пропускаем, если не найден
|
|
38
|
-
},
|
|
39
|
-
}
|
|
4
|
+
export { lintStaged, lintStagedMonorepo }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itcase/config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"author": "ITCase",
|
|
5
5
|
"description": "ITCase Config",
|
|
6
6
|
"engines": {
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"commitlint",
|
|
29
29
|
"husky-hooks",
|
|
30
30
|
"lint-staged",
|
|
31
|
-
"lint-staged-ts",
|
|
32
31
|
"semantic-release",
|
|
33
32
|
"postcss",
|
|
34
33
|
"smart-commit",
|
package/lint-staged-ts/index.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { dirname, join, resolve } from 'node:path'
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
4
|
-
|
|
5
|
-
const checkNoFileDependencies = join(
|
|
6
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
7
|
-
'../lint-staged/checkNoFileDependencies.js',
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
// eslint-disable-next-line import/no-default-export
|
|
11
|
-
export default {
|
|
12
|
-
// На любой staged-файл: если в package.json есть file:/link: — exit 1, коммит не пройдёт
|
|
13
|
-
'*': () => `node ${JSON.stringify(checkNoFileDependencies)}`,
|
|
14
|
-
'*.(ts|tsx)': (files) => {
|
|
15
|
-
const existing = files.filter((file) => existsSync(file))
|
|
16
|
-
const tsFiles = existing.filter((file) => /\.(ts|tsx)$/.test(file))
|
|
17
|
-
const commands = []
|
|
18
|
-
if (tsFiles.length > 0) {
|
|
19
|
-
commands.push('tsc --noEmit --pretty')
|
|
20
|
-
}
|
|
21
|
-
if (existing.length > 0) {
|
|
22
|
-
commands.push(`npx eslint --fix ${existing.join(' ')}`)
|
|
23
|
-
}
|
|
24
|
-
return commands.length ? commands : 'true'
|
|
25
|
-
},
|
|
26
|
-
'*.css': (files) => {
|
|
27
|
-
const existing = files.filter((file) => existsSync(file))
|
|
28
|
-
if (!existing.length) return 'true'
|
|
29
|
-
return `npx stylelint --fix --color --formatter verbose ${existing.join(' ')}`
|
|
30
|
-
},
|
|
31
|
-
'*.mdx': (files) => {
|
|
32
|
-
const existing = files.filter((file) => existsSync(file))
|
|
33
|
-
if (!existing.length) return 'true'
|
|
34
|
-
return `npx eslint --fix ${existing.join(' ')}`
|
|
35
|
-
},
|
|
36
|
-
'package.json': (files) => {
|
|
37
|
-
// Проверяем, есть ли package.json в корне репозитория
|
|
38
|
-
const rootPackageJson = resolve(process.cwd(), 'package.json')
|
|
39
|
-
const isRoot = files.some((file) => resolve(file) === rootPackageJson)
|
|
40
|
-
if (existsSync(rootPackageJson) && isRoot) {
|
|
41
|
-
// lint-staged автоматически добавляет изменения задач в index
|
|
42
|
-
return 'npm install --package-lock-only'
|
|
43
|
-
}
|
|
44
|
-
return 'true' // Пропускаем, если не найден
|
|
45
|
-
},
|
|
46
|
-
}
|