Background
When I joined the project I’m currently working on, it was a sprawling React Redux codebase, the navigation of which was surely difficult for newcomers to large codebases. The architecture for this front-end app was designed by an experienced developer, and occurred before I joined the team.
Redux Thunk handled most of our API requests; because the returned JSON was often deeply nested—and to avoid duplication of data—Normalizr was applied to all returned responses, in order to place data in the store in a standardized manner.
Redux Form was used to handle quick bootstrapping of multiple forms throughout the app. Initially, Bootstrap was used for styling.
Overtime, of course, tech debt was introduced into the app, as well as bugs. One of my professors in college once forwarded me an article by Kevin Simler about how new Computer Science grads would find software engineering to be a whole ‘nother ballgame. The article seems to be true.
The introduction of bugs into a large codebase seems inevitable, not necessarily because they go undetected, but because the app is “schizophrenic,” not able to determine exactly what it does. In other words, once an app stops “growing,” bugs should, in theory, disappear.
Initially our dedicated QA team member introduced automated regression testing, which had previously been absent from our codebase. Our app has a built-in workflow that was the product of a research project some four years ago. This testing was written with WebdriverIO, and basically tested the entire workflow with different permissions from start to finish.
One of the problems with this testing strategy is that, in hindsight, it seemed to produce false negatives, mostly because of uncertain load times (“race conditions”). Since the workflow was tested in a serial fashion, any failure at any step would cause the entire suite to fail; this made debugging the tests also difficult.
One of the front-end team members who joined us in July 2018 noticed we weren’t using Reselect at the time, and essentially introduced it to the codebase. He argued that many of the mapStateToProps
calculations we were using were expensive, and that if we cached them, a significant speed increase should be observed.
That same developer also eventually introduced TypeScript and Cypress to our codebase. With the latter the front-end team was more able to easily produce tests for various features in a targeted manner. By using a bunch of fixtures, essentially ripped directly from visiting the app itself, the test suite could enter specific pages, test something, and exit. This helped with the “stacked test problem” a lot.
Before leaving, that developer also encouraged us to use Formik, over Redux Form, which at the moment we are almost finished migrating from.
I was eventually given a ticket regarding standardizing our entire codebase to follow an internal style guide. So I did this in the only way I knew how: install ESLint. Due to partial TypeScript migration, I also installed TSLint.
One of my professors in college had our entire class once install ESLint and extend the Airbnb style guide. Initially we laughed when he picked Airbnb over Google’s or Facebook’s style guide, but then we realized he was being serious. He also had us configure the installation using YAML.
After configuring the .eslintrc.yml
file to alphabetically sort members of our React classes, I went about “stylizing” the codebase.
My first exposure to an IDE was in 2011, when I downloaded Microsoft Visual C++ as part of a summer class I was taking. I credit this class largely with getting me “over the hump” of learning how to program and think like a programmer.
Prior to that, I had some exposure to scripting languages like Python and Perl, via Swaroop C. H., Magnus Lie Hetland, and Clinton Pierce.
Now at the time, Facebook had an “Engineering Puzzles” page. Prior to attending college I successfully solved only the first puzzle, Hoppity Hop, which I later learned was just a variation of FizzBuzz. During my first year of college I did most of my homework in Notepad and Notepad++. Our curriculum was in JavaScript and Java.
Later on after installing different Linux distros on a small netbook I had purchased, I started using Vim. Throughout a lot of my college career, a not-insignificant portion of my work was done in Vim. Occasionally I used Sublime Text for a better feel. For example, much of my Senior Project, and Compilers homework was done in Vim. For Compilers we did not actually write a compiler, but rather defined a language and a grammar via Ohm, and then successfully transpiled that language to JavaScript.
Upon entering Hack Reactor I at first used Sublime Text, but then later switched to VS Code due to it’s popularity. Upon joining the team I’m currently on, I used Sublime Text, but also occasionally switched between Sublime Text and VS Code.
One of the front-end team members used MacVim, which I thought was interesting, since our codebase was quite large, and often times there were a lot of find-and-replace tickets in our backlog. I speculate that he probably used grep
to work on those tickets.
IDEs
I initially preferred Sublime Text over other editors or IDEs for its no-frills nature. The interface was uncluttered and it had a good theme for my eyes, which were less-and-less sensitive to light contrast (this was due to an incident in college where I used an iPad nightlight for several months; please don’t do this).
I later switched to VS Code for some of the search-and-replace tickets, and due to the presence of regex in VS Code, I had a lot of fun combing patterns and mass-replacing strings of text.
The problem with VS Code is that it seems to lack space in the interface itself. The chief engineer and lead front-end on our team both use WebStorm at the moment. Aside from them, I had heard and intuited for a while that WebStorm was somehow actually better than VS Code. The developer who initially introduced Reselect and a variety of other technologies to our codebase was actually very pro–VS Code himself.
Funnily enough the QA engineer used Atom. At one point, our team consisted of five members using five different editors: Atom, VS Code, Sublime Text, MacVim, and WebStorm.
I’ve decided to try out WebStorm, thus far, its benefits seem to reside in a seemingly more spacious layout. The shortcuts are all different however. Our codebase has already integrated ESLint (extending Airbnb, but customized by us), Prettier (integrated with the former so that the two don’t contradict each other), and TSLint (obviously from Palantir, but customized by us), all together. WebStorm seems to intuitively pick up on these configurations and apply them. In addition, it appears to have its own “Local History” aside from our Git, although I haven’t had recourse to use that feature yet.
Another WebStorm boast is that it is generally unnecessary to install plugins to gain functionality. Lastly, even in the absence of ESLint and TSLint, it has its own built-in refactoring and static code analysis features. WebStorm also has a nifty “search whole codebase” feature, which VS Code also has, but somehow I think the former is more powerful. Small annotations appear throughout the code, annotating arguments you pass to third-party tools. For example, in the React Redux bindings, the first argument passed to connect
is actually mapStateToProps
, but in practice it just looks like an anonymous function (although, this depends on how you write your code). WebStorm will remind you of this. Similarly, with React Hooks, the argument passed to useState
is basically the initial state, and so WebStorm annotates this for you. The IDE also informs you of unused Promises.
This particular JetBrains product, therefore, seems superior overall. But there does seem to be a steep learning curve.
Update
After re-enabling a large chunk of TSLint and ESLint rules our team had disabled, I then browsed through and tried some of the features listed in their Getting Started guide.
TSLint and ESLint integration is excellent, although one will have to finnagle with .eslintignore
in order to ensure that the IDE doesn’t apply ESLint critiques to TypeScript files. If your ESLint style guide proffers quick fixes for certain issues, a quick keyboard command can apply them (for example, favoring dot notation over bracket notation when accessing “known,” i.e. not at-runtime-determined, properties of objects). If there is no quick fix, a list of possible options is presented to the user.
WebStorm “groks” your entire codebase. While VS Code has regex and partial string matching for looking for text, WebStorm knows the exact location of where all classes, methods, interfaces, or whatever, are declared, not just throughout the codebase, but also within the current file you are viewing. For example, the internal properties of classes are all “grokked” by WebStorm, such that you can find where you declared such-and-such a property or field.
WebStorm also has built-in refactoring features. If I want to rename a function or method, I can do so, and WebStorm will rename all instances where that method is used. VS Code supports a more primitive string-based search-and-replace, but WebStorm is like an abstraction over your codebase, having transformed the entire thing into some sort of logical tree it knows the details of.
WebStorm also has a quick way of searching for meaningful declarations of content throughout the codebase, as well as the more freestyle string-searches of VS Code. The former is triggered with ⇧⇧. The latter is triggered with ⌘⇧F.
WebStorm also has good Prettier integration, allowing me to Prettier files or blocks of code within the editor itself. In VS Code I always hacked this by staging certain files, and then “committing” them to trigger the pre-commit hook. There is also a diff-comparison tool in WebStorm, whereas before I used Diffchecker.com. Before I also used Flap.TV’s online Alphabetizer, but now those two might not be necessary.
Finally, WebStorm also has Webpack/npm integration. I can run my package.json
scripts within the editor itself, thereby building my app. Of course, in VS Code you can open the terminal and do whatever you want, but it’s nice to have this integration.
Lastly, there are some small things WebStorm does that VS Code doesn’t. For example, it seems like WebStorm “knows” that I alphabetize all imports from one source, so whenever WebStorm auto-adds an import, it puts it in the correct location in the list, in alphabetized form. If I copy-and-paste a large block of code, WebStorm auto-formats it with correct indentation, whereas in VS Code I have to paste, and then clean up. If I hit enter, the cursor moves to the correct indentation on the next line, but in VS Code it defaults to all the way to the left.
If I paste a method, it intelligently calls the method. If I hit enter on an if-block, it opens it for me to write something inside. VS Code and Sublime Text have some of these intelligent features as well, but with the latter one has to customize them, and since my abilities of customization are limited, those rules do not work in all cases.
For example, Sublime Text can be customized such that whenever you create an opening parenthesis, a closing one is placed as well. Sublime Text already does this for braces and brackets, but it must be added for parentheses I believe. But there are some cases where I don’t want a closing parenthesis, and Sublime Text cannot detect this intention. VS Code does the same thing for brackets and braces occasionally.
Thus far, it doesn’t seem like WebStorm has this issue.
According to my brother, as well, WebStorm will automatically notify you if your package.json
file presents an updated version of a software or some tool. It can then install that upgrade into your node_modules
folder on the spot. This is useful since node_modules
is often ignored as part of a project’s Git configuration.
Cheers, and happy coding.