Fight for Code Style or Bracket Wars
Hello to the Khabrovites! In this article, we will try to consider such a “slippery” issue as code design and code style, and propose one of the solutions that is successful in everyday practice.
For JavaScript, which for a long time remained “overboard” of great development, the golden era has come for the rapid development and appearance of more and more new technologies based on it, and applications are becoming more complex every day. Considering that the adoption of annual standards, the emergence of new syntactic sugar and “buns” make it very attractive for more developers, this topic will be relevant for more than one year. Beginners in JavaScript enthusiastically begin to study it, trying more and more chips, but for the most part they forget about the design of the code and about such a thing as technical debt.
What is the code style at the moment? Everything is bad: the quality of the code suffers for the sake of development speed, and this process goes back to the moment when JS was not considered a full-fledged programming language. However, it is worth considering the complexity of the tasks that are now being solved using JavaScript, and it becomes clear: this approach is fundamentally wrong and should be eradicated.
And this is not to mention that petabytes of JavaScript-related materials are often uploaded to the Internet, often of very dubious quality. Some beginner-centered tutorial materials create uniform hell. It is not surprising that when you hire even developers with experience in working and programming in JavaScript, you don’t have to wait for the formed style and even more so commitment to a certain style of code design. There is no question of understanding “best practices” at all.
I note that with the increase in the number of programmers, the quality of their training, knowledge and “lamp” falls at an appalling speed.
However, when you are dealing with commercial development in JavaScript, developing applications at various stages of readiness, and numerous rotations of developers, in the end you understand that you cannot do without a single code style within one project.
What does he give:
What are the disadvantages:
It's not for nothing that I put it in a name like “Bracket Wars”. This was almost the main problem of the first stage of introducing a single code style. It was the lack of a consensus on some design issues that generated real holivars. I will not cover the topic of holivars, but I will try to provide a solution to this problem.
Most often, two opposite points of view can be found: “It works” and “On line 21 there are 7 spaces at the beginning instead of 4”. Both points of view are equally controversial. They do not have a middle ground, one will result in a terrible govnokod with a huge technical debt and a bunch of furious developers who have to deal with such a legacy, the second can stall the development and rolling out of new releases for a long time. Both of them are not justified and lead to risks and customer dissatisfaction.
It’s just that the effect is delayed for the first one - even if it works now and we may be ahead of schedule, but in the future, when the functionality is expanded or changed, you may encounter a lot of problems like debugging complexity, inability to expand or such defects that cannot be fixed without rewriting everything written earlier.
The second one is almost instantaneous - we did not have time to implement the planned features on time, because the developer of the rules indented 70 files he changed and changed 7 spaces to 2 tabs, engaged in unplanned refactoring, the rules he didn’t like the code outside the task - here you can list a lot options when perfectionism calls into question the very development of the project.
Since none of these situations is unacceptable, it is necessary to look for an alternative way and approach to the design of the code now.
Fortunately, today these problems are perfectly solved by the developer tools - the IDE itself or the plugins for them. Actually, we will automate the process of checking and maintaining the code style and consider further on the example of three editors / IDEs that you most often encounter: Sublime Text, Atom, WebStorm.
A little more theory: what is covered later refers to static analysis and linting (verification) of code, so plugins are linter (parsers) and / or their integration into a particular editor or IDE.
Earlier, I would consider two main, in my opinion, tools - these are JSHint (static code analysis for errors) and JSCS (JavaScript CodeStyle - code design analysis based on design agreements or individual rules), but today these 2 tools are great replaces ESLint (almost always, but more on that below). So I’ll consider its integration. The main difference between ESLint and JSCS and JSHint is modularity and great customization.
It is worth making a clarification on how ESLint replaces these two tools. JS parser, which is used in ESLint (Espree - also plug-in after), judging by the page on npmjs, completely replaces JSHint, however, more customizable than its predecessor, and slower, but for the purpose of daily support for code style this is extremely low. It is worth considering that, most likely, the replacement for the support of code style rules is not yet complete, the developers of this tool themselves say that although they have joined forces with the JSCS team to implement a more universal tool, support is still incomplete. A list of discrepancies can be found here . Preset support is limited. Rather, it will be said that the implementation of this support has now changed its appearance, if JSCS supported a limited set of presets from the box, now these presets have become plug-ins that need to be installed separately and registered in the configuration file. I found a preset forYandex and presets for AirBnB and Google (last 2 - you can choose when initializing the plugin at the time of writing).
It is worth expressing special thanks to the developers for the various configuration file formats, their automatic generation and loading of modules with presets in the process of initializing configs for EsLint.
But let's move on to the practical part, namely, EsLint setup. It is worth noting the presence of two parts of the configuration: general and editor-specific. Let's start with the general.
Eslint Global Installation:
Please note that when using nvm in linux, a situation may arise when eslint is not visible globally, in my case it was enough to create a symbolic link to eslint inside / usr / local / bin / with the command:
where is the vX.XX version of the current Node.js that you last used in
It is needed in order to run at the root of your project:
This command leads to the configuration file generation dialog. A guide is very similar to a similar package.json generation. In fact, you have 2 choices: answer questions about the technologies and code style used or select a preset in the list, as mentioned earlier; You can choose Google, AirBnB and Standard - the recommended preset from the ESLint team. There is a third option with checking the code style of your files, which essentially acts the same as polling, but also makes an attempt to determine the code style.
In fact, a not very useful feature, if you have an imperfect code style at the time of the initialization of the config, it crashes at the first gross violation. Plus you should have globally all plugins.
Next is the choice of the configuration file format - Javascript, JSON, YAML. After choosing one of the formats, a config is generated and the necessary plugins are installed. EsLint recommends using a local installation of EsLint and the necessary plug-ins, installs them in the working directory, and writes them in the devDependencies section of your package.json.
At this stage, you can further customize your configuration file by following the guides on the tool’s website and commit changes. For example, for the project on the react, I generated (answering questions about the code style), and after that I added some rules to this config:
Let's move on to setting up your editor.
Atom
Everything is clear with the plugins for the atom - we install the linter-eslint plugin in the Install settings section, configure it:
We also install the linter package, if it did not stand, this is the linter-eslint dependency. It may be necessary to update Atom, in my case, with every change in the file, a lot of errors fell out and updating the editor solved the problem. The ease of installation of plugins for Atom is one of its advantages. This plugin also corrects the code style when saving, if “Fix errors on save” is checked.
Sublime
Through PackageControl, you need to install in fact three plugins. These are SublimeLinter , SublimeLinter-contrib-eslint and ESLint-formatter. The first, like the linter in Atom, is the basis of code lining in Sublime - this framework has extensive documentation , its configuration is described in great detail. SublimeLinter-contrib-eslint is a bridge for connecting eslint to SublimeLinter and has its own documentation and work-around in case of problems. In the settings of SublimeLinter in the linters section, you need to write the following code:
The rest is a matter of taste. Customize the appearance of the linter to your needs. Description of topics and settings can be found on the documentation website.
ESLint-formatter - allows you to automatically format a file according to your ESLint settings. It also needs to be configured - register paths to Node.js and ESLint, I also recommend at least setting “format_on_save”: true. Perhaps you should take into account the project specificity and create a .sublime-project and write the settings for a specific project there.
WebStorm .
The setting is shown in the screenshot. Just activate ESLint in Settings> Languages & Frameworks> Javascript> Code Quality Tools> ESLint, specify the path to the local installation of ESLint, if it was not detected automatically. It is recommended to automatically detect the presence of a config, but you can also specify the path to it.
The only negative - I did not find any automatic formatting by ESLint in WebStorm - there is import of codestyle from JSCS config and Code> Reformat Code , but there is no import from ESLint config. However, the linting function works:
For WebStorm, you should consider this aspect and not abandon JSCS. This is precisely the aspect that makes ESLint “almost always” replace its predecessors - its support in some IDEs still loses to JSCS and JSHint.
In conclusion, I would like to note that tight binding of the code style to the editor in many cases is not justified and leads to problems in setting up the development environment. It is justified only in exceptional cases, like a single code style on all projects. But this is an extremely rare case. In most cases, the modularity that ESLint provides has undeniable advantages over solidity. Keep this in mind and customize the project for a specific case, and the editor is universal.
What is the profit from all this:
Thanks for attention.
For JavaScript, which for a long time remained “overboard” of great development, the golden era has come for the rapid development and appearance of more and more new technologies based on it, and applications are becoming more complex every day. Considering that the adoption of annual standards, the emergence of new syntactic sugar and “buns” make it very attractive for more developers, this topic will be relevant for more than one year. Beginners in JavaScript enthusiastically begin to study it, trying more and more chips, but for the most part they forget about the design of the code and about such a thing as technical debt.
What is the code style at the moment? Everything is bad: the quality of the code suffers for the sake of development speed, and this process goes back to the moment when JS was not considered a full-fledged programming language. However, it is worth considering the complexity of the tasks that are now being solved using JavaScript, and it becomes clear: this approach is fundamentally wrong and should be eradicated.
And this is not to mention that petabytes of JavaScript-related materials are often uploaded to the Internet, often of very dubious quality. Some beginner-centered tutorial materials create uniform hell. It is not surprising that when you hire even developers with experience in working and programming in JavaScript, you don’t have to wait for the formed style and even more so commitment to a certain style of code design. There is no question of understanding “best practices” at all.
I note that with the increase in the number of programmers, the quality of their training, knowledge and “lamp” falls at an appalling speed.
However, when you are dealing with commercial development in JavaScript, developing applications at various stages of readiness, and numerous rotations of developers, in the end you understand that you cannot do without a single code style within one project.
What does he give:
- Readability. Structured code is always more readable than unstructured, otherwise we would immediately write code that is close to minified, and did not steam.
- Uniformity. An important aspect, for which many for some reason do not think. The human brain is a lazy thing, it forms a kind of inline cache for reading the source code, and as a result, switching between pieces or files of different styles takes time to form new reading patterns. In your opinion, it will be great if the developer, when switching from file to file, hangs, forming a new reading model? Unlikely.
- A single style of code design makes it possible to free up developer resources that he spends on reading and redefining the style of design for their more productive use. For example, in addition to unconditionally accelerating development, he can see “narrow” areas in the code, potential performance losses, defects and other garbage, and accordingly see the opportunities for improvement.
- Quick entry of a new developer. This paragraph, as well as paragraph 3, is rather a consequence of uniformity and readability. The new developer will still have to build an inline cache for reading, but due to uniformity this cache will be built once for one project. And ideally - if all projects follow a single style - then once.
What are the disadvantages:
- Every developer should know the code style.
- It takes a lot of time to support the code style.
- It takes time to resolve conflicts about which quotes are more correct or on which line to put brackets.
It's not for nothing that I put it in a name like “Bracket Wars”. This was almost the main problem of the first stage of introducing a single code style. It was the lack of a consensus on some design issues that generated real holivars. I will not cover the topic of holivars, but I will try to provide a solution to this problem.
Most often, two opposite points of view can be found: “It works” and “On line 21 there are 7 spaces at the beginning instead of 4”. Both points of view are equally controversial. They do not have a middle ground, one will result in a terrible govnokod with a huge technical debt and a bunch of furious developers who have to deal with such a legacy, the second can stall the development and rolling out of new releases for a long time. Both of them are not justified and lead to risks and customer dissatisfaction.
It’s just that the effect is delayed for the first one - even if it works now and we may be ahead of schedule, but in the future, when the functionality is expanded or changed, you may encounter a lot of problems like debugging complexity, inability to expand or such defects that cannot be fixed without rewriting everything written earlier.
The second one is almost instantaneous - we did not have time to implement the planned features on time, because the developer of the rules indented 70 files he changed and changed 7 spaces to 2 tabs, engaged in unplanned refactoring, the rules he didn’t like the code outside the task - here you can list a lot options when perfectionism calls into question the very development of the project.
Since none of these situations is unacceptable, it is necessary to look for an alternative way and approach to the design of the code now.
Fortunately, today these problems are perfectly solved by the developer tools - the IDE itself or the plugins for them. Actually, we will automate the process of checking and maintaining the code style and consider further on the example of three editors / IDEs that you most often encounter: Sublime Text, Atom, WebStorm.
A little more theory: what is covered later refers to static analysis and linting (verification) of code, so plugins are linter (parsers) and / or their integration into a particular editor or IDE.
Earlier, I would consider two main, in my opinion, tools - these are JSHint (static code analysis for errors) and JSCS (JavaScript CodeStyle - code design analysis based on design agreements or individual rules), but today these 2 tools are great replaces ESLint (almost always, but more on that below). So I’ll consider its integration. The main difference between ESLint and JSCS and JSHint is modularity and great customization.
It is worth making a clarification on how ESLint replaces these two tools. JS parser, which is used in ESLint (Espree - also plug-in after), judging by the page on npmjs, completely replaces JSHint, however, more customizable than its predecessor, and slower, but for the purpose of daily support for code style this is extremely low. It is worth considering that, most likely, the replacement for the support of code style rules is not yet complete, the developers of this tool themselves say that although they have joined forces with the JSCS team to implement a more universal tool, support is still incomplete. A list of discrepancies can be found here . Preset support is limited. Rather, it will be said that the implementation of this support has now changed its appearance, if JSCS supported a limited set of presets from the box, now these presets have become plug-ins that need to be installed separately and registered in the configuration file. I found a preset forYandex and presets for AirBnB and Google (last 2 - you can choose when initializing the plugin at the time of writing).
It is worth expressing special thanks to the developers for the various configuration file formats, their automatic generation and loading of modules with presets in the process of initializing configs for EsLint.
But let's move on to the practical part, namely, EsLint setup. It is worth noting the presence of two parts of the configuration: general and editor-specific. Let's start with the general.
Eslint Global Installation:
npm i -g eslint
Please note that when using nvm in linux, a situation may arise when eslint is not visible globally, in my case it was enough to create a symbolic link to eslint inside / usr / local / bin / with the command:
ln -s /usr/local/nvm/vX.X.X/bin/eslint /usr/local/bin/eslint
where is the vX.XX version of the current Node.js that you last used in
nvm use X.X.X
It is needed in order to run at the root of your project:
eslint --init
This command leads to the configuration file generation dialog. A guide is very similar to a similar package.json generation. In fact, you have 2 choices: answer questions about the technologies and code style used or select a preset in the list, as mentioned earlier; You can choose Google, AirBnB and Standard - the recommended preset from the ESLint team. There is a third option with checking the code style of your files, which essentially acts the same as polling, but also makes an attempt to determine the code style.
In fact, a not very useful feature, if you have an imperfect code style at the time of the initialization of the config, it crashes at the first gross violation. Plus you should have globally all plugins.
Next is the choice of the configuration file format - Javascript, JSON, YAML. After choosing one of the formats, a config is generated and the necessary plugins are installed. EsLint recommends using a local installation of EsLint and the necessary plug-ins, installs them in the working directory, and writes them in the devDependencies section of your package.json.
At this stage, you can further customize your configuration file by following the guides on the tool’s website and commit changes. For example, for the project on the react, I generated (answering questions about the code style), and after that I added some rules to this config:
{
"env": {
"browser": true,
"es6": true,
"commonjs": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"installedESLint": true,
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"indent": [
"warn",
"tab"
],
"linebreak-style": [
"warn",
"unix"
],
"quotes": [
"warn",
"double"
],
"semi": [
"warn",
"always"
],
"react/prop-types": "off",
"no-console": "off",
"no-unused-vars": "off"
}
}
Let's move on to setting up your editor.
Atom
Everything is clear with the plugins for the atom - we install the linter-eslint plugin in the Install settings section, configure it:
We also install the linter package, if it did not stand, this is the linter-eslint dependency. It may be necessary to update Atom, in my case, with every change in the file, a lot of errors fell out and updating the editor solved the problem. The ease of installation of plugins for Atom is one of its advantages. This plugin also corrects the code style when saving, if “Fix errors on save” is checked.
Sublime
Through PackageControl, you need to install in fact three plugins. These are SublimeLinter , SublimeLinter-contrib-eslint and ESLint-formatter. The first, like the linter in Atom, is the basis of code lining in Sublime - this framework has extensive documentation , its configuration is described in great detail. SublimeLinter-contrib-eslint is a bridge for connecting eslint to SublimeLinter and has its own documentation and work-around in case of problems. In the settings of SublimeLinter in the linters section, you need to write the following code:
"linters": {
"eslint": {
"@disable": false,
"args": [],
"excludes": []
}
}
The rest is a matter of taste. Customize the appearance of the linter to your needs. Description of topics and settings can be found on the documentation website.
ESLint-formatter - allows you to automatically format a file according to your ESLint settings. It also needs to be configured - register paths to Node.js and ESLint, I also recommend at least setting “format_on_save”: true. Perhaps you should take into account the project specificity and create a .sublime-project and write the settings for a specific project there.
WebStorm .
The setting is shown in the screenshot. Just activate ESLint in Settings> Languages & Frameworks> Javascript> Code Quality Tools> ESLint, specify the path to the local installation of ESLint, if it was not detected automatically. It is recommended to automatically detect the presence of a config, but you can also specify the path to it.
The only negative - I did not find any automatic formatting by ESLint in WebStorm - there is import of codestyle from JSCS config and Code> Reformat Code , but there is no import from ESLint config. However, the linting function works:
For WebStorm, you should consider this aspect and not abandon JSCS. This is precisely the aspect that makes ESLint “almost always” replace its predecessors - its support in some IDEs still loses to JSCS and JSHint.
In conclusion, I would like to note that tight binding of the code style to the editor in many cases is not justified and leads to problems in setting up the development environment. It is justified only in exceptional cases, like a single code style on all projects. But this is an extremely rare case. In most cases, the modularity that ESLint provides has undeniable advantages over solidity. Keep this in mind and customize the project for a specific case, and the editor is universal.
What is the profit from all this:
- No Bracket Wars. The toolkit takes care of the code style, not you. This gives room for a kostruktiva instead of holivars;
- You do not need to know the code style anymore - in any case, force its study and enforce it. Over time, the developer will remember specific rules, and if he misses something, “fix on save” will save everyone;
- Code style support is automatic, does not require developer time;
- The project is uniform in style, and this gives all the goodies that were described at the beginning of the article in the “pluses”.
Thanks for attention.