My first contributions to an NPM Module open source project

 Every developer ought to contribute back to the community they so heavily benefit from. Using open source tools, libraries and other resources is something we all do. We leverage the work from countless peers. And that is fine — that is why our peers share their work. However, it would be great if we would also actively participate. For example by spreading the word about the projects we make use of — in articles, presentations and videos. And of course by making code contributions that help to improve the functionality of a project.

Like many developers, I felt a little reluctant about making a code contribution. I was not sure how exactly that should be done and what requirements I should satisfy. I probably could and should have made contributions on many earlier occasions — but in the end my very first code contribution to an actual open source project was made just a few days ago — and I am still waiting for my Pull Request to be accepted.

In this article I will share how I made that contribution. Not because the code itself is in any way special (to be honest, it is quite lame) but to demonstrate how simple the process is — thanks to GitHub — and how you really should not let that reluctance hold you back. Just go through the steps, make the improvement and share your change. It is the ultimate form of appreciation for the unsung heroes that create the software we benefit from on a daily basis.

The Open Source Project: NPM Module faker.js

In an earlier article I have introduced faker.js. This is an NPM module for generating fake data, for example for use in tests, demonstrations and trainings. Faker.js is written in JavaScript, used as either a server side Node application or as a client side browser library.

Faker.js generates many types of data — names, addresses, products, companies, dates, IP addresses and many more. It also support different locales — localized data, according to the formats and languages in many different countries in the world. Faker for example knows how to generate Dutch Postcodes, French First Names, German Addresses and Portuguese product descriptions — for both Portugal and Brazil.

Faker.js is very useful. And very easy to use. Downloaded close to 1.5M times per week with over 110 contributors. A well established project that has been around for over 8 years. Maintained by Marak — who on their website indicate “We are on a mission to be awesome and make the world a better place.” I would like to join that mission by helping to improve faker.js.

The grantedly minuscule contribution I have decided to make consists of translations of names of weekdays and months for the Dutch (NL) locale. Is that how I make a better world? Well. It is a step, albeit a very small one. It is token of appreciation to Marak and the work they are doing. And it adds value to faker.js, even though not a on a spectacular level. And I suspect it will lower the threshold for me — and perhaps for you, dear reader — to make further contributions to this and other projects.

The Plan and its Execution

So here is the plan: I will define weekdays and months in Dutch and offer that contribution to Marak for inclusion in faker.js.

How is that done? Do I simply code the JavaScript and send an email to Marak? Or is this where GitHub comes in? And go through a more formal process? Indeed, GitHub is the core mechanism for creating and submitting the change.

Let me summarize the process — before showing the steps in much more detail.

First, I create a fork of the faker.js repository. A fork is my own copy of the repository — created and managed for me by GitHub.

Next, I clone the fork[ed] repository to my laptop. This basically means copying the sources to a local development environment.

Then, using a git client I define and check out a feature branch. I will make the changes for the new functionality I intend to contribute to faker.js on this branch.

Now it is time for some coding. I implement the change. I run all tests to verify I did not break anything. If I have added code not covered by the existing tests, I also extend the test set. I run the build script, to verify it is still working after I added my changes.

If everything is okay — I will now commit the changed and new sources [to the feature branch] and push the changes. My code contribution has landed now in my fork of the faker.js repository.

GitHub understands the situation and offers the option of creating a Pull Request in the original faker.js repository for the feature branch in the fork that contains my changes. This PR is my offering to the project maintainers; the PR describes the what and perhaps the why of my change and contains the code I have committed for the new feature.

At this point, ideally the PR is accepted — after being reviewed — and the code is merged into the master branch in the faker.js repository. It is also possible for the reviewers to ask additional questions, request refinements or even flat out reject my proposal (as they did with the PR that introduced generation of Star Wars related data).

At the time of writing, my PR is still under review. I expect it to be accepted, simple, straightforward as it is. But I feel a little anxious. As if I am waiting for my test results for some exam.

Below, you will find detailed descriptions of the steps I have outlined here. Hopefully clear enough for you to give it a try yourself.

Step by Step — from Fork to Pull Request

  1. Fork the Original Repository
    The repository for faker.js in GitHub is at https://github.com/Marak/faker.js. Go to this URL. Make sure you are logged in into your GitHub account. Then click on the Fork link to create your personal fork of this repo.
Image for post

When the Fork is complete, you have a new repository in your GitHub account — which is marked as a fork from the original (upstream) repository.

Image for post

2. Clone the Fork(ed) Repo

Clone the repository to a local development environment. This downloads all sources from GitHub to that environment,.

git clone https://github.com/lucasjellema/faker.js

When I want to run tests, builds or examples, I need to have installed all dependencies of the faker.js module:

npm install

