浅谈如何用 VS Code 舒服地编码

前言

现在写前端代码基本都 ES6 了,更前沿的都开始使用 TS 了。本文的目标是:配置项目和编辑器,使写代码更舒服。更舒服一般体现在3点:

  • 保存后实时报错(lint)
  • 保存后自动格式化(prettier)
  • 代码提交时自动lint且格式化(husky),确保团队代码风格统一

支持 ES6

  • 转ES5
    .babelrc
// react 项目
{
    "presets": [
        "env",
        "react"
    ],
    "plugins": [ "babel-plugin-transform-runtime","transform-object-rest-spread"] // 转换 rest 和 spread operator  runtime转异步函数
}
// react-native 项目
{
  "presets": ["module:metro-react-native-babel-preset"]
}
  • Eslint
    安装 eslint 和安装vs code 的 eslint 插件,书写 .eslintrc 文件
    插件的目的是实时提示错误,否则只能通过命令行编译后才知道错误
{
  "plugins": ["react", "prettier"],
  "globals": {
    "__DEV__": true,
    "__dirname": false,
    "__fbBatchedBridgeConfig": false,
    "cancelAnimationFrame": false,
    "clearImmediate": true,
    "clearInterval": false,
    "clearTimeout": false,
    "console": false,
    "document": false,
    "escape": false,
    "exports": false,
    "fetch": false,
    "global": false,
    "jest": false,
    "Map": true,
    "module": false,
    "navigator": false,
    "process": false,
    "Promise": true,
    "requestAnimationFrame": true,
    "require": false,
    "Set": true,
    "setImmediate": true,
    "setInterval": false,
    "setTimeout": false,
    "window": false,
    "XMLHttpRequest": false,
    "alert": true,
    "pit": false,
    "ReactElement": true
  },

  "parser": "babel-eslint",

  "env": {
    "es6": true
  },

  "rules": {
    "no-undef": "error",
    "react/jsx-boolean-value": 0,
    "react/jsx-curly-spacing": 1,
    "react/jsx-indent-props": [1, 2],
    "react/jsx-key": 1,
    "react/jsx-max-props-per-line": 0,
    "react/jsx-no-duplicate-props": 1,
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 1,
    "react/jsx-uses-react": 1,
    "react/jsx-uses-vars": 1,
    "react/no-danger": 1,
    "react/no-deprecated": 1,
    "react/no-did-mount-set-state": 0,
    "react/no-did-update-set-state": 1,
    "react/no-direct-mutation-state": 1,
    "react/no-is-mounted": 1,
    "react/no-multi-comp": [1, {"ignoreStateless": true}],
    "react/no-set-state": 0,
    "react/no-unknown-property": 1,
    "react/prefer-es6-class": 1,
    "react/react-in-jsx-scope": 1,
    "react/self-closing-comp": 1,
    "react/sort-comp": 1,
    "react/jsx-wrap-multilines": 1,
    "react/prop-types": [2, { "ignore": [ "children", "navigation" ]}],
    "jsx-quotes": 1,
    "prettier/prettier": "error"
  }
}

  • Prettier
    安装 Prettier 和安装vs code 的 Prettier 插件,书写.prettierrc。
    插件的目的是实时提示错误,否则只能通过命令行编译后才知道错误
{
    "printWidth": 80,
    "tabWidth": 2,
    "useTabs": false,
    "semi": true,
    "singleQuote": true,
    "trailingComma": "none",
    "bracketSpacing": true,
    "jsxBracketSameLine": false,
    "arrowParens": "avoid",
    "rangeStart": 0,
    "parser": "babylon",
    "requirePragma": false,
    "insertPragma": false,
    "proseWrap": "preserve"
}
  • Eslint 结合 Prettier
    安装 eslint-plugin-prettier ,这会让eslint调用prettier来格式化代码
    若是 react 项目,还需安装 eslint-plugin-react 以支持 jsx 语法
    最后开启 vscode 编辑器设置:
"prettier.eslintIntegration": true,
"eslint.autoFixOnSave": true,
"editor.formatOnSave": true,
  • Prettier 结合 Husky
    1、安装 husky 和 lint-staged
    2、修改 package.json 配置,设置 precommit 和 lint-staged
{
  "scripts": {
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,jsx}": ["eslint --fix", "git add"]
  }
}
  • 规范提交信息
npm i validate-commit-msg -D

在项目根目录新建 .vcmrc 文件

{
  "types": ["feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert"],
  "scope": {
    "required": false,
    "allowed": ["*"],
    "validate": false,
    "multiple": false
  },
  "warnOnFail": false,
  "maxSubjectLength": 100,
  "subjectPattern": ".+",
  "subjectPatternErrorMsg": "subject does not match subject pattern!",
  "helpMessage": "",
  "autoFix": true
}

