Under the Hood
Let’s begin with how the idea came to the mind. One of my friends posted a tweet about this JS confusing file system for configuring third parties.
Let me explain, you want to install Tailwind CSS along with webpack and typescript in your frontend repository.
So what you typically do you add all the corresponding files in the root directory to mention the configuration.
This raised a question among developers otherwise it will keep on increasing the configuration files for different packages all lie in the root directory path.
This tweet summarises everything I am talking about.
Introspection
So I think the solution won’t be easy.
First, we should understand why we need these config files in the root directory.
When I googled this thing, I found that people are discussing this problem in nodejs projects.
the creeping scourge of tooling config files in project root directories #79
Splitting this out from #71 which was rather broad. There are (at least) two separate issues there; one is where user-specific config files should live, and another is where project-specific config files should live. This issue is about project-specific config files.
The files we're talking about are configuration files for development dependencies and are committed to VCS.
Many projects suffer from the problem of too many config files in the project root, as @iansu tweeted:
We put config files in the project root because we put config files in the project root. There is no reason other than a lack of an alternative convention.
We can do better than this. The idea is we aim for a "critical mass" of popular tooling authors moving their project-specific configuration to a subdirectory (e.g., .config/
). If we can agree on a subdirectory, and change our tools to support the new subdirectory, we will significantly reduce this problem. It's our hope (though not a strict requirement) that the convention we agree upon will be flexible enough to reach beyond the JS ecosystem. For instance, your .travis.yml
and netlify.toml
could live in this directory as well, if this idea becomes popular enough.
We should get buy-in from maintainers of popular tools; if these tools adopt the new subdirectory, it's likely the ecosystem will slowly follow suit.
cc @nodejs/tooling @nodejs/package-maintenance
But that’s not the point either, why we need these files in the root directory lies in the past.
- Centralised configuration is easy to handle
- Easy to setup the configurations as one file in the root directory
- Easy to read by package.json exists and must exist in the root directory
- Easy to work and scale with other developers in the team
- Easy to read by GitHub and version controls
A lot of thought wouldn’t have been given to this problem statement, instead, developers developing packages simply stated to define a config file in the root directory.
Alternative Solution
I googled the solution and found a stackoverflow discussion
Lately, I've been creating a chrome extension and for that, I use a bunch of tools and bundlers that requires a config file-usually starting with a dot. In the root directory, everything looks so cluttered, and it takes a few seconds for me to find a file in the root.
…Is there a way to put every configuration file to a config directory rather than root in Node…
But most of the discussions are going for nodejs projects, and we also want to solve this convention problem for frontend frameworks.
This makes sense to me a lot now, a lot of developers need a config folder to put all the configuration files and a lot of developers won’t need that because they understand the existing solution.
Where we want is a good question, but as a developer, we should try to make it better. A good option will be putting efforts into solving this problem for at least a few developers who might live to see all config files inside the config folder.
Solution: Single Config Directory
Single config directory meaning one config folder inside the root directory contains all the configuration files.
Config folder in the root directory will contain, tailwind, webpack, yaml, and other configuration files to configure third-party tools.
The biggest bottleneck is the tools that require the config file to be present in the root directory and in that case, we can’t alter that tool config within our project, so need a smart move in that case.
3 Steps to do that!!!
- Create a config directory
- Add all the config files in the directory
- Adjust the build scripts, and tools scripts accordingly (this will be tricky)
This sounds easy but some of the tools won’t work at all simply because they inherently deal with the configuration located in the root directory.
And that makes everything tricky, but we do need this configuration solution as an optional solution.
One way to do that is to create an npm script that alters the configuration for tools during build time from the root config directory.
In this way, we can simply put all the config files in one directory and make our repository look clean and simple.
But a lot to do in that case because it’s a universal method for a lot of developers and npm modules to have a config file in the root directory.
That’s it
See you in the next one.
Top comments (13)
For example in Nuxt it is possible to have integration modules (which are distributed as npm package and activated simply by adding entry into
modules
array innuxt.config.ts
) which can inject the most common options todefineNuxtConfig
object and so you can only keep one extra config file (nuxt.config.ts
itself) unless you really something extra that cant be achieved like that).Yes, if the module not exist yet, you may have hard times. But you can always try to write your own plugin.
Yes, it is not platform-agnostic, but why not to benefit from a framework? I beleive others will have similar mechanisms to help centralising the config.
I totally agree with the next framework thing but creating platform-agnostic will still remain the bottleneck.
Some of these tools allow for an optional path to their config file. Like eslint has the --config flag. We can have our build scripts use those flags to configure that. Though it would be nice to have it be more turnkey. An environment variable option gets us closer, though it still requires some fussing around. We would want our editors to be able to adapt too.
I think there won't be enough active demand to make this convention happen. And think about breaking changes if someone is using that sort of folder with their own unexpected convention for a "config project" in their repo or something like that. Just playing devil's advocate there. Everything has tradeoffs and risks.
Make an RFC and we'll talk 😛 I suppose this article is close to that but we need more guidance and more voice of authority in the conversation.
I vote for
./.conf/
or./.config/
If we start asking for it enough and get the largest tools on board, the rest should follow. I'd start with node.
I think the rest weren't able to follow this new convention because of platform agnostic solution, a solution that should exist in the Javascript(JS) ecosystem instead of the framework ecosystem and developing such kind of tool will be a task
What do you mean by the Javascript ecosystem?
We can't simply create an npm module that will solve the problem for every existing and upcoming framework, in order to be backward and forward compatible it's make sense if javascript ecosystem like node bring something as a solution which can become universal, if not wrong!!
That was my suggestion: to start with node. Not another node package, but node-native support of configuration files in a
.conf
directory.That is a bit complex topic as there are so many different tools.
Currently you can use .env file. It can be located anywhere.
With JS it it trivial to create a .JSON config and put it into any location. Can be one configured in process.env.mypackagename.configfilename (in .env file). You end with custom dir - you can also follow Linux ~/etc and ./etc. Npmrc normally is loaded from system global path, then ~/.npmrc then ./.npmrc.
Finally you can run this in a sandbox (docker?) and inject the files. Or k8s and map configmaps.
Then you have the issue of ./src vs./dist. Even worse when creating js from ts and also generating types. And having static content. One option is to have subdirs under src and dist.
Tests. Where to put unit tests, integration tests, fixtures, docs (manual), docs (generated), default confirmation and finally local confirmation override? With docker you could achieve that but it is challenging.
Overall you can get it done easily with proper design and many iterations of refactoring.
What I suggest... well... should I write an article about it? Likely...
I don't think just sweeping it under the rug is the solution, there needs to be less configuration. This is why frontend development is viewed as over engineered and bloated.
There should be a standard file format that defines the project level, it could point to where the other configuration files are, if you still want to have multiple files. The issue that I have had in the past with multiple files is finding which one is causing a bug due to a misconfiguration -- too many different formats and naming conventions.
Yeah, debugging with multiple files make things difficult, and only using those files to configure the plugins is quite a waste of resource(time + space)
Thanks for the article, definitely a good idea, would also be good to create a repository to test this out for a few configuration files
Yeah, seems like a small JS project if able to complete!!!