How does typical frontend project start?
git clone project cd project npm i
And we have received thousands of modules installed in the OS, megabytes (or gigabytes) of files. After installation we try to start a project using
npm start, but we get some
node-gyp, versions errors or vulnerabilities This walls of information, that we can't fix, are really frustrating. I want to talk about some of these problems.
Let’s see how much size popular project
Create React App has:
It has 300mbs that does nothing. After template was created devs can install
css-in-js packages, components library, something like
rx.js, some type definitions for typescript, etc. In result we have half of GB space of empty project without actual code base.
I want to remind - we are in chip shortage, Apple asks ~200$ for 128GB. These gigabytes of packages, that we transfer back and forth, don’t just disappear — they are stored in our disks (and often this is global npm packages, that we can’t just delete as project dependencies), in DNS servers, in data centres. This is unbelievable how irresponsibly we develop software, without looking into future and software complexity.
How regularly devs update their package dependencies? During my practice, this doesn’t happen as often as necessary. Let’s look at
create-react-app for example. It has
jest as dependency with version
27.4.3, when I wrote this article actual version was
micromatch package with version
4.0.4 (that was actual version for
minimatch package with version
3.0.4. But actual version is
5.0.1, that solve, at least one major security problem.
And this is just five minutes research,
Create React App has dozens of dependencies, which have dozens of dependencies, which have... One of them could be out of date or has vulnerability issues.
Deps control can be more hard with very popular projects.
Cypress updates its version very often. Sometimes it happens twice a week. When I’ve started to use
Cypress I updated it every two week, but then I just got tire to do this. But this was mistake - Cypress team, probably, fixed some major bugs, solved some vulnerabilities in this updates. But as developer in modern and big project, where you have many deps, you can’t hold dependencies actual every time.
There are many instructions and StackOverflow answers that recommend: “Install
this to solve your problem”. Package distribution systems (
pnpm) are very easy to use, they installed by default in some Unix-system, they installed with
Node.js. And this ease doesn’t good for our industry.
Because complexity of IT is growing up from year to year, new folks learn only the tip of the iceberg (not all people, of course). Because the main goal of business is getting money, not creating good and robust software, we have no time to control every aspect of development. Open-source folks spend their own time to support projects.
And because of these points we don’t spend time to check package size, all dependencies (include dependency’s dependencies), vulnerabilities, but much more, we don’t think that this package is necessary. We install
Axios instead of just using
fetch api. We use
css modules instead of using
BEM. We could use just REST API, instead of
GraphQL. And there is much more examples.
Prioritize robustness over development speed and “developer experience”.
Ask yourself about package necessity, maybe there is standard library method for your problem, or you don’t need full module, just a part, that you can copy-paste to your project.
Check not only stars and popularity, but also maintenance, update regularity, communication with community
CRAdoesn’t update about year, we don’t have any news from their team. This is red flag not to use
CRA. Actually, they released new version, but anyway, this was red flag :)
You can store node_modules in version control system
That sound stupid, but this is easy way to maintain dependencies, to ask questions “why do I need this”. This care us from unexpected node_modules extending.
Best practices are propaganda for juniors
This topic can be disputed, but I think that the Patterns and other best practices, that puts into folks head to use it without thinking about necessity - are propaganda just as is. The Patterns are good, but we need to use it when we really meet a problem in code base. Sounds like I recommend to go to the Assembly and code using it, but no, I just recommend to think twice before doing something.
Solve actual problem, don’t solve future problem
I have met so many times, when “architect” decided to use something like a store, argued that in future we could have a lot of data which we can share between modules and etc. And in this scenario we could use the react context and change it with store when we actually find a problem with data management. Another problem is technology FOMO - you need to use popular solutions, be in edge of technology. And there is much more examples when we solve problems that doesn’t exist.
I want to show easy solutions of popular problems using standard library.
Often we have installed by default
Lodash in our projects.
Lodash give us some handy functions, some syntax sugar. One of the best function is
debounce, that we use when we need to control user input.
What’s wrong, you can ask. Source code of function is unreadable. This is little function, but we install a whole
Lodash for this. This is how debounce looks using plain JS:
The difference is dozens of lines of code, is less maintainable, needs more code control.
We often use
css-in-js or special setup of
webpack to stop class intersection. Really simple solution is BEM — methodology of a class naming. We need to name every class like block_element-modification. Using React it looks like:
componentName_someWord. This is easy.
When I've written this article I never stood a goal to change your mind, but if you start to think more about dependencies - this would be cool.
I can recommend you to read or watch:
Thank you ❤️