[Testing] Static Analysis Testing JavaScript Applications
The static code analysis and linting tool ESLint is the de-facto standard for linting JavaScript projects. In this lesson we’ll see how to install, run, and configure it for your preferences.
Install:
npm i -D eslint
Run:
npx eslint src
Create: .eslintrc file
{ "parserOptions": { "ecmaVersion": "2018" }, "extends": [ "eslint:recommended" ], "rules": { "no-console": "off" }, "env": { "browser": true, "node": true, "es6": true, "jest": true } }
The code formatting tool prettier can help you avoid a lot of useless time spent formatting code and arguing about code formatting with your co-workers. It can also help you catch subtle issues with your code that you may not notice otherwise. In this lesson we’ll learn how to install and run prettier.
Install:
npm i -D prettier
Run:
"format": "prettier --write \"**/*.+(js|jsx|json|yml|yaml|css|less|scss|ts|tsx|md|graphql|mdx)\""
npm run format
In VSCode: Settings.json
{ "editor.formatOnSave": true }
Prettier is a pretty opinionated tool, but it does allow for some customization. In this lesson we’ll check out the prettier playground and see what options we want to enable in our project’s .prettierrc
file.
After adding in our custom configuration, we’ll create a .prettierignore
file so that you can avoid formatting any files generated within the project such as node_modules
or a build
folder.
.prettierrc:
{ "arrowParens": "avoid", "bracketSpacing": false, "insertPragma": false, "jsxBracketSameLine": true, "parser": "babylon", "printWidth": 80, "proseWrap": "always", "requirePragma": false, "semi": true, "singleQuote": false, "tabWidth": 2, "trailingComma": "all", "useTabs": false }
.prettierignore:
node_modules
coverage
dist
build
.build
.vscode
package.json
package-lock.json
debug.log
Because prettier can automatically fix a lot of stylistic issues in our codebase, it’s not necessary to have eslint check for those and it can actually be kind of annoying if it does. So let’s see how we can use eslint-config-prettier
to disable all rules that are made irrelevant thanks to prettier.
Install:
npm i -D eslint-config-prettier
.eslintrc:
{ "parserOptions": { "ecmaVersion": "2018" }, "extends": [ "eslint:recommended", "eslint-config-prettier" ], "rules": { "no-console": "off" }, "env": { "browser": true, "node": true, "es6": true, "jest": true } }
You can’t force everyone on your project to use the prettier integration for their editor, so let’s add a validation script to verify that prettier has been run on all project files.
Fortunately for us, Prettier accepts a --list-different
flag that you can use that will throw an error when code is not up to the standard of your project.
"scripts": { "test": "node --require ./setup-global.js src/index.js", "lint": "eslint src", "format": "npm run prettier -- --write", "prettier": "prettier \"**/*.+(js|jsx|json|yml|yaml|css|less|scss|ts|tsx|md|graphql|mdx)\"", "validate": "npm run lint && npm run prettier -- --list-different" },
We can run:
npm run validate
to check whether there is any files which is not formatted.
If it is, then will throw error, we can run:
npm run format
to format the code.
ESLint can check for a lot of things, but it’s not a great tool for checking the types of variables that flow through your application. For this you’ll need a type-checking tool like Flow or TypeScript. Let’s see how we can configure our project to work with Flow.
Install:
npm i -D flow-bin
Add script:
"flow": "flow",
Run:
npm run flow
For the first time, we run 'npm run flow' will tell us to run:
npm run flow init
it create a .flowconfig file.
Create a exmaple js file to pratice flow:
//@flow function add(a: number, b: number): number { return a + b } type User = { name: { first: string, middle: string, last: string, }, } function getFullName(user: User): string { const { name: {first, middle, last}, } = user return [first, middle, last].filter(Boolean).join('') } add(1,2) getFullName({name: {first: 'Joe', middle: 'Bud', last: 'Matthews'}})
Run:
npm run flow
We won't see any error for this, if everything is correct type checking.
We have a 'validate' script setup previously:
"validate": "npm run lint && npm run prettier -- --list-different"
we can also add "flow" into it:
"validate": "npm run lint && npm run prettier -- --list-different && npm run flow"
In order to make 'validate' script works, we still need to install 'babel-eslint' for eslint to understand flow syntax:
Install:
npm i -D babel-eslint
.eslintrc:
{ "parser": "babel-eslint", "parserOptions": { "ecmaVersion": "2018" }, "extends": [ "eslint:recommended", "eslint-config-prettier" ], "rules": { "no-console": "off" }, "env": { "browser": true, "node": true, "es6": true, "jest": true } }
Then run:
npm run validate
it will checks eslint, prettier and flow.
We have a few checks we’ll run in continuous integration when someone opens a pull request, but it’d be even better if we could run some of those checks before they even commit their code so they can fix it right away rather than waiting for CI to run. Let’s use husky’s precommit script to run our validation.
Install:
npm i -D husky
Hook with 'precommit' with valdiation:
"precommit": "npm run validate"
If you don't want this precommit hook and commit you changes anyway you can do:
git commit -m "bad stuff" --no-verify
Rather than failing when a developer has failed to format their files or run linting on all the files in the project on every commit, it would be even better to just automatically format the files on commit and only check the relevant files with eslint. Let’s use lint-staged to run scripts on the files that are going to be committed as part of our precommit hook.
Install:
npm i -D lint-staged
package.json:
"precommit": "lint-staged && npm run flow"
.lintstagedrc:
{ "linters": { "*.js": [ "eslint" ], "**/*.+(js|jsx|json|yml|yaml|css|less|scss|ts|tsx|md|graphql|mdx)": [ "prettier --write", "git add" ] } }
Now when you do commit, it will automatcilly format all the code and readded to git and commit it.
相关文章
- JavaScript中给onclick绑定事件后return false遇到的问题
- JavaScript正则表达式详解(一)正则表达式入门
- JavaScript之变量
- Android中WebView如何加载JavaScript脚本
- JavaScript原生折叠扩展收缩菜单带缓冲动画
- [Javascript] Natively Format JavaScript Dates and Times
- [Javascript] Conditionally spread entries to a JavaScript object
- [Javascript] Use JavaScript's for-in Loop on Objects with Prototypes
- [Javascript] Understanding the .constructor property on JavaScript Objects
- [Javascript] IntersectionObserver -- Lazy Load Images on a Website
- [Javascript] Delegate JavaScript (ES6) generator iteration control
- JavaScript获取图片的原始尺寸
- [Javascript] Filter out Duplicates from Flat JavaScript Array with array.filter / reduce / Set
- [Javascript] Link to Other Objects through the JavaScript Prototype Chain (Object.setPrototypeOf())
- [Javascript] Wait for Multiple JavaScript Promises to Settle with Promise.allSettled()
- [Javascript] Await a JavaScript Promise in an async Function with the await Operator
- [Javascript] Replicate JavaScript Constructor Inheritance with Simple Objects (OLOO)
- [Javascript] Link to Other Objects through the JavaScript Prototype Chain
- [Javascript] JavaScript赋值时的传值与传址
- [Javascript] Specify this using .call() or .apply()
- [Javascript] Compose multiple functions for new behavior in JavaScript
- [Javascript] Decorators in JavaScript
- 了解Javascript 变量
- Atitit.js模块化 atiImport 的新特性javascript import
- 如何使用Javascript复制到剪贴板
- 【华为OD机试 2023】 查找单入口空闲区域(C++ Java JavaScript Python)
- Javascript:jQuery的ajax请求get请求模板
- 2014在辛星Javascript口译科
- javascript技巧合集
- 【阅读笔记】JavaScript设计模式与开发实践1--面向对象与this