规范化介绍
为什么要有规范化标准?
- 软件开发需要多人协同
- 不同开发者具有不同的编码习惯
- 不同的喜好增加项目维护成本
- 每个项目或者团队需要明确统一的标准 哪里需要规范化标准?
- 代码、文档、甚至是提交日志
- 开发过程中认为编写的成果物
- 代码标准化规范最为重要 实施规范化的方法:
- 编码前人为的标准约定
- 通过工具实现lint 常见的规范化实现方式:
- ESLint工具使用
- 定制ESLint校验规则
- ESLint对TypeScript的支持
- ESLint结合自动化工具或者Webpack
- 基于ESLint的衍生工具
- Stylelint工具的使用
ESLint
ESLint是最为主流的JavaScript Lint工具,监测JS代码质量。
安装ESLint步骤:
- 初始化项目
npm init -y - 安装ESLint模块为开发依赖
npm i eslint -D - 通过cli命令验证安装结果
ESLint配置文件解析
ESLint初始化:npx eslint --init,会生成.eslintrc.js文件
使用 ESLint 对 js 文件进行检查:npx eslint xxx.js
// .eslintrc.js
module.exports = {
// 标记当前代码运行环境
env: {
browser: true,
es2020: true
},
// 用于继承共享配置
extends: [
'standard'
],
// 用来设置语法解析器配置
parserOptions: {
ecmaVersion: 2015
},
// 配置每个校验规则的开启和关闭,值为warn、off、error
rules: {
'no-alert': "error"
},
// 配置全局变量
globals: {
"jQuery": "readonly"
}
}
配置注释
const str1 = "${name} is a coder" // eslint-disable-line no-template-curly-in-string
console.log(str1)
ESLint结合自动化工具
- 集成之后,ESLint一定会工作
- 与项目统一,管理更加方便
// gulpfile.js
const { src, dest, parallel, series, watch } = require('gulp')
const eslint = require('gulp-eslint');
const del = require('del')
const browserSync = require('browser-sync')
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
const bs = browserSync.create()
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist', 'temp'])
}
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' })
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.eslint())
.pipe(plugins.eslint.format())
.pipe(plugins.eslint.failAfterError())
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const serve = () => {
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
], bs.reload)
bs.init({
notify: false,
port: 2080,
// open: false,
// files: 'dist/**',
server: {
baseDir: ['temp', 'src', 'public'],
routes: {
'/node_modules': 'node_modules'
}
}
})
}
const useref = () => {
return src('temp/*.html', { base: 'temp' })
.pipe(plugins.useref({ searchPath: ['temp', '.'] }))
// html js css
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true
})))
.pipe(dest('dist'))
}
const compile = parallel(style, script, page)
// 上线之前执行的任务
const build = series(
clean,
parallel(
series(compile, useref),
image,
font,
extra
)
)
const develop = series(compile, serve)
module.exports = {
clean,
build,
develop,
script
}
ESLint结合webpack
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/main.js',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: 'eslint-loader', //eslint-loader需要放在最后,先执行
enforce: "pre"
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
}
ESLint检查TypeScript
// .eslintrc.js
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard'
],
// 指定语法解析器
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 11
},
// 插件
plugins: [
'@typescript-eslint'
],
rules: {
}
}
Stylelint
Stylelint使用介绍:
- 提供默认的代码检查规则
- 提供cli工具,快速调用
- 通过插件知识Sass、Less、PostCSS
- 支持Gulp或webpack集成
安装:npm i stylelint -D
添加配置文件.stylelintrc.js
module.exports = {
// 共享文件
extends: [
"stylelint-config-standard", //npm i stylelint-config-standard -D
"stylelint-config-sass-guidelines" // 校验Sass npm i stylelint-config-sass-guidelines -D
]
}
Prettier
Prettier是一款通用的前端代码格式化工具,可以完成代码的自动格式化。
Prettier具有以下几个有优点:
- 可配置化
- 支持多种语言
- 集成多数的编辑器
- 简洁的配置项
安装:npm install --save-dev --save-exact prettier
只需要使用 eslint-plugin-prettier 来添加Prettier作为ESLint的规则配置。
npm i -D prettier eslint-plugin-prettier
// .stylelintrc.js
module.exports = {
// 共享文件
extends: [ "prettier" ],
rules: {
"prettier/prettier": "error"
}
}
ESLint结合Git Hooks实现代码提交前的lint检查
Git Hooks
介绍:
- Git Hooks也称之为git钩子,每个钩子都对应一个任务
- 通过shell脚本可以编写钩子任务触发时要具体执行的操作
操作:
创建了一个目录,并初始化git仓库。打开 .git,可以看到其中的hooks目录。
hooks目录中存放了很多sample文件,这里面的每一个sample,其实就是每一个git钩子。
我们只需要去关注pre-commit.sample这个钩子,因为它对应的就是commit操作,当我们在执行commit的时候就会去触发这个钩子中所定义的一些任务。
将pre-commit.sample拷贝一份,重命名为pre-commit,将其内容修改为如下:
然后在项目目录下创建一个测试的txt文件,随便写点内容,之后执行git操作
Husky
我们希望通过git钩子在代码提交之前去强制对代码执行lint操作,但是这里我们就遇到了一个很现实的问题,比如说,当下很多前端开发者并不擅长使用shell脚本来编写功能,而当前的功能又是我们必须要去使用的,所以就有人开发了一个npm模块,直接将Git Hooks的操作进行一个简单化的实现,这个模块就是Husky。
有了Husky模块,我们就可以实现在不编写shell脚本的情况下,也能够去直接使用git钩子所带来的一些功能。
安装:npm i -D husky
配置package.json
"scripts":{
"lint":"eslint ./index.js --fix"
},
"husky":{
"hooks":{
"pre-commit":"npm run lint"
}
}
这样我们在使用git提交代码的时候就会执行npm run lint,也就是执行eslint ./index.js --fix
lint-staged
经过以上对Husky的使用,我们已经可以对代码在commit之前进行lint检查,但是如果我们想要在检查之后再对代码进行一些后续的操作,例如格式化,这时候Husky就显得有些不够用了。所以我们就要用到另一个模块,也就是 lint-staged。它可以配合Husky,再对代码继续执行一些其他的操作。
安装lint-staged:npm i lint-staged -D
配置package.json
"scripts": {
"precommit":"lint-staged"
},
"husky": {
"hooks": {
"pre-commit": "npm run precommit"
}
},
"lint-staged":{
"*.js":[ // 在这里配置一些我们后续想要执行的任务
"eslint --fix",
"git add"
]
}
如此一来,我们对代码修改后,执行git add .,再执行git commit -m "111"提交代码,就会执行eslint --fix命令,检查代码没问题后会继续执行git add命令,最后我们就可以通过git push将代码推送至远端仓库了。