This installs for example mocha — the test library used for faker.js.

3. Set Original Repo as Upstream

I must configure a remote that points to the upstream repository in Git to sync changes I make in a fork with the original repository. This also allows me to sync changes made in the original repository to my fork.

git remote add upstream https://github.com/Marak/faker.js.git

Verify the new upstream repository you’ve specified for your fork.

Image for post

4. Create and Checkout a Feature Branch

To neatly organize the changes I will be making — and to coordinate the subsequent Pull Request — I will create a branch to work on. This can be done in the GitHub browser UI or on the command line:

git checkout -b nl-locale-weekdays

This command creates the branch and checks out the branch. Any work now done locally is done on the feature branch. Note: the branch currently exists only locally — the branch has not been pushed to the remote repo so you will not yet see the branch in the GitHub UI.

Image for post

5. Implement the Change

In this particular case, I want to create the Dutch counterpart to the file lib/locales/en/date/weekday.js.

Image for post

I can simply create a copy of this file in directory lib/locales/nl/date/weekday.js. It turns out that I can easily provide the Dutch equivalent of the file month.js. I also copy lib/locales/en/date/index.js to lib/locales/nl/date. Before translating the content of weekday.js and month.js into Dutch, I edit the file lib/locales/nl/index.js that coordinates the Dutch locale; I add the line: nl.date = require("./date"); to make sure that the new date domain in the NL domain is loaded.

Then, I translate both weekday.js and month.js.

6. Run Test and Build

After making the changes, I run the entire test set.

npm test

This does not prove I defined the correct translations of course but it does verify that the code is still valid after making my changes. There is no need to extend the test set for this change.

Image for post

If you add functionality — new functions, even a new domain — then you need to make sure to update the test set to retain the test coverage. The project owner has asked several pull requesters to first extend the test set before the pull request can be accepted. See for example PR for Support parts of speech for faker.random.word and faker.random.words — needs test coverage.

7. Commit and Push Changes

At this point I can commit my changes .

git commit -m "Extended NL locale for date: names of weekdays and months"
Image for post

and push them to the remote repository (in GitHub)

git push origin nl-locale-weekdays

In the GitHub browser UI, the new commit is visible:

Image for post

8. Create a Pull Request for the New Feature with the Original Repo

The Pull Request is created in the GitHub Browser UI:

Image for post

See GitHub Docs on making a Pull Request for more details.

The PR is created and checked automatically. Then it is brought to the attention of the core committers on the faker.js project — for review.

Image for post

I am now waiting for my PR to be accepted. You can check progress and even weigh in: best PR ever.

Please feel encouraged to also make contributions to Faker — and hopefully even more interesting ones than this somewhat low hanging translation fruit. What about extending Faker with new namespaces — for example for weather, food, sports, airlines, programming languages, cloud? Or to start with a simple contribution, consider translating into Dutch data sets such as commerce/product_name, commerce/color, commerce/product_description, commerce/department, finance/account_type, finance/transaction_type, company/bs_verb, company/bs_noun, team/creature (animals), vehicle/fuel, vehicle/vehicle_type. All these locale sets are defined in English here: https://github.com/Marak/faker.js/tree/master/lib/locales/en.

What is next?

While I am waiting for the PR to be accepted (or for more work on my part to finalize the PR), I would like to start using my customized version of faker.js instead of the official release that is currently sadly lacking Dutch names for months and weekdays. This is easily achieved through a special syntax in the dependencies in package.json for any application that would like to make use of faker.js.

Where is would normally say:

"dependencies": {
"faker": "^5.1.0"
}

we can change the reference to faker in package.json to the customized version in our GitHub repo:

"dependencies": {
"faker": "lucasjellema/faker.js#nl-locale-weekdays"
}

This syntax references the GitHub Repo and the specific branch from which the NPM module should be loaded. We can also reference a specific commit identifier. Note: see https://docs.npmjs.com/files/package.json#git-urls-as-dependencies for details on GitHub and other references to custom NPM modules in package.json.

Use npm install as always to download the dependencies specified in package.json. In this case this will download faker.js from the feature branch in my fork of the repository.

Eventually of course I hope to replace the customized version with the new release of faker.js that contains my feature.

The following snippet leverages my valiant extension of faker.js by generating a Dutch month and weekday:

const faker = require('faker');
faker.locale = "nl";
// generate month and weekday in the NL locale
// because of my extension of faker.js,
// this will produce real Dutch values
let month = faker.date.month();
let weekday = faker.date.weekday();
console.log(month);
console.log(weekday);

Comments

Popular posts from this blog

Flutter for Single-Page Scrollable Websites with Navigator 2.0

A Data Science Portfolio is More Valuable than a Resume

Better File Storage in Oracle Cloud