- “Big Code: Developer Infrastructure at Facebook’s Scale” (F8 2015): what is it like to be an engineer at Facebook; moving from Git towards Mercurial; Atom-based IDE for App, server-side and client-side development; continues integration at Facebook.
- Zach Holman (GitHub) on “Move fast and break nothing”: how to ship software changes fast and not to break things.
I’ve been curious about the state of our CSS code and its changes over the time.
So I’ve written recently a program called
What does it do? It answers the following questions:
- What is a total number of selectors in your CSS codebase? How has it been changing over the time?
- What is a maximum/average/median selector‘s specificity of your CSS codebase? How has it been changing over the time?
- How does the distribution of selector‘s specificity of your CSS codebase look like? How has it been changing over the time?
- How many selectors in your CSS codebase contain at least one rule with the
!importantdirective? How has it been changing over the time?
Wait, why is it so important? It’s not, until you have a codebase of dozens of thousands lines of code that is hard to maintain and you used to do a lot of experiments. And of course, if it’s not even important, it’s quite interesting at least.
node-specificity provides two commands. One is for parsing your CSS files and creating profiles.
Second is for reading or “exploring” these profiles. Let’s look at an example. I have a few versions of
CSS of the website
you’re reading right now. As I’m writing this post the website is using
Alright, let’s create profiles for these files:
$ node-specificity parse v1.css --label=v1 --output=v1.json ... $ node-specificity parse v8.css --label=v8 --output=v8.json
We’ve created a profile for each CSS file since we want to observe changings over the time. If you use more than one CSS file on your website, you have to create a profile for all of them, for instance:
$ node-specificity parse main.css print.css --label=2014-12-23 --output=20141223.json
Label acts as a profile’s name in reports. Once we have profiles created, we are able to run a report. Let’s start a ‘server’ report:
$ node-specificity explore v*.json --report=server Server is running on http://localhost:4000/ Press Ctrl + C to stop it.
Open a browser and go to “http://localhost:4000/”. Now you’re supposed to be seeing the page with different controls and a weird graph. It‘s the specificity distribution chart (see in the picture above). For each specificity (tuple) it shows the total number of selectors of this specificity in the specific profile.
Other graphs are: number of selectors in your CSS files and total number of selectors in profiles,
how many of them contain rules with the
!important directive, average and median
values of selector’s specificity for CSS files and profiles.
You are able to explore all these graphs for a specific profile. To do this, you have to select the particular profile’s label in the dropdown list. For instance, it’s the specificity distribution bar chart for ‘v8.json’ profile in the picture below.
server report is quite a powerful tool. Bear in mind, images above are for the profiles
of one humble CSS file. If you have a few files for profile, it gets better.
There is also
inspect report (it’s used as the default one). If you run
node-specificity explore v8.json,
it will print out the list of all selectors in the given profile, the summary on specificity numbers
and the specificity distribution chart, which is very similar to the one you can see above.
Reports can accept additional command line options. There are few of them. In the example above,
--no-inspect-selectors option has been used. It disables printing out the list of all selectors.
That’s it. Happy exploring!
- Drew Petersen (Spotify) on “Developing Games Using Data not Trees”: cons and pros of using data-oriented approach in game development.
- Daniel Espeset (Etsy) on “The role of Front-end Infrastructure at Etsy”: continuos deployment and experimentation-driven development, instruments that help to delete old code constantly.
Often I finish working day without committing changes to the repository. Thus, next morning I need to open all the files I was working yesterday. And I found an efficient way to do this.
$ vim -p $(git diff --name-only HEAD | sed "s,$(git rev-parse --show-prefix),," | tr "\n" " ")
It opens Vim and loads all modified files in tabs. You could add this command as an alias to your
but adding this to
.gitconfig seems like a better option. This is what you need to add to your
[alias] open = "!vim -c \"cd $GIT_PREFIX\" -p $(git diff --name-only HEAD | tr '\\n' ' ')"
To run this command you need to type
git open in the terminal. Since all commands prefixed with an exclamation
point are executed from the top-level directory of a repository, we need to change working directory in Vim to
the current one. And of course you can replace Vim by your favorite editor or event by
Besides, If you use sort of file watchers to perform certain operations when files change, then you would find the following command quite helpful. It changes modification time of all modified files at once.
[alias] touch = "!touch -c $(git diff --name-only HEAD | tr '\\n' ' ')"
You can find more handy aliases in .dotfiles of mine.
- Bred Victor (MIT) on “Media for Thinking the Unthinkable”: incredible ideas that will probably change the way we present and understand things.
- Facebook’s way to Flux and React in “Rethinking Web App Development at Facebook”.
- Patrick Hamann (The Guardian) on “CSS and the Critical Path”: dealing with performance bottlenecks in the browser from network to painting.