本文将会联合 ESLint、Prettier、husky、lint-stage、gulp.js 等工具使得我的项目一键化操作,缩小在格式化、代码查看等操作上浪费时间,因为大前端真的太多货色学了,不学会“偷懒”的话,咱们就要落后更多了。
本系列文章的示例 Demo 在这里 ???? GitHub: wechat_applet_demo。
分为两篇文章介绍:
- 使 Prettier 一键格式化 WXSS(上集)
- 使 Prettier 一键格式化 WXSS(下集)
在简书也有更新 ???? 这里。
最近在做公司部门前端我的项目由 SVN 迁徙 Git 的事件,因为历史代码在此之前并没有引入相似 ESLint、Prettier 的代码查看或者格局束缚等工具。
目前部门仅剩我一人保护这十几个小程序、H5 前端我的项目。当初只有接触以前那些没有经手的我的项目,就头疼不想改。尽管思维是这样,但很无奈,谁让我只是一个“打工仔”呢!
吐槽完,入正题。
一、必备
1. 新建一个微信小程序我的项目
此处过于简略省略一万字 …
# 或者克隆 wechat_applet_demo 我的项目下来
$ cd your_folder
$ git clone git@github.com:toFrankie/wechat_applet_demo.git
2. 应用 yarn 作为包管理工具
yarn
相干的装置不在本系列教程,置信你们都懂。也不再赘述,自行搜寻。
3. 应用 Visual Studio Code 作为编辑器
尽管从业有一段时间了,不好意思,前端开发我只用 VS Code,未来好长一段时间应该还是它。至于什么 WebStorm、Atom、Sublime Text 等,用过但当初曾经不会了。
Anyway,什么开发工具不重要,本人用着难受就好。
上面介绍几个与本我的项目相干的 VS Code 插件
ESLint:自动检测 ESLint Rule,不合乎规定时,在编辑页面会有正告 ️
Prettier – Code formatter:可用于格式化
依照以上两个插件之后,须要对编辑器做增加一些配置。
思考到多人开发的场景,而每个人的开发工具配置不尽相同,所以我把以下配置放到我的项目根目录下中,并将其退出 Git 版本控制中,这样每个人拿到我的项目都有此配置了。
门路是:your_project/.vscode/settings.json
{
"files.associations": {
"*.wxss": "css",
"*.wxs": "javascript",
"*.acss": "css",
"*.axml": "html",
"*.wxml": "html",
"*.swan": "html"
},
"files.trimTrailingWhitespace": true,
"eslint.workingDirectories": [{"mode": "auto"}],
"eslint.enable": true, // 是否开启 vscode 的 eslint
"eslint.options": {
// 指定 vscode 的 eslint 所解决的文件的后缀
"extensions": [".js", ".ts", ".tsx"]
},
"eslint.validate": ["javascript"],
"editor.codeActionsOnSave": {"source.fixAll.eslint": true},
"git.ignoreLimitWarning": true
}
二、要开始了
1. yarn
初始化生成 package.json
:
2. 装置 ESLint、Prettier 相干依赖
若要应用 ESLint,往往须要配置很多繁冗的 rules 规定,如果每个人都要这种做的话,显然会消耗很多精力。于是就有人站了进去,并在 GitHub 上开源了他们的代码标准库,比拟风行的有 airbnb、standard、prettier 等。
在这里我抉择的是国内腾讯 AlloyTeam 团队出品的 eslint-config-alloy 开源标准库。
其实他们团队最开始应用 Airbnb 规定,然而因为它过于严格,局部规定还是须要个性化,导致起初越改越多,最初决定从新保护一套。通过两年多的打磨,当初 eslint-config-alloy 曾经十分成熟了。
我抉择它的几点起因:
- 实用于 React/Vue/Typescript 我的项目
- 款式相干规定由 Prettier 治理
- 有中文文档和网站示例(就我那糟糕的英语水平,这点极吸引我,哈哈)
- 更新快,且领有官网保护的 vue、typescript、react+typescript 规定
$ yarn add --dev babel-eslint@10.0.3
$ yarn add --dev eslint@6.7.1
$ yarn add --dev eslint-config-alloy@3.7.1
$ yarn add --dev eslint-config-prettier@6.10.0
$ yarn add --dev eslint-plugin-prettier@3.1.4
$ yarn add --dev prettier@2.0.5
$ yarn add --dev prettier-eslint-cli@5.0.0
3. 装置完依赖,那么就要加上 ESLint、Prettier 的配置文件
他们的配置文件能够有多种,这里应用 JavaScript 格局别离是 .eslintrc.js
、.prettierrc.js
,都搁置在我的项目根目录下。
对于配置我就不开展说了,若有纳闷的,能够自行搜寻查找答案或者评论留言给我。
// .eslintrc.js
module.exports = {
root: true,
parser: 'babel-eslint',
env: {
browser: true,
es6: true,
node: true,
commonjs: true
},
extends: ['alloy'],
plugins: ['prettier'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
__DEV__: true,
__WECHAT__: true,
__ALIPAY__: true,
App: true,
Page: true,
Component: true,
Behavior: true,
wx: true,
my: true,
swan: true,
getApp: true,
getCurrentPages: true
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
},
rules: {
'no-debugger': 2,
'no-unused-vars': 1,
'no-var': 0,
'no-param-reassign': 0,
'no-irregular-whitespace': 0,
'no-useless-catch': 1,
'max-params': ['error', 3],
'array-callback-return': 1,
eqeqeq: 0,
indent: ['error', 2, { SwitchCase: 1}]
}
}
// .prettierrc.js
module.exports = {
printWidth: 120,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: 'as-needed',
// jsx 不应用单引号,而应用双引号
jsxSingleQuote: false,
// 开端不须要逗号
trailingComma: 'none',
// 大括号内的首尾须要空格
bracketSpacing: true,
// jsx 标签的反尖括号须要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,无需括号
arrowParens: 'avoid',
// 每个文件格式化的范畴是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不须要写文件结尾的 @prettier
requirePragma: false,
// 不须要主动在文件结尾插入 @prettier
insertPragma: false,
// 应用默认的折行规范
proseWrap: 'preserve',
// 依据显示款式决定 html 要不要折行
htmlWhitespaceSensitivity: 'css',
// 换行符应用 lf
endOfLine: 'lf'
}
4. 配置 ESLint、Prettier 疏忽规定
对应的文件是 .eslintignore
、.prettierignore
,同样的都放在我的项目根目录下。
这些就依据本人我的项目理论状况做调整了,以下仅供参考:
# .eslintignore
*.min.js
typings
node_modules
# .prettierignore
*.min.js
/node_modules
/dist
# OS
.DS_Store
.idea
.editorconfig
.npmrc
package-lock.json
# Ignored suffix
*.log
*.md
*.svg
*.png
*ignore
## Built-files
.cache
dist
5. 增加 .editorconfig
配置文件
它是用来抹平不同编辑器之间的差别的。同样搁置在我的项目根目录下。
# .editorconfig
# http://editorconfig.org
# https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties
# 根目录的配置文件,编辑器会由当前目录向上查找,如果找到 `roor = true` 的文件,则不再查找
root = true
# 匹配所有的文件
[*]
# 缩进格调:space
indent_style = space
# 缩进大小 2
indent_size = 2
# 换行符 lf
end_of_line = lf
# 字符集 utf-8
charset = utf-8
# 不保留行末的空格
trim_trailing_whitespace = true
# 文件开端增加一个空行
insert_final_newline = true
# 运算符两遍都有空格
spaces_around_operators = true
# 对所有的 js 文件失效
[*.js]
# 字符串应用单引号
quote_type = single
[*.md]
trim_trailing_whitespace = false
6. 增加 npm scripts
增加三条脚本指令:
"eslint": "eslint ./ --ext .js"
"eslint:fix": "eslint --fix ./ --ext .js"
"prettier:fix": "prettier --config .prettierrc.js --write'./**/*.{js,css,less,scss,json}'"
通过 yarn run <command>
即可执行一键格式化和修复了,当然了 ESLint 应用 --fix
只能修复一部分,残余的只能手动解决了。
{
"name": "wechat_applet_demo",
"version": "1.0.0",
"description": "微信小程序 Demo",
"main": "app.js",
"repository": "git@github.com:toFrankie/wechat_applet_demo.git",
"author": "Frankie <1426203851@qq.com>",
"license": "MIT",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\"&& exit 1",
"eslint": "eslint ./ --ext .js",
"eslint:fix": "eslint --fix ./ --ext .js",
"prettier:fix": "prettier --config .prettierrc.js --write'./**/*.{js,css,less,scss,json}'"},"devDependencies": {"babel-eslint":"10.0.3","eslint":"6.7.1","eslint-config-alloy":"3.7.1","eslint-config-prettier":"6.10.0","eslint-plugin-prettier":"3.1.4","prettier":"2.0.5","prettier-eslint-cli":"5.0.0"}
}
三、你认为完了?
不不不,本文我最想分享的是上面这个,后面的内容都比较简单,很多人都懂了。
Prettier 反对的 JavaScript、JSX、Angular、Vue、Flow、TypeScript、CSS、Less、Scss、HTML、JSON、GraphQL、Markdown(GFM、MDX)、YAML 的代码格式化。
但其实是不能辨认 wxss
、acss
等小程序特有的层叠款式,只管它们规定与 CSS 无异,然而 Prettier 并没有解析器去解析它们。
咱们试图去调整脚本命令为(增加 *.wxss
扩展名的文件):
{
"scripts": {"prettier:fix": "prettier --config .prettierrc.js --write'./**/*.wxss'",}
}
而后去执行的时候就会报错,如下:
[error] No parser could be inferred for file: app.wxss
既然这样走不通的话,总不能利用 VS Code 的 Prettier 插件一个一个地去格式化 *.wxss
的文件吧,那样工作量太大了,不合乎咱们“偷懒”的做法。
那么如何解决呢?
我应用的是 Gulp.js 来解决。 如果对 Gulp 不太熟悉了,点击这里理解一下。
四、Gulp.js
简略说下 Gulp.js 的工作形式,它应用的是 Node.js 中的 stream
(流),首先获取到须要的 stream
,而后通过 stream
的 pipe()
办法把流导入到你想要的中央。比方 Gulp 插件中,通过插件解决后的流又能够导入到其余插件汇总,当然也能够把流写入文件中,所以 Gulp 是以 stream
为媒介的,它不须要频繁的生成临时文件,这也是 Gulp 的速度比 Grunt 快的一个起因。
我刚开始时的想法是:首先将
wxss
(acss
)转换并导出为css
,接着删除wxss
(acss
)文件,再者应用 Prettier 对css
文件进行格式化,转回wxss
(acss
)之后,再删除掉css
文件。这个过程会频繁的生成临时文件,思路是有点像 Grunt。然而理解了 Gulp 的思维后,其实它帮咱们省掉了频繁增删文件的环节,全副放在内存中操作,也会更快一些,所以此前的计划被我否掉了。
上面咱们只用到 Gulp 的其中两个 API,gulp.src()
和 gulp.dest()
。
1. gulp.src()
这个办法是用来获取流的,但要留神这个流外面的内容不是原始的文件流,而是一个虚构文件对象流(Vinyl files),这个虚构文件对象中存储着原始文件的门路、文件名、内容等信息。(这里不深刻,点到为止,有趣味自行理解)
语法:gulp.src(globs[, options])
- globs:是文件匹配模式,用来匹配文件门路(包含文件名)
- options:为可选参数,通常状况咱们不须要用到
* 对于参数具体阐明,请看文档。
2. gulp.dest()
该办法是用来写文件的
gulp.dest(path[, options])
- path:是写入文件的门路
- options:为可选参数,通常状况咱们不须要用到
要想应用好 gulp.dest()
这个办法,就要了解给它传入的门路参数与最终生成的文件的关系。
Gulp 的应用流程个别是:首先通过 gulp.src()
办法获取到咱们想要解决的文件流,而后把文件流通过 pipe()
办法导入到 Gulp 的插件中,最初把通过插件解决后的流再通过 pipe()
办法导入到 gulp.dest()
中,gulp.dest()
办法则把流中的内容写入到文件中。
这里须要弄清楚的一点是,咱们给 gulp.dest()
传入的门路参数,只能用来指定要生成的文件的目录,而不能指定生成文件的文件名,它生成文件的文件名应用的是导入到它的文件流本身的文件名,所以生成的文件名是由导入到它的文件流决定的,即便咱们给它传入一个带有文件名的门路参数,而后它也会把这个文件名当做是目录名,例如:
const gulp = require('gulp')
gulp.src('script/jquery.js').pipe(gulp.dest('dist/foo.js'))
// 最终生成的文件门路为 dist/foo.js/jquery.js,而不是 dist/foo.js
若须要批改文件名,须要应用插件 gulp-rename。
- 对于上述 Gulp 的 API 与办法阐明,次要参考自官网文档与无双的一篇文章。
五、开始配置
首先,装置 Gulp 相干依赖包。
$ yarn add --dev gulp@4.0.2
$ yarn add --dev gulp-clean@0.4.0
$ yarn add --dev gulp-debug@4.0.0
$ yarn add --dev gulp-prettier@3.0.0
$ yarn add --dev gulp-rename@2.0.0
接着,咱们在我的项目根目录下创立一个 gulpfile.js
文件。
Gulp.js 官网疾速入门的教程,很简略,这里不在赘述。
思路:应用
gulp.src()
获取流,而后应用 Gulp 插件对流别离作重命名(gulp-rename)、格式化(gulp-prettier
)、再重命名回来(gulp-rename
)、最初导出(gulp.dest()
)。过程中有利用gulp-debug
插件来查看一些信息。
这里我对微信小程序、支付宝小程序的层叠款式都解决了。
// gulpfile.js
const {series, parallel, src, dest} = require('gulp')
const rename = require('gulp-rename')
const debug = require('gulp-debug')
const clean = require('gulp-clean')
const prettier = require('gulp-prettier')
const config = require('./.prettierrc')
// wxss 一键格式化
const wxssPrettier = () => {return src('./**/*.wxss')
.pipe(
// 能够利用插件,查看一些 debug 信息
debug())
.pipe(
// 重写扩大名为 css,能力被 Prettier 辨认解析
rename({extname: '.css'})
)
.pipe(
// Prettier 格式化
prettier(config)
)
.pipe(
// 从新将扩展名改为 wxss
rename({extname: '.wxss'})
)
.pipe(
// 导出文件
dest(__dirname)
)
}
// acss 一键格式化
const acssPrettier = () => {return src('./**/*.acss')
.pipe(debug())
.pipe(
rename({extname: '.css'})
)
.pipe(prettier(config))
.pipe(
rename({extname: '.acss'})
)
.pipe(dest(__dirname))
}
// 这里导出多个 task,通过 gulp xxx 就能来调用了,如 gulp all
// 对于 series、parallel API 别离是按程序执行(同步)、同时执行(并行)module.exports = {all: parallel(wxssPrettier, acssPrettier),
wxss: wxssPrettier,
acss: acssPrettier
}
通过以下形式调用就好了
// package.json
{
"scripts": {
"prettier:wxss": "gulp wxss",
"prettier:accs": "gulp acss",
"prettier:wxss:acss": "gulp all"
}
}
执行命令,咱们看到如下后果,阐明配置胜利了。
六、Git-Hooks
下面曾经实现了对 wxss
、acss
扩展名的文件进行一键格式化了。
还能够“更懒”一些,利用 git-hooks 咱们可实现在 commit
之前,对我的项目进行 ESLint、Prettier 检测和格式化,一旦呈现谬误,将进行 commit
操作。
因为本文篇幅曾经很长了,所以咱们放到下一篇持续写 …
七、插个题外话
因为本我的项目的 npm 包仅用于代码查看与格式化,并未参加页面代码逻辑中。所以我在小程序本地我的项目配置文件中增加上打包配置选项。
packOptions 用以配置我的项目在打包过程中的选项。打包是预览、上传时对我的项目进行的必须步骤。
目前能够指定
packOptions.ignore
字段,用以配置打包时对合乎指定规定的文件或文件夹进行疏忽,以跳过打包的过程,这些文件或文件夹将不会呈现在预览或上传的后果内。
* 须要留神的是支付宝小程序,在编写本文时还未反对相似 ignore
选项。
// project.config.js
{
"packOptions": {
"ignore": [
{
"type": "regexp",
"test": "\\.md$"
},
{
"type": "folder",
"test": "node_modules"
}
]
}
}