关于eslint:使Prettier一键格式化WXSS上集

19次阅读

共计 8788 个字符,预计需要花费 22 分钟才能阅读完成。

本文将会联合 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 的代码格式化。

但其实是不能辨认 wxssacss 等小程序特有的层叠款式,只管它们规定与 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,而后通过 streampipe() 办法把流导入到你想要的中央。比方 Gulp 插件中,通过插件解决后的流又能够导入到其余插件汇总,当然也能够把流写入文件中,所以 Gulp 是以 stream 为媒介的,它不须要频繁的生成临时文件,这也是 Gulp 的速度比 Grunt 快的一个起因。

我刚开始时的想法是:首先将 wxssacss)转换并导出为 css,接着删除 wxssacss)文件,再者应用 Prettier 对 css 文件进行格式化,转回 wxssacss)之后,再删除掉 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

下面曾经实现了对 wxssacss 扩展名的文件进行一键格式化了。

还能够“更懒”一些,利用 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"
      }
    ]
  }
}

正文完
 0