0%

代码规范与项目结构

参考

资源

项目结构

代码规范

规范的代码能减少团队成员间的沟通成本, 而规范\优雅的 Standard 代码, 则使人赏心悦目!

Standard

Standard 是现在 JS 最流行的规范, 也是能让你的代码最简洁的规范.

细则如下:

  • 使用两个空格 – 进行缩进
  • 字符串使用单引号 – 需要转义的地方除外
  • 不再有冗余的变量 – 这是导致 大量 bug 的源头!
  • 无分号 – 这没什么不好。不骗你!
  • 行首不要以 (, [, or `\ 开头, 这是省略分号时唯一会造成问题的地方
  • 关键字后加空格 if (condition) { ... }
  • 函数名后加空格 function name (arg) { ... }
  • 坚持使用全等 === 摒弃 == 一但在需要检查 null || undefined 时可以使用 obj == null
  • 一定要处理 Node.js 中错误回调传递进来的 err 参数。
  • 使用浏览器全局变量时加上 window 前缀 – document 和 navigator 除外
  • 避免无意中使用到了这些命名看上去很普通的全局变量, open, length, event 还有 name。

你可以在这里查看实际的例子以加深理解

ESLints

ESLints 是一个实时代码格式检查工具, 它也可以在你保存文件修改时自动按照你定义好的 JS 代码规范来格式化你的代码.

ESLints 中文网

你可以参考下面这篇文章以及 ESLints 官方文档配置适合自己的 ESLints 配置文件:

深入浅出 eslint ——关于我学习 eslint 的心得 —— @掘金 时长: 5分钟

ESLints 的配置文件一般包含在脚手架提供的项目模板中,
不需要我们自己写,
不过参考上面的文档现配一个也很简单.

如果你需要自己写 eslint 插件的话:

开发 eslint 规则 —— 掘金 时长: 20分钟

在 ESLints 中使用 Standard 规范

eslint-config-standard

在 vscode 编辑器中配置 Prettier-StandardESlint 扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
* 插件名: ESLint插件的配置
* 描述:根据定义的规则对相应的语言的语法风格进行严格的约束,以统一编码风格降低阅读沟通成本
* 详情:https: //marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
*/
// 禁用默认 vscode 的 js 格式化
"javascript.validate.enable": false,
"editor.formatOnPaste": false,
"editor.formatOnSave": false,
"eslint.autoFixOnSave": true, // 启用保存时自动修复,默认只支持 .js 文件
"eslint.validate": [
"javascript", // 用 eslint 的规则检测 js 文件
{
"language": "vue", // 检测vue文件
"autoFix": true // 为 vue 文件开启保存自动修复的功能
},
{
"language": "html",
"autoFix": true
},
],
"[javascript]": {
"editor.defaultFormatter": "numso.prettier-standard-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[javascriptreact]": {
"editor.defaultFormatter": "numso.prettier-standard-vscode"
},
/*
* 插件名:prettier
* 描述:按照设定的规则格式化对应的文档
* 详情:https: //marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
* 注意:此插件被 Vetur 插件依赖
*/
// 使用单引号?
"prettier.singleQuote": true,
// 要分号?
"prettier.semi": false,
//将>多行JSX元素放在最后一行的末尾,而不是单独放在下一行
"prettier.jsxBracketSameLine": true,

lint-staged , huskycommitlint

在我们要将代码 commit 到本地仓库时, 对 commit message 的格式和 staged files 的代码样式进行规范, 对一个合格的团队来说是非常重要的!
lint-staged , huskycommitlint 就是可以帮助我们对 commit message 的格式和 staged files 的代码样式进行规范的工具.

lint-staged 与 eslint 结合使用

引入 lint-staged 和 eslint

1
npm i -D lint-staged eslint

package.json

1
2
3
4
5
6
7
8
{
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
}
}

git hook husky

引入 husky

1
npm i -D husky

简单的使用 verifyCommit.js

package.json

1
2
3
4
5
6
7
8
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "node scripts/verifyCommit.js"
}
},
}

其中 的 verifyCommit.js 可参考 vue-next 项目
使用 Angular 团队的 commit 约定 : conventional-changelog
verifyCommit.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Invoked on the commit-msg git hook by yorkie.

const chalk = require('chalk')
const msgPath = process.env.GIT_PARAMS
const msg = require('fs')
.readFileSync(msgPath, 'utf-8')
.trim()

const commitRE = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip)(\(.+\))?: .{1,50}/

if (!commitRE.test(msg)) {
console.log()
console.error(
` ${chalk.bgRed.white(' ERROR ')} ${chalk.red(
`invalid commit message format.`
)}\n\n` +
chalk.red(
` Proper commit message format is required for automated changelog generation. Examples:\n\n`
) +
` ${chalk.green(`feat(compiler): add 'comments' option`)}\n` +
` ${chalk.green(
`fix(v-model): handle events on blur (close #28)`
)}\n\n` +
chalk.red(` See .github/commit-convention.md for more details.\n`)
)
process.exit(1)
}

注意引入的开发时依赖: chalk

1
npm i -D chalk

husky 结合 commitlint

commitlint 是标准化的 git commit lint 工具

Conventional commit format

type(scope?): subject

  • What type of changes am I committing?
  • What scope is affected by my changes?
  • subject: When applied, the software will …
1
2
npm install --save-dev @commitlint/config-angular @commitlint/cli
npm install --save-dev @commitlint/prompt @commitlint/prompt-cli

package.json

1
2
3
4
5
6
7
8
9
10
11
{
"scripts": {
"gc": "commit"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}

commitlint.config.js

1
module.exports = { extends: ['@commitlint/config-angular'] }

semantic-release (语义化版本)

1
npm i -D semantic-release

package.json

1
2
3
"scripts": {
"semantic-release": "semantic-release",
}

semantic-release 结合 travis-ci 和 travis-deploy-once 自动化发布

1
npm i -D travis-deploy-once

package.json

1
2
3
4
"scripts": {
"deploy": "npm run travis-deploy-once 'npm run semantic-release'",
"travis-deploy-once": "travis-deploy-once"
}

.travis.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
language: node_js
cache:
directories:
- ~/.npm
notifications:
email: true
node_js:
- 'node'
- 'lts/*'
install: npm install
before_install:
- npm install -g npm@5
- npm install -g greenkeeper-lockfile@1
jobs:
include:
- stage: test
script:
- npm run build
- npm run build:prod
- npm run lint
- npm run test
before_script: greenkeeper-lockfile-update
after_script: greenkeeper-lockfile-upload
- stage: deploy
if: branch = master
script:
- npm run deploy

jest

安装 cross-env

1
npm i -D cross-env

安装 [core-js][]

1
npm -D i core-js@3

安装 bable 和 jest

1
npm i -D @babel/core @babel/preset-env @babel/cli babel-jest jest

.babelrc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"env": {
"test": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
},
"modules": "auto",
"useBuiltIns": "usage",
"corejs": {
"version": 3,
"proposals": true
}
}
]
]
},
"production": {
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "usage",
"corejs": {
"version": 3,
"proposals": true
}
}
]
]
}
}
}

jest.config.js

1
2
3
4
5
6
7
8
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html

module.exports = {
collectCoverage: true,
testEnvironment: 'node',
testMatch: ['<rootDir>/__tests__/**/*spec.js']
}

package.json

1
2
3
4
5
6
7
{
"scripts": {
"build": "rollup -c",
"build:prod": "cross-env BABEL_ENV=production npm run build",
"test": "cross-env BABEL_ENV=test jest",
}
}

codecov

安装

1
npm install codecov --save-dev

package.json

1
2
3
4
5
{
"scripts": {
"codecov": "codecov",
}
}