style-code 1.0.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 +30 -0
- package/bin/index.js +15 -0
- package/config/commitLint/commitlintTemplate.js +27 -0
- package/config/eslint/eslintTemplate.js +23 -0
- package/config/gitHooks/commitMsgTemplate +2 -0
- package/config/gitHooks/preCommitTemplate +16 -0
- package/config/vscode/settingsTemplate.js +50 -0
- package/const/dependencies.js +30 -0
- package/index.js +242 -0
- package/package.json +21 -0
package/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
## 代码风格规范工具
|
2
|
+
|
3
|
+
## 运行条件
|
4
|
+
|
5
|
+
- node18+
|
6
|
+
|
7
|
+
## 安装依赖
|
8
|
+
|
9
|
+
1. 局部安装 `npm i style-config`
|
10
|
+
|
11
|
+
2. 全局安装 `npm i style-config -g`
|
12
|
+
|
13
|
+
## 初始化
|
14
|
+
|
15
|
+
1. `npx style init`
|
16
|
+
2. 全局安装时可使用 `style init`
|
17
|
+
|
18
|
+
## 使用
|
19
|
+
|
20
|
+
1. 检查单个文件 `npx eslint yourfile.js`
|
21
|
+
2. 检查单个文件并修复 `npx eslint yourfile.js --fix`
|
22
|
+
3. 检查所有文件 `npm run lint`
|
23
|
+
4. 检查所有文件并修复 `npm run lint:fix`
|
24
|
+
|
25
|
+
## 说明
|
26
|
+
|
27
|
+
1. 添加代码提交eslint校验修复和提交信息校验,校验成功可提交代码。
|
28
|
+
2. 保存将自动修复代码以及格式化。
|
29
|
+
3. 默认支持vue3,如需校验vue2,可在配置文件`eslint.config.mjs`中修改,更多配置可参考@antfu/eslint文档(https://github.com/antfu/eslint-config/tree/v2.27.3?tab=readme-ov-file)。
|
30
|
+
4. 提交信息格式`type: msg`,例如:`perf: 代码优化`,详情见`commitlint.config.mjs`文件,可自定义规则。
|
package/bin/index.js
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
const process = require('node:process')
|
3
|
+
const { program } = require('commander')
|
4
|
+
const { StyleConfigInit } = require('../index')
|
5
|
+
|
6
|
+
program
|
7
|
+
.command('init')
|
8
|
+
.description('初始化')
|
9
|
+
.action(() => {
|
10
|
+
const styleConfigInit = new StyleConfigInit()
|
11
|
+
|
12
|
+
styleConfigInit.init()
|
13
|
+
})
|
14
|
+
|
15
|
+
program.parse(process.argv)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
export default {
|
2
|
+
// 继承的规则
|
3
|
+
extends: ['@commitlint/config-conventional'],
|
4
|
+
// 定义规则类型
|
5
|
+
rules: {
|
6
|
+
// type 类型定义,表示 git 提交的 type 必须在以下类型范围内
|
7
|
+
'type-enum': [
|
8
|
+
2,
|
9
|
+
'always',
|
10
|
+
[
|
11
|
+
'feat', // 新功能 feature
|
12
|
+
'fix', // 修复 bug
|
13
|
+
'docs', // 文档注释
|
14
|
+
'format', // 代码格式(不影响代码运行的变动)
|
15
|
+
'perf', // 优化
|
16
|
+
'style', // css样式修改
|
17
|
+
'refactor', // 重构(既不增加新功能,也不是修复bug)
|
18
|
+
'test', // 增加测试
|
19
|
+
'chore', // 构建过程或辅助工具的变动
|
20
|
+
'revert', // 回退
|
21
|
+
'build', // 打包
|
22
|
+
],
|
23
|
+
],
|
24
|
+
// subject 大小写不做校验
|
25
|
+
'subject-case': [0],
|
26
|
+
},
|
27
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
// eslint.config.mjs
|
2
|
+
import antfu from '@antfu/eslint-config'
|
3
|
+
|
4
|
+
export default antfu({
|
5
|
+
// 使用Prettier格式化css(css、less、scss)、html、markdown文件
|
6
|
+
formatters: {
|
7
|
+
css: true,
|
8
|
+
html: true,
|
9
|
+
markdown: 'prettier',
|
10
|
+
},
|
11
|
+
vue: true,
|
12
|
+
rules: {
|
13
|
+
'no-console': 'off',
|
14
|
+
'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行
|
15
|
+
'no-unexpected-multiline': 'error', // 禁止空余的多行
|
16
|
+
'vue/block-order': [
|
17
|
+
'error',
|
18
|
+
{
|
19
|
+
order: ['template', 'script', 'style'],
|
20
|
+
},
|
21
|
+
], // vue组件代码块顺序
|
22
|
+
},
|
23
|
+
})
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# 获取当前分支
|
2
|
+
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
3
|
+
|
4
|
+
echo -e "\033[33m -------------- 当前分支: $current_branch 正在执行代码commit操作 -------------- \033[0m"
|
5
|
+
|
6
|
+
# 检查是否有待提交的文件
|
7
|
+
if [ -z "$(git diff --cached --name-only)" ]; then
|
8
|
+
echo -e "\033[0;31m ************** 暂存区域没有文件 ************** \033[0m"
|
9
|
+
exit 1
|
10
|
+
fi
|
11
|
+
|
12
|
+
# 通过lint-staged进行代码检查
|
13
|
+
npx --no-install lint-staged
|
14
|
+
|
15
|
+
echo -e "\033[0;32m -------------- 代码校验通过准备提交 ✅ -------------- \033[0m"
|
16
|
+
exit 0
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module.exports = {
|
2
|
+
// Disable the default formatter, use eslint instead
|
3
|
+
'prettier.enable': false,
|
4
|
+
'editor.formatOnSave': false,
|
5
|
+
|
6
|
+
// Auto fix
|
7
|
+
'editor.codeActionsOnSave': {
|
8
|
+
'source.fixAll.eslint': 'explicit',
|
9
|
+
'source.organizeImports': 'never',
|
10
|
+
},
|
11
|
+
|
12
|
+
// Silent the stylistic rules in you IDE, but still auto fix them
|
13
|
+
'eslint.rules.customizations': [
|
14
|
+
{ rule: 'style/*', severity: 'off', fixable: true },
|
15
|
+
{ rule: 'format/*', severity: 'off', fixable: true },
|
16
|
+
{ rule: '*-indent', severity: 'off', fixable: true },
|
17
|
+
{ rule: '*-spacing', severity: 'off', fixable: true },
|
18
|
+
{ rule: '*-spaces', severity: 'off', fixable: true },
|
19
|
+
{ rule: '*-order', severity: 'off', fixable: true },
|
20
|
+
{ rule: '*-dangle', severity: 'off', fixable: true },
|
21
|
+
{ rule: '*-newline', severity: 'off', fixable: true },
|
22
|
+
{ rule: '*quotes', severity: 'off', fixable: true },
|
23
|
+
{ rule: '*semi', severity: 'off', fixable: true },
|
24
|
+
],
|
25
|
+
|
26
|
+
// Enable eslint for all supported languages
|
27
|
+
'eslint.validate': [
|
28
|
+
'javascript',
|
29
|
+
'javascriptreact',
|
30
|
+
'typescript',
|
31
|
+
'typescriptreact',
|
32
|
+
'vue',
|
33
|
+
'html',
|
34
|
+
'markdown',
|
35
|
+
'json',
|
36
|
+
'json5',
|
37
|
+
'jsonc',
|
38
|
+
'yaml',
|
39
|
+
'toml',
|
40
|
+
'xml',
|
41
|
+
'gql',
|
42
|
+
'graphql',
|
43
|
+
'astro',
|
44
|
+
'css',
|
45
|
+
'less',
|
46
|
+
'scss',
|
47
|
+
'pcss',
|
48
|
+
'postcss',
|
49
|
+
],
|
50
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module.exports = [
|
2
|
+
{
|
3
|
+
name: 'eslint',
|
4
|
+
version: '8.57.1',
|
5
|
+
},
|
6
|
+
{
|
7
|
+
name: '@antfu/eslint-config',
|
8
|
+
version: '2.27.3',
|
9
|
+
},
|
10
|
+
{
|
11
|
+
name: '@commitlint/cli',
|
12
|
+
version: '19.5.0',
|
13
|
+
},
|
14
|
+
{
|
15
|
+
name: '@commitlint/config-conventional',
|
16
|
+
version: '19.5.0',
|
17
|
+
},
|
18
|
+
{
|
19
|
+
name: 'lint-staged',
|
20
|
+
version: '15.2.10',
|
21
|
+
},
|
22
|
+
{
|
23
|
+
name: 'husky',
|
24
|
+
version: '9.1.6',
|
25
|
+
},
|
26
|
+
{
|
27
|
+
name: 'eslint-plugin-format',
|
28
|
+
version: '0.1.2',
|
29
|
+
},
|
30
|
+
]
|
package/index.js
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
const fs = require('node:fs')
|
3
|
+
const process = require('node:process')
|
4
|
+
const path = require('node:path')
|
5
|
+
const { exec } = require('node:child_process')
|
6
|
+
const dependenciesList = require('./const/dependencies')
|
7
|
+
const settingsTemplate = require('./config/vscode/settingsTemplate')
|
8
|
+
|
9
|
+
// 安装依赖并生成配置文件以及配置项
|
10
|
+
class StyleConfigInit {
|
11
|
+
constructor() {
|
12
|
+
this.animate = new StyleConfigAnimate()
|
13
|
+
}
|
14
|
+
|
15
|
+
// 读取文件内容
|
16
|
+
readFileContent(filePath) {
|
17
|
+
return new Promise((resolve, reject) => {
|
18
|
+
fs.readFile(filePath, 'utf8', (err, data) => {
|
19
|
+
if (err) {
|
20
|
+
reject(new Error(`在读取文件 ${filePath} 时发生错误:${err}`))
|
21
|
+
return
|
22
|
+
}
|
23
|
+
resolve(data)
|
24
|
+
})
|
25
|
+
})
|
26
|
+
}
|
27
|
+
|
28
|
+
// 写入文件内容
|
29
|
+
createFile(filePath, content) {
|
30
|
+
return new Promise((resolve, reject) => {
|
31
|
+
fs.writeFile(filePath, content, 'utf8', (err) => {
|
32
|
+
if (err) {
|
33
|
+
reject(new Error(`在写入文件${filePath}时发生错误:${err}`))
|
34
|
+
return
|
35
|
+
}
|
36
|
+
resolve()
|
37
|
+
})
|
38
|
+
})
|
39
|
+
}
|
40
|
+
|
41
|
+
// 读取模板配置并生成配置文件
|
42
|
+
async generateConfigFile(readPath, writePath) {
|
43
|
+
const content = await this.readFileContent(readPath)
|
44
|
+
await this.createFile(writePath, content)
|
45
|
+
}
|
46
|
+
|
47
|
+
// 安装依赖
|
48
|
+
installDependencies() {
|
49
|
+
const dependenciesStr = dependenciesList
|
50
|
+
.reduce((pre, cur) => {
|
51
|
+
return `${pre + cur.name}@${cur.version} `
|
52
|
+
}, '')
|
53
|
+
.slice(0, -1)
|
54
|
+
return new Promise((resolve, reject) => {
|
55
|
+
exec(
|
56
|
+
`npm install ${dependenciesStr} -D`,
|
57
|
+
{ cwd: process.cwd() },
|
58
|
+
(err, _stdout, _stderr) => {
|
59
|
+
if (err) {
|
60
|
+
reject(new Error(`在安装依赖时发生错误:${err}`))
|
61
|
+
return
|
62
|
+
}
|
63
|
+
resolve()
|
64
|
+
},
|
65
|
+
)
|
66
|
+
})
|
67
|
+
}
|
68
|
+
|
69
|
+
// 在package.json中添加配置
|
70
|
+
async addConfigToPackageJson() {
|
71
|
+
const packagePath = path.join(process.cwd(), 'package.json')
|
72
|
+
const packageContent = await this.readFileContent(packagePath)
|
73
|
+
const packageObj = JSON.parse(packageContent)
|
74
|
+
packageObj.scripts = {
|
75
|
+
...packageObj.scripts,
|
76
|
+
'lint': 'eslint .',
|
77
|
+
'lint:fix': 'eslint . --fix',
|
78
|
+
'prepare': 'husky',
|
79
|
+
}
|
80
|
+
packageObj['lint-staged'] = {
|
81
|
+
'*.{js,jsx,ts,tsx,vue}': ['eslint --fix'],
|
82
|
+
'*.{scss,less,css,html,md}': ['eslint --fix'],
|
83
|
+
}
|
84
|
+
await this.createFile(packagePath, JSON.stringify(packageObj, null, 2))
|
85
|
+
}
|
86
|
+
|
87
|
+
// 生成eslint.config.mjs配置文件
|
88
|
+
async generateEslintConfig() {
|
89
|
+
const templatePath = path.join(__dirname, 'config/eslint/eslintTemplate.js')
|
90
|
+
const writePath = path.join(process.cwd(), 'eslint.config.mjs')
|
91
|
+
await this.generateConfigFile(templatePath, writePath)
|
92
|
+
}
|
93
|
+
|
94
|
+
// 生成commitlint.config.mjs配置文件
|
95
|
+
async generateCommitlintConfig() {
|
96
|
+
const templatePath = path.join(__dirname, 'config/commitLint/commitlintTemplate.js')
|
97
|
+
const writePath = path.join(process.cwd(), 'commitlint.config.mjs')
|
98
|
+
await this.generateConfigFile(templatePath, writePath)
|
99
|
+
}
|
100
|
+
|
101
|
+
// husk初始化
|
102
|
+
huskyInit() {
|
103
|
+
return new Promise((resolve, reject) => {
|
104
|
+
exec(
|
105
|
+
`npm run prepare`,
|
106
|
+
{ cwd: process.cwd() },
|
107
|
+
(err, _stdout, _stderr) => {
|
108
|
+
if (err) {
|
109
|
+
reject(new Error(`在husk初始化时发生错误:${err}`))
|
110
|
+
return
|
111
|
+
}
|
112
|
+
resolve()
|
113
|
+
},
|
114
|
+
)
|
115
|
+
})
|
116
|
+
}
|
117
|
+
|
118
|
+
// husk生成pre-commit钩子和commint-msg钩子
|
119
|
+
async huskyGenerateHooks() {
|
120
|
+
// 生成commit-msg文件
|
121
|
+
const commitMsgTemplate = path.join(__dirname, 'config/gitHooks/commitMsgTemplate')
|
122
|
+
const commitMsgWritePath = path.join(process.cwd(), '.husky/commit-msg')
|
123
|
+
await this.generateConfigFile(commitMsgTemplate, commitMsgWritePath)
|
124
|
+
|
125
|
+
// 生成pre-commit文件
|
126
|
+
const preCommitTemplate = path.join(__dirname, 'config/gitHooks/preCommitTemplate')
|
127
|
+
const preCommitWritePath = path.join(process.cwd(), '.husky/pre-commit')
|
128
|
+
await this.generateConfigFile(preCommitTemplate, preCommitWritePath)
|
129
|
+
}
|
130
|
+
|
131
|
+
// 判断文件是否存在
|
132
|
+
async fileExists(filePath) {
|
133
|
+
try {
|
134
|
+
await fs.promises.access(filePath)
|
135
|
+
return true
|
136
|
+
}
|
137
|
+
catch {
|
138
|
+
return false
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
// 添加.vscode/settings.json配置
|
143
|
+
async addVscodeSettings() {
|
144
|
+
// 判断文件是否存在
|
145
|
+
const vscodeSettingsPath = path.join(process.cwd(), '.vscode/settings.json')
|
146
|
+
const isExists = await this.fileExists(vscodeSettingsPath)
|
147
|
+
// 文件存在则合并配置
|
148
|
+
if (isExists) {
|
149
|
+
const content = await this.readFileContent(vscodeSettingsPath)
|
150
|
+
const settingsObj = JSON.parse(content)
|
151
|
+
for (const key in settingsTemplate) {
|
152
|
+
if (settingsObj[key] !== undefined) {
|
153
|
+
console.log(`\nsettings.json中 ${key} 配置项已存在, 未进行更改...`)
|
154
|
+
continue
|
155
|
+
}
|
156
|
+
settingsObj[key] = settingsTemplate[key]
|
157
|
+
}
|
158
|
+
const settingsJson = JSON.stringify(settingsObj, null, 2)
|
159
|
+
await this.createFile(vscodeSettingsPath, settingsJson)
|
160
|
+
return
|
161
|
+
}
|
162
|
+
// 判断文件所在目录是否存在
|
163
|
+
const dirPath = path.dirname(vscodeSettingsPath)
|
164
|
+
if (!fs.existsSync(dirPath)) {
|
165
|
+
// 目录不存在,创建目录
|
166
|
+
fs.mkdirSync(dirPath, { recursive: true })
|
167
|
+
}
|
168
|
+
await this.createFile(
|
169
|
+
vscodeSettingsPath,
|
170
|
+
JSON.stringify(settingsTemplate, null, 2),
|
171
|
+
)
|
172
|
+
}
|
173
|
+
|
174
|
+
// 初始化
|
175
|
+
async init() {
|
176
|
+
try {
|
177
|
+
console.log('\x1B[32m%s\x1B[0m', '************** 正在初始化 ************\n')
|
178
|
+
// 动画
|
179
|
+
this.animate.start()
|
180
|
+
|
181
|
+
// 安装依赖
|
182
|
+
await this.installDependencies()
|
183
|
+
|
184
|
+
// 生成eslint.config.mjs配置文件
|
185
|
+
await this.generateEslintConfig()
|
186
|
+
|
187
|
+
// 生成commitlint.config.mjs配置文件
|
188
|
+
await this.generateCommitlintConfig()
|
189
|
+
|
190
|
+
// 在package.json中添加配置
|
191
|
+
await this.addConfigToPackageJson()
|
192
|
+
|
193
|
+
// husky初始化
|
194
|
+
await this.huskyInit()
|
195
|
+
|
196
|
+
// 生成pre-commit钩子和commint-msg钩子文件
|
197
|
+
await this.huskyGenerateHooks()
|
198
|
+
|
199
|
+
// 添加.vscode/settings.json配置
|
200
|
+
await this.addVscodeSettings()
|
201
|
+
|
202
|
+
// 关闭动画
|
203
|
+
this.animate.stop()
|
204
|
+
console.log('\x1B[32m%s\x1B[0m', '\n\n************** 初始化完成 ************')
|
205
|
+
}
|
206
|
+
catch (error) {
|
207
|
+
// 关闭动画
|
208
|
+
this.animate.stop()
|
209
|
+
console.error('\n\n出错了:', error)
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
// 动画类
|
215
|
+
class StyleConfigAnimate {
|
216
|
+
constructor() {
|
217
|
+
this.timer = null
|
218
|
+
this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
219
|
+
this.frameIndex = 0
|
220
|
+
}
|
221
|
+
|
222
|
+
// 加载中动画
|
223
|
+
animateArrow() {
|
224
|
+
process.stdout.write(`\r初始化中...${this.frames[this.frameIndex]}`)
|
225
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length
|
226
|
+
this.timer = setTimeout(() => {
|
227
|
+
this.animateArrow()
|
228
|
+
}, 100) // 调整速度
|
229
|
+
}
|
230
|
+
|
231
|
+
// 开始动画
|
232
|
+
start() {
|
233
|
+
this.animateArrow()
|
234
|
+
}
|
235
|
+
|
236
|
+
// 停止动画
|
237
|
+
stop() {
|
238
|
+
clearTimeout(this.timer)
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
module.exports = { StyleConfigInit }
|
package/package.json
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"name": "style-code",
|
3
|
+
"type": "commonjs",
|
4
|
+
"version": "1.0.0",
|
5
|
+
"author": "lei",
|
6
|
+
"license": "ISC",
|
7
|
+
"main": "index.js",
|
8
|
+
"bin": {
|
9
|
+
"style": "bin/index.js"
|
10
|
+
},
|
11
|
+
"files": [
|
12
|
+
"README.md",
|
13
|
+
"bin",
|
14
|
+
"config",
|
15
|
+
"const",
|
16
|
+
"index.js"
|
17
|
+
],
|
18
|
+
"dependencies": {
|
19
|
+
"commander": "^12.1.0"
|
20
|
+
}
|
21
|
+
}
|