DEV Community

loading...
Cover image for 5 things to include in your project ASAP

5 things to include in your project ASAP

lbragile profile image Lior Bragilevsky ใƒป8 min read

After the launch of v2.0 of my current project (TabMerger), I decided to learn/integrate a few items that really pushed my skills to the next level. Best of all, adding these to my projects made me very excited to work on new projects and/or refactor existing ones.

Here is TabMerger's repository which you can view to get ideas about how to add any of the features discussed below.

GitHub logo lbragile / TabMerger

TabMerger, as the name suggests, merges your tabs into one location to save memory usage and increase your productivity. TabMerger is a cross-browser extension - currently available on Chrome, Firefox, and Edge.

tabmerger logo

Coverage Mutation Score Code Quality Build Issues Pull Request Forks Stars Contributors Release Date Last Commit Commits Since Latest Release Chrome Users Chrome Rating Firefox Users Firefox Rating Firefox Downloads YouTube Views YouTube Votes contributions Welcome Docs Available Active Development Code Size Donation Receive Donation Goal OC Backers OC Sponsors License

Chrome Firefox Edge

TabMerger - Stores tabs to save memory and increase productivity. | Product Hunt

Merges your tabs into one location to save memory usage and increase your productivity.

TabMerger v2.0.0 What's New?

Table of Contents ๐Ÿ“ƒ

  1. Description
  2. Contributing
  3. Download
  4. Leave A Review
  5. Documentation
  6. Todo
  7. Build
  8. Test
  9. Contact
  10. Donate
  11. License

Description ๐Ÿ–‹

Tired of searching through squished tab icons to find that one tab you are sure is there? With TabMerger you can simplify this clutter while greatly increasing productivity in a highly organized and customizable fashion!

With a single click, you can have all your tabs in a single place, where you can then re-arrange them into appropriate groups, delete extra/unwanted tabs, customize group colors, and so much more. All tabs that are merged into TabMerger are stored internally for you to use at a later time, even when you close the browser window. Lots of analytics are provided to keep you informed about the state of yourโ€ฆ

Here are the concepts I urge you to learn as they will hopefully bring the same excitement into your coding life - don't fall into the trap of pushing them off/procrastinating.

Table of Contents ๐Ÿ“‘

  1. Testing
  2. Linting - Static Testing
  3. TypeScript
  4. Module Aliasing
  5. Documentation
  6. Conclusion

1. Testing ๐Ÿงช

I highly recommend Jest as it is available right out of the box when you use React (CRA), but you could also use other test runners like Mocha, Karma, etc.

Why?

Do you want to manually test every little feature of your code every time you change/update/add something?

Yeah, no thanks, I would rather have a testing script that automates this for me. Plus it is super rewarding once you understand the main concepts. This is probably the most time consuming of all the items listed here.

  • Start with the basics - Unit Testing

  • Look into Mutation Testing - this is insanely amazing once you understand how to use it! Stryker is the way to go here.

  • Once you understand your coverage reports from Jest & Stryker, add Integration Tests and E2E Tests with Jest Puppeteer which is another easy to integrate module with React.
    Disclaimer: I haven't done this step yet for TabMerger but experimented with this in the past and it is very fun - feel free to contribute ๐Ÿ˜Š. This should be simpler than unit testing as it is "Black Box" since you do not care about the internal (just input and output) rather than a unit tests' "White Box" approach.

TabMerger Testing

Here is a brief snapshot of TabMerger's current testing performance:
TabMerger v2.0.0 testing performance

As you can see, with these test scripts, I can check the logic of all the files in my application with the help of around 250 tests in less than 20 seconds. This gives me a great deal of confidence that new features do not break existing code. There is still some room for improvement (uncovered lines and not exactly 100%), but the current state lets me easily add new features without endlessly pursuing a 100% coverage report - after all 99.5% rounds up ๐Ÿ˜‰.

You can use npm run test:all to get these results.

TabMerger also uses mutation testing and currently scores above 95% (only 67/1499 mutants are undetected across all files).

I've parallelized the mutation testing scripts with a matrix build in GitHub to speed up the lengthy execution - from 12 hours to 5 hours.

As you can see from the below post, testing is a relatively "hidden" gem that many developers are not aware of or simply need the reason to get started. Additionally, almost all experienced testers recommended Stryker for mutation testing!

2. Linting - Static Testing ๐Ÿ“

You must have heard about linting by now and how amazing it is, but never wanted to delve into it since it sounds too complicated for little to no benefits. I felt exactly the same way until I started using it - and let me tell you linting is beyond amazing.

Source Code Linting

Add ESLint to your project (even if you plan to use TypeScript). Imagine writing a very long essay/thesis in a Word document without grammar highlighting - do you think you will be flawless? Isn't it nice to be warned of any inaccuracies/errors you made right away?

That's exactly ESLint's purpose inside your VSCode IDE (assuming everything is setup right). You can configure it to follow specific rules according to your liking. So far, this fixed a lot of issues in my code - from small to large - and even allowed me to learn new Javascript concepts.

For example, I learned that const means constant reference rather than simply value, so you could actually have a const array whose elements can be changed, added or removed. The same is not true for a const variable. That is,

const arr: number[] = [];
arr.push(1) // valid
console.log(arr) // [1]

const val = 5;
val = 1; // error
Enter fullscreen mode Exit fullscreen mode

Here is an example of what ESLint looks like:
ESLint in VS Code

As you can see, the instructions are very clear and you are even provided with quick actions from VSCode which can be accessed with ctrl + .

Style Sheet Linting