修改 package.json

  "husky": {
    "hooks": {
      ...
      "commit-msg": "validate-commit-msg"
    }
  }
  • 生成 CHANGELOG.md
npm i conventional-changelog -D

修改 package.json

"scripts":{
    ...
    "change-log":"conventional-changelog -p angular -i CHANGELOG.md -s"
}

支持 TS

tsconfig.json

npm install typescript typescript-eslint-parser eslint-plugin-typescript -D
{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "strict": true,
    "allowJs": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "importHelpers": true,
    "downlevelIteration": true,
    "lib": ["es2015", "dom"],
    "jsx": "react",
    "baseUrl": "./src"
  },
  "include": ["./src/**/*"]
}
// 配套的 .eslintrc 和 .prettierrc 需要调整
{
  "plugins": ["typescript", "react", "prettier"],
  "globals": {
    "__DEV__": true,
    "__dirname": false,
    "__fbBatchedBridgeConfig": false,
    "cancelAnimationFrame": false,
    "clearImmediate": true,
    "clearInterval": false,
    "clearTimeout": false,
    "console": false,
    "document": false,
    "escape": false,
    "exports": false,
    "fetch": false,
    "global": false,
    "jest": false,
    "Map": true,
    "module": false,
    "navigator": false,
    "process": false,
    "Promise": true,
    "requestAnimationFrame": true,
    "require": false,
    "Set": true,
    "setImmediate": true,
    "setInterval": false,
    "setTimeout": false,
    "window": false,
    "XMLHttpRequest": false,
    "alert": true,
    "pit": false,
    "ReactElement": true,
  },

  "parser": "typescript-eslint-parser",

  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "modules": true
    }
  },

  "env": {
    "es6": true
  },

  "rules": {
    "no-undef": "error",
    "react/jsx-boolean-value": 0,
    "react/jsx-curly-spacing": 1,
    "react/jsx-indent-props": [1, 2],
    "react/jsx-key": 1,
    "react/jsx-max-props-per-line": 0,
    "react/jsx-no-duplicate-props": 1,
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 1,
    "react/jsx-uses-react": 1,
    "react/jsx-uses-vars": 1,
    "react/no-danger": 1,
    "react/no-deprecated": 1,
    "react/no-did-mount-set-state": 0,
    "react/no-did-update-set-state": 1,
    "react/no-direct-mutation-state": 1,
    "react/no-is-mounted": 1,
    "react/no-multi-comp": [1, {
      "ignoreStateless": true
    }],
    "react/no-set-state": 0,
    "react/no-unknown-property": 1,
    "react/prefer-es6-class": 1,
    "react/react-in-jsx-scope": 1,
    "react/self-closing-comp": 1,
    "react/sort-comp": 1,
    "react/jsx-wrap-multilines": 1,
    "react/prop-types": [
      2,
      {
        "ignore": ["children", "navigation", "history", "match", "location"]
      }
    ],
    "jsx-quotes": 1,
    "prettier/prettier": "error",
    "typescript/class-name-casing": "error"
  }
}
// prettierrc
{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "avoid",
  "rangeStart": 0,
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "parser": "typescript"
}

需要注意的是:
1、在 tslint 中想让代码被 prettier 格式化有个前提,就是 tslint 必须全部编译通过。若一个文件报了 tslint 错误,那么该文件是不会被 prettier 格式化的。这个也是 不如 eslint 可以自动格式化的地方。
2、使用 TS 时,.prettierrc 中的 parser 要设为:'typescript',否则不能使用诸如 enum 之类的关键字(使用了代码不会报错,但 prettier 格式化工具会报错,你这个文件也就无法被 prettier 格式化)


image.png

参考

附录(其他插件)

  • 同步插件 Settings Sync
    能同步扩展、主题、脚本片段、快捷键等。详细使用:
    https://www.cnblogs.com/kenz520/p/7416836.html
  • EditorConfig
    1、在当前项目根目录下添加.editorconfig文件
    2、安装EditorConfig扩展(怎么安装扩展哈?纳尼?打开百度或google,输入vscode 安装扩展 | vscode install extension;好了,不能再提示了)
    3、全局安装或局部安装editorconfig依赖包(npm install -g editorconfig | npm install -D editorconfig)
    4、打开需要格式化的文件并手动格式化代码(shift+alt+f)
    注意:vscode自身有一些格式化设定,二者可以结合
  • 字体
    https://github.com/tonsky/FiraCode
  • turbojs
    包含大部分 js snippest
  • carbon
    代码分享十分美观 https://carbon.now.sh/
  • 让不同项目侧边栏颜色不一样提高辨识度配置
// .vscode/settings.json
{
  "workbench.colorCustomizations": {
    "activityBar.background": "#67C23A"
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容