项目仓库:https://github.com/kaqiinono/scripts
安装依赖
代码规范需要用到的依赖
npm install cz-customizable commitizen @commitlint/{cli,config-conventional} husky lint-staged standard-version prettier eslint-config-prettier eslint-plugin-prettier --save-dev
各依赖性的作用
- @commitlint/{cli,config-conventional} 进行代码提交约束,制定提交规则
- lint-staged 进行代码格式化和代码格式化校验
- standard-version 自动提升版本号,打tag,生成changelog
- commitizen 命令式提交commit,提交代码更直观
- cz-customizable 可自定义commitizen内容
- husky 进行提交校验
- prettier 代码格式化
@commitlint/{cli,config-conventional}
- .commitlintrc.json
{
"extends": [ "@commitlint/config-conventional" ],
"rules": {
"header-max-length": [
0,
"always",
100
],
"type-enum": [
2,
"always",
[
"feat",
"fix",
"docs",
"style",
"refactor",
"test",
"revert",
"perf",
"chore",
"conflict",
"release",
"merge",
"repair"
]
]
}
}
lint-staged
- 文件名:.lintstagedrc.json
{
"{src,apps,packages,libs,test}/**/*..{js,ts,jsx,tsx}": ["eslint --fix"],
"./**/*.{ts,js,jsx,tsx,json,*rc}": ["prettier --write"]
}
standard-version
- 文件名:.versionrc.json
{
"changelogHeader": "# Change Log", // change log title
"releaseCommitMessageFormat": "release: 发布 v{{currentTag}}",
"issueUrlFormat": "http://jagile.jd.com/test-manage/jbug/{{id}}",
"types": [
{
"type": "feat",
"section": "需求列表"
},
{
"type": "fix",
"section": "Bug修复"
},
{
"type": "perf",
"section": "优化列表"
},
{
"type": "chore",
"hidden": true, // hide==true的提交记录不显示在changelog中
"section": "构建过程或辅助工具的变动"
},
{
"type": "docs",
"hidden": true,
"section": "文档"
},
{
"type": "style",
"hidden": true,
"section": "格式(不影响代码运行的变动)"
},
{
"type": "refactor",
"hidden": true,
"section": "重构(即不是新增功能,也不是修改bug的代码变动)"
},
{
"type": "test",
"hidden": true,
"section": "测试用例"
},
{
"type": "conflict",
"hidden": true,
"section": "解决冲突"
},
{
"type": "revert",
"hidden": true,
"section": "回退"
},
{
"type": "release",
"hidden": true,
"section": "发布"
},
{
"type": "merge",
"hidden": true,
"section": "合并"
},
{
"type": "repair",
"hidden": true,
"section": "修补"
}
]
}
commitizen、cz-customizable
- 文件名:.czrc
{
"path": "cz-customizable"
}
- 文件名:.cz-config.js
- 代码提示需要跟代码约束保持一致
// https://github.com/leoforfree/cz-customizable/edit/master/cz-config-EXAMPLE.js
const standard = require('./.versionrc.json');
module.exports = {
types: standard.types.map(st => ({
value: st.type,
name: st.section,
})),
scopes: [{ name: 'dm' }, { name: 'ge' }, { name: 'jsf' }],
allowTicketNumber: false,
isTicketNumberRequired: false,
ticketNumberPrefix: 'TICKET-',
ticketNumberRegExp: '\\d{1,5}',
messages: {
type: "Select the type of change that you're committing:",
scope: '\nDenote the SCOPE of this change (optional):',
// used if allowCustomScopes is true
customScope: 'Denote the SCOPE of this change:',
subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
breaking: 'List any BREAKING CHANGES (optional):\n',
footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
confirmCommit: 'Are you sure you want to proceed with the commit above?',
},
allowCustomScopes: true,
allowBreakingChanges: ['feat', 'fix'],
skipQuestions: ['body'],
subjectLimit: 100,
};
husky
husky install # 安装git hook
# 进行提交校验
npx husky add .husky/prepare-commit-msg "exec < /dev/tty && git cz --hook || true"
npx husky add .husky/pre-commit "npx lint-staged --allow-empty $1"
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
- .prettierrc
{
"printWidth": 120,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "avoid",
"endOfLine": "auto",
"overrides": [
{
"files": "*.json",
"options": {
"singleQuote": false
}
},
{
"files": ".*rc",
"options": {
"singleQuote": false,
"parser": "json"
}
}
]
}
脚本自动化
完整脚本示例
编写脚本
推荐使用shelljs进行shell命令的执行,以兼容windows环境
- setEnv.js
#!/usr/bin/env node
#!/usr/bin/env node
const path = require('path');
const {excute} = require('../shelljs/excute');
const root = process.cwd();
// npm > 7 否则无法创建script
const {stdout} = excute(`npm --version`, {
silent: true
});
if (stdout && stdout.split('.')[0] < 7) {
console.log(`npm版本(${stdout.trim()})过低,需要安装最新版本!`)
console.log('请输入您的开机密码进行授权===>')
excute(`sudo npm install npm -g`);
}
excute(`npm set-script release "standard-version --dry-run"`);
excute(`npm set-script postinstall "dm-husky"`)
excute(`npm install cz-customizable commitizen @commitlint/{cli,config-conventional} husky lint-staged standard-version prettier eslint-config-prettier eslint-plugin-prettier --save-dev`);
excute(`dm-husky --force --cz`);
excute(`cp -rf ${path.join(__dirname, 'files')}/ ${root}`);
- husky.js
#!/usr/bin/env node
const path = require('path');
const {excute} = require('../shelljs/excute');
const {existsSync} = require('fs');
const args = require('minimist')(process.argv.slice(2));
const root = process.cwd();
if (existsSync(path.resolve(root, '.husky/_')) && args.force !== true) {
console.info('husky exists,jump to next step!');
} else {
console.info('husky env begin to set:');
// excute(`npm cache clear --force`);
excute(`rm -rf ${path.resolve(root, '.husky')}`);
excute('npx husky install');
excute(`sh ${path.join(__dirname, 'husky.sh')}`);
if (args.cz) {
excute(`npx commitizen init cz-conventional-changelog --force --save-dev --save-exact`)
excute(`echo 'exec < /dev/tty && node_modules/.bin/cz --hook || true' > .git/hooks/prepare-commit-msg`)
}
}
- husky.sh
#!/bin/bash
npx husky add .husky/prepare-commit-msg "exec < /dev/tty && git cz --hook || true"
npx husky add .husky/pre-commit "npx lint-staged --allow-empty $1"
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
- …/shelljs/excute
#!/usr/bin/env node
const shell = require('shelljs');
const root = process.cwd();
function excute(cmd, opt) {
const { stdout, stderr, code } = shell.exec(
cmd, {
cwd: root,
...opt
} );
if (code === 0) {
console.log(stdout);
} else {
console.log(stdout);
console.log(stderr);
// process.exit(1);
}
return { stdout, stderr, code }
}
module.exports = {
excute
};
创建命令
- package.json
{
"name": "kaqiinono-scripts",
"version": "1.0.3",
"description": "",
"main": "index.js",
"bin": {
"dm-husky": "env/husky.js",
"dm-rule": "rule/setEnv.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"minimist": "^1.2.5",
"shelljs": "^0.8.5",
"walk": "^2.3.15"
}
}
发布
npm publish
引入项目
# 安装可执行脚本
npm install kaqiinono-scripts -D
# 执行命令
dm-rule