Now that you have ESLint working, you should consider StyleLint for your styling files (CSS, SASS, LESS, etc.).

This helps reduce duplicates that are scattered across your many files on large projects. StyleLint also enforces best standards such as the following:

Spacing Errors

Stylelint Spacing Errors in VS Code

Unit Errors

Stylelint Unit Errors in VS Code

Duplicates

Stylelint Duplicates in VS Code

Additionally, StyleLint detects when you forget to add blank lines between blocks of styles and/or if you have an extra space in a block comment like:

/* <- space
 * comment
 */
Enter fullscreen mode Exit fullscreen mode

TabMerger Linting

TabMerger uses both linting types dynamically (through the use of IDE extensions: ESLint & stylelint) and manually:

  • npm run lint โ†’ ESLint
  • npm run lint:style โ†’ StyleLint

Manually linting will produce a report in the command line that will outline all the errors across all files so that you can quickly find them (rather than opening each file one by one). Here is an example:
Manual Style Lint in TabMerger

Note: a clean run will produce no output.

3. TypeScript โœ

With both of these linters, you will be happy to know that TypeScript (TS) also offers "linting" in the form of type control.

This is super useful when working on any project as you can quickly hover over anything (function, variable, etc.) to get more type specific information in your IDE. TypeScript is also very well integrated with VS Code.

Typing information can be seen by hovering:
TypeScript Type Information

Here is how TypeScript errors look like:

Error

TypeScript Error Demonstration

No Error

TypeScript Without Error Demonstration

A good point about TypeScript is that you can slowly/incrementally modify your JavaScript files in existing projects and everything will still work fine - since TS files get compiled to JS. Check out TabMerger's repository to see how I structured my project to incorporate and successfully run with TypeScript.

I am still in the process of learning TypeScript and in TabMerger I currently have around 100 places where I am not sure how to "type" properly - so I am by no means a master with TypeScript - but ever since I started using it, I haven't looked back.

So far, I've refactored pretty much all my old projects to include TypeScript in one way or another. The typing information it provides and just the process of migrating to TypeScript is very rewarding and useful!

It will take longer to get used to TypeScript than linting but it should not take too long before you start seeing how useful TS is.

4. Module Aliasing ๐Ÿ’ฅ

Tired of looking up your directory tree to know the relative path of your import?

This can certainly slow down your workflow and is not very practical when you consider the fact that users/contributors do not want to look up your structure just to use your module. It is very common for npm/yarn packages to have their module paths aliased to simpler names that are mapped to the correct paths.

To do this in TS, you can add the baseURL and paths options to your TS configuration file. If done right, this allows you to import { A } from @A/A instead of import { A } from ../components/A/A.

Example from one of TabMerger's files:

Without Aliasing

Without Module Aliasing in TabMerger

With Aliasing

With Module Aliasing in TabMerger

Unfortunately, React's build scripts prevent the paths option in the tsconfig.json, so a work around is needed to get this working properly:

  • npm i -D react-app-rewired
  • Add config-overrides.js to root (see TabMerger's file)
  • Ensure alias object matches your aliases as shown in the file from the previous step
  • change start: react-scripts start to start: react-app-rewired start and the same for the build script (see TabMerger's file)

You will also need to adjust your jest.config.js by adding the alias' and their corresponding true paths to the moduleNameMapper property.

Note that you can use RegExp variables to shorten these key/value pairs.

5. Documentation ๐Ÿ“š

By now, you might have noticed that the functions I posted in some of the above images have a specific comment syntax. Something like:
TabMerger's Documentation Comments

This is done on purpose to generate good looking documentation as seen here. The main modules which generate these documentation reports are jsDoc (Javascript) and typeDoc (TypeScript).

Commenting your code like this will make it much easier to follow for anyone who visits it for the first time. It might also allow you to remember that hard to understand part in your code. The added bonus of using such comments for documentation is that it makes the transition from JS to TS much smoother as you can "infer" types from the comments using VS Code to automatically type your function arguments and return values.

You can see that only specific modules are shown on the documentation's main page. This can be controlled by a configuration file and by adding the following to the top of your respective files:

/**
 * @module MODULE_NAME
 */
Enter fullscreen mode Exit fullscreen mode

TabMerger Documentation Generation

In TabMerger, you can use the following commands to generate documentation reports:

  • npm run jsdoc (JavaScript)
  • npm run typedoc (TypeScript)

Conclusion

I hope my suggestions are useful to some of you. I urge you to take action and add these items to your project as soon as possible.

I can almost guarantee that you will instantly be more excited to work on your project(s) (granted everything works as expected). Worst thing that can happen is you cannot get one of the items to work properly or just don't find it that useful. In that case, you can simply revert back to the good old days ๐Ÿ˜Š.

I am actually in the process of looking for work so have a "lot" of spare time to help anyone who is confused or stuck on any of these items.

Cheers ๐Ÿฅ‚

Discussion (2)

pic
Editor guide
Collapse
polaroidkidd profile image
Daniel Einars

The module aliases can come back to haunt you though because it makes it easy to accidentally create circular dependencies. I use them aswllu but with the rule of thumb to not use aliased imports within the module. So if I'm working on a component which imports another component, I'll use the relative path for that import.

Collapse
lbragile profile image
Lior Bragilevsky Author

Great point! As long as you provide aliases to the main modules of your project (not their internals), circular dependencies should not happen. Yes, you could use relative imports within a module without any problems, but I think it leads to slower programming as you have to determine the correct relative path each time - unless your IDE handles this for you. In my case aliasing greatly increased my workflow speed - but your comment brought forward a valid point that I previously did not consider.