Here we are at the end of the GSOC 2019, seems yesterday that I wrote the first article before beginning my work for webpack, check it out if you want to have an overview of my project (link).
Long story short, in those 3 months I’ve developed a plugin called ReporterPlugin that helps to customize webpack’s output. You can read more on the Github repo and you can find it on npm as test-webpack-reporter-plugin.
The purpose of this plugin is to offer a more informative and CI friendly way of outputting information, offering an improvement over what is available at the moment:
- making easier to understand what webpack is doing, for example, you should now know where your compilation broke in a more chronologically accurate and predictable format
- reducing the time required to customize the information displayed, making easy to override webpack’s output, to remove it completely or to define any custom behavior (e.g. dumping log to a file)
What I’ve not been able to do in 3 months, is finding a different name for this plugin since webpack-reporter-plugin is already taken
Those are some fundamental concepts to understand the purpose of this project and how to use it.
You can think of hooks as event listeners, you can use myHook.tap(callback) to add a listener that will be executed when myHook.call(params) will be called.
Hooks are provided by a library called tapable and are used extensively in webpack’s code to implement the plugin system (e.g. compiler.hooks.done is called every time a compilation has finished).
This plugin uses hooks in 2 ways:
- Listens to every webpack’s hook in order to be able to log whatever is happening during a compilation
- Provides 4 new hooks (info, warn, error and stats) allowing to easily write a CustomReporter to handle all logs
A CustomReporter is the actual piece of code that you will write in case you want to override webpack’s output. A Reporter taps into the ReporterPlugin’s hooks (info, warn, error and stats) specifying how to print all those kind of logs. While it’s straightforward to think of a custom reporter as something that formats and prints logs, it also covers use cases where you are not interested in printing but instead, you may want to dump all the logs into a file or forward them to a web server. Wrapping it up, a CustomReporter is something that listens to 4 different kinds of logs (info, warn, error and stats) and handles them as needed.
Since this plugin is meant to be used by anybody without requiring too much knowledge of webpack’s internals, it has good default settings so that it doesn’t need configurations to work, although, you can harness its power by tweaking the configurations. Through the configurations, you can decide which hooks you want your Reporter to report or to exclude and you can also pass one or more CustomReporters
Sometimes some hooks are called many times during a webpack run, this plugin allows you to limit those “noisy” hooks. You can set a value to tell this plugin to emit a log for a specific hook only once every N times or every N milliseconds.
After being selected for this GSOC I talked with my mentors and opened some discussion to gather feedback from the community, receiving great suggestions on the infrastructure design (webpack#9137) and the plugin configuration schema (webpack-reporter-plugin#2)
I started working on the bare bones of the project implementing the infrastructure that makes this plugin extensible with CustomReporters with the goal of providing a simple and friendly way of defining reporters. The result is that reporters are easy to write and look familiar to everyone that has seen the code of a webpack’s plugins.
After that, I refined the first implementation and made the plugin customizable through settings. After defining the schema, the other important task was to validate it to avoid errors. I used a library called schema-utils before implementing my own wrapper around a JSON validator called ajv to have more control over error messages.
When everything was in place I started writing documentation and tests. I decided to test if the plugin was able to validate and parse the configurations, listen and report the hooks according to the configurations and lastly I tested the correct behavior of the default reporter. This part has been really instructive and helped me discover and fix some problems.
While working on this project I looked at many webpack-contrib repositories and made mine as similar as possible to those in order to make it easier for people from the community to understand and possibly contribute to it. I’ve set up linting & commit linting to ensure consistency of code and commits and Travis CI and codecov to automate quality checks.
This is my second GSOC and it has been very different from my previous one for many reasons:
What hasn’t changed is the amazingness of this experience, something that I would suggest to every student!