JavaScript, compared to other languages, has a more flexible syntax. Such characteristic sometimes causes unintended problems. For example, the flexible syntax creates accidental errors that are not, from syntactical perspective, bugs, and also leads to codes of which purpose is not transparent. Because JavaScript does not have a compile stage, such errors are undetectable before actually running the program. While adhering to the Coding Convention to increase readability and prevents anti-patterns is a temporary solution, it is still difficult for developers to ensure that they are following the Coding Convention by themselves. In order to compensate for the JavaScript’s shortcoming, Static Analysis is used to automatically validate the Coding Convention and sniff out possible errors.
Built by Nicholas C. Zakas, ESLint is currently the most widely used static analysis tool. The tool’s credibility has been verified by the fact that giants like Facebook, PayPal, and Airbnb feel comfortable enough to use it in their development environments. ESLint uses the Espree parser to built Abstract Syntax Tree (AST) to directly evaluate the code, and it not only supports diverse rules, but also supports various environments and formatters. Because it also provides features to add custom rules or formatters, it can be customized flexibly in accordance with the project’s characteristics. To learn more about rules and demos, follow the respective links.
ESlint can be installed using npm.
npm install --save-dev eslint
It is possible to create a config file for each project, and use it to enforce different rules to carry out static analysis. Also, editors that support ESLint give feedback according to the custom ESLint rule in the project folder, which allows faster debugging and prompt error validation. ESLint can even be integrated into bundlers like Webpack and can be configured to suit the development mode or production mode. Especially in production mode, if more errors are raised than the alert threshold, it can even stop the build process.
Options in ESLint can be categorized into six modes: Possible Errors, Best Practices, Strict Mode, Variables, Stylistic Issues, and ES6, and detailed explanation on each option can be found in the official documentation. Options can be applied on the .eslintrc.js
config file, and will be explained briefly in the Applying it to Projects
section. More in depth explanation can be found in the official documentation.
In order to use ESLint, a config file containing the basic rules (.eslintrc.js
) is required. Use the --init
option provided by the CLI to create the config file as shown below.
npx eslint --init
Now, ESLint can be executed using the CLI.
npx eslint app.js
When the CLI command finishes executing, ESLint statically analyzes the app.js file, and detects and prints the lines that contain errors or do not conform to the Coding Convention as in the following image.
--fix
is one of the commonly used options in the CLI. --fix
automatically corrects the pieces of code marked as error and saves the code. In order to only display the corrections without saving them, use --fix-dry-run
.
More options and their detailed explanations can be found on the official website.
1. Creating .eslintrc.js
file
Note The previously explained method of using the
--init
option from the CLI also works.
Below is an example of a config file with some basic rules.
module.exports = {
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
es6: true,
jasmine: true
},
extends: ['tui'],
// add your custom rules here
rules: {
'indent': [2, 2, {SwitchCase: 1, ignoreComments: false, ImportDeclaration: 1}],
'semi': 2
}
};
parserOptions
ESLint can be configured to support different JavaScript language options. The parseOptions can take values like ecmaVersion, sourceType, ecmaFeatures, and etc., and more examples can be found on the user guide.env
The env option allows developers to define the environment on which the code is being executed. The example above has browser
, es6
, and jasmine
as values.extends
The extends option allows developers to use predefined custom rule sets. In the example above, the file is configured to use the eslint-config-tui
, set of rules used in FE Development Lab. (This property will be explained in greater detail in the 2. Using Predefined ESLint Rules)rules
Using the rules
, rules in the collection defined in the extends
property can be added and redefined. In the example file, a rule making the semicolon mandatory semi
has been defined and enforced. Also, the indent
is set to only accept 2 spaces for indentation, and more detailed options like switchCase (applicable in switch statements), ignoreComments (applicable for comments), and ImportDeclaration (applicable in import declarations) have been set to true.
2. Using Predefined ESLint Rules
ESLint contains incredibly large collection of rules, so it could be difficult to go through each one to pick out the rules suitable for each project. Luckily, tech-giants like Google, Microsoft, and Airbnb have released their corresponding Coding Conventions and respective ESLint rules, and such collections can be adopted reliably.
The Coding Convention produced by the FE Development Lab has been reviewed one rule at a time, and can prove to be a useful guide. It contains a set of well-written predefined rules, so it is recommended that readers take advantage of it. The FE Development Lab’s Coding Convention and eslint-config-tui
file can be found in the link below.
To use the eslint-config
files, simply download the desired config file using npm, and include it in the .eslintrc.js
file’s extends
property. When writing the value for the extends
attribute, the eslint-config-
prefix can be omitted.
// Install the config file
npm install --save-dev eslint-config-tui
// Edit the .eslintrc.js
module.exports = {
extends: ['eslint-config-tui']
}
;
It is important to keep in mind that the predefined should be used cooperatively with default rules, not independently. The default rules have been explained in greater detail in earlier sections. In order to use ECMAScript’s module system in the project, it is necessary to set parserOptions.sourceType
to module
as shown below.
// Edit the .eslintrc.js
module.exports = {
parserOptions: {
"sourceType": "module"
},
extends: ['eslint-config-tui']
};
To use global variables from the browser and ES6, configure the env
attribute as shown below.
// Edit the .eslintrc.js.
module.exports = {
parserOptions: {
"sourceType": "module"
},
env: {
browser: true,
es6: true
},
extends: ['eslint-config-tui']
};
3. Tips for Using Multiple Recommended Configurations
It is actually common to inherit multiple recommended configurations for projects. The below is an example of using the TOAST UI Rules and Vue framework’s recommended configurations together at FE Development Lab.
module.exports = {
..
extends: ['tui', 'plugin:vue/recommended'],
..
};
As such, when using multiple configurations, the set declared last holds highest priority.
4. Editing the npm Script
package.json
{
"scripts": {
"lint": "eslint src"
}
}
5. Running the CLI Command
npm run lint
npm run lint -- --fix // (Fix automatically)
Prettier, unlike other static analysis tools that analyze every code for syntax, focuses strictly on the code’s style. The biggest advantage Prettier offers is that it automatically formats the code, eliminating the need for each developer to pay attention to making the codes look “pretty.” It allows developers to forget about styling the code, and only focus on the program’s logic. However, since Prettier does only focus on formatting, it is recommended to use tools like ESLint to guarantee the quality of the code. Prettier supports many different languages (JavaScript, JSX, Flow, TypeScript, CSS, Less, SCSS, JSON, GraphQL) and can be integrated on to most of the editors.
In the image below, the left side is unformatted code, and the codes on the right have been formatted using Prettier.
To test Prettier, click here.
npm install --save-dev --save-exact prettier
# or globally
npm install --global prettier
yarn add prettier --dev --exact
# or globally
yarn global add prettier
Many modern editors like Atom, Emacs, Vim, Visual Studio, Sublime, and JetBrains WebStorm supports integrated application of Prettier. Using the integrated plugin, when the source code is being saved, it automatically goes through the Prettier and is saved in formatted version. Refer to the official documentation for more thorough instructions about using Prettier on editors. The following is an example of Prettier formatting the code before it is saved in JetBrains WebStorm editor.
Prettier is a tool to eliminate any debate over the coding convention, so it does not have complicated options about style. However, Prettier does provide options regarding specific cases like tabs vs. spaces or single quotes vs. double quotes. If ESLint is already installed, Prettier can be adopted just by installing the eslint-plugin-prettier
. This section will discuss how to add config files to Prettier and how it can be used with ESLint.
1. Adding the Config File
First create a .prettierrc
file in the project folder, and edit the file according to the official documentation. An explanation on options have been included in the end of the document. The starter template for .prettierrc
file should look like the following code.
Prettier, compared to ESLint, does not have many options. This is because it is built to settle any disagreements on style, and the original creators of Prettier thought that enabling never ending list of options would defeat the purpose.
{
"trailingComma": "none",
"printWidth": 120,
"singleQuote": true,
"bracketSpacing": false,
"tabWidth": 2,
"jsxBracketSameLine": false
}
2. Using Prettier as a Plugin in ESLint
Because Prettier and ESLint can have different opinions on the same piece of code, it is recommended to use them together. The two can be integrated simply by installing eslint-plugin-prettier
and adding to the eslintrc.js
file’s list of plugins.
1) Include Prettier in ESLint’s list of rules, by using eslint-plugin-prettier
.
npm install --save-dev eslint-plugin-prettier
2) Add Prettier plugin to eslintrc.js
.
module.exports = {
...
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
};
3. Turn off the ESLint’s formatting rule.
It can be confusing for the program if ESLint and Prettier send redundant reports to it, so it is recommended to just turn off the ESLint’s formatting options. If the Prettier is integrated using eslint-config-prettier
, it automatically deactivates any redundant rules.
The following example demonstrates how ESLint and Prettier can produce redundant reports regarding the empty space after the function name. As shown below, both ESLint’s space-before-function-paran
error and Prettier’s DELETE ‘.’
errors are printed together.
By following the steps below, the redundant reporting issue can be resolved.
1) Install eslint-config-prettier
.
npm install --save-dev eslint-config-prettier
2) Add Prettier setting to .eslintrc.js
.
module.exports = {
...
"extends": ["prettier"]
};
ESLint provides plugins so that users can customize and add features of their own. Prettier also provides eslint-plugin-prettier
plugin just for ESLint, and allows users to run Prettier rules with ESLint. eslint-config-prettier
enables the existing rules in ESLint to cancel out redundant rules so that the program can be ran more efficiently.
4. Using the Recommended Rules to Eliminate the Unnecessary config
By using the recommended rules like the following, users do not have to specify the prettier
in .eslintrc.js
’s plugin property. However, even in this case, it is required to install both eslint-plugin-prettier
and eslint-config-prettier
. plugin-prettier/recommended
automatically adds the prettier
value to plugin property, and deactivates the redundant rules.
module.exports = {
..
"extends": ["plugin:prettier/recommended"]
..
};
printWidth
- Specifies the line length of the printer wraptabWidth
- Specifies the number of empty spacesuseTabs
- Uses tabs instead of spaces to indentsemi
- Enforces semicolons at end of statementssingleQuote
- Uses single quotes instead of double quotestrailingComma
- Prints trailing commas for multiline codesbracketSpacing
- Enforces spacing between the object literal parenthesisjsxBracketSameLine
- Ensures that the closing bracket is not left alone its own line when using jsx.arrowParens
- Enforces parenthesis for arrow function parametersparser
- Specifies the parserfilepath
- Specifies the filepath for the parserrequirePragma
- Enables/disables pragma headersinsertPragma
- Enables/disables automatic pragma header insertionsproseWrap
- Specifies wrap typeEach option is explained in greater detail on the official documentation.
Although Prettier is often used integrated with editors, it can also be used in CLI environment. Shown below is an example of using the CLI to run Prettier. (The example is using the --no-config
to check the javascriptCode.js with default settings.)
prettier --no-config javascriptCode.js
To add other options, refer to the official documentation and find the desired input to use with the CLI. The example below is using --single-quote
and --no-semi
to make sure that string is declared with single quotes and semicolons will be placed at the end of each statement. Finally, it uses the --write
option to save the changes made.
prettier --single-quote --no-semi --write javascriptCode.js"
To learn more about using the CLI to access Prettier’s functionalities, refer to the official documentation.
This document has explored the Static Analysis. Static analysis enables developers to analyze the code before execution to maintain the consistency inside of the code and to prevent bugs. This guide is focused on the importance of static analysis and the tools related to it, especially ESLint and Prettier. The author hopes that this document helps the readers adopt the static analysis methods efficiently.
This document is an official Web Front-End development guide written and maintained by NHN Cloud FE Development Lab. Any errors, questions, and points of improvement pertaining to this document should be addressed to the official support channel (dl_javascript@nhn.com).
Last Modified |
---|
2019. 04. 15 |