Before we begin: The "beginner" in the title is for open-source newbies. The article assumes some level of front-end knowledge; having said that, I'd encourage you to read-on nonetheless 🙂
What's going to be covered in this article?
This article aims to be a simplistic guide for people who want to get started with open-source contributions; it's to help newbies navigate through issues, the code base, etc.
We're going to,
- Pick and Fork a repository (repo)
- Pick an issue to solve
- Build a fix (and refactor it)
- Raise a pull request (PR)
Why am I writing this?
When I googled "How to get started with open-source contributions", I didn't find any solid how-to guides. Most articles or tips I could find were centered around making documentation changes for Hactoberfest, while those are great and they give you a good sense of how to get started with Github and PRs, they still did not offer enough of a platform to build on.
I've picked Vue as an example, but you could equate these steps to most open-source repositories.
Step 1 - The Issue
The first thing you'd want to do is go to the Github repo for VueJS, go to the issues tab and filter by label - "good first issue" and look for PRs that don't have the "has PR" label.
Note: These labels are pretty standard but they're not guaranteed to be the same if you're looking at a different project.
In the list of open "good first issues", we're picking the second one titled:
$http.delete shows warning "avoid using JavaScript unary operator as property name"
When you open the issue you'll find the following details,
Version
2.6.11Reproduction link
https://codepen.io/frOracle/pen/vYOEEVWSteps to reproduce
use $http.delete in @clickWhat is expected?
$http.delete is a function, not unary operatorWhat is actually happening?
a warning "avoid using JavaScript unary operator as property name"
Note: Issue logging is usually driven by a template that's decided by the project authors.
In this case Vue has decided that they want the person logging the issue to
- Provide a reproduction link
- Provide steps to reproduce
and answer a few questions around the behavior.
If you open the codepen link and open the console you'll see the following error,
"[Vue warn]: Error compiling template:
avoid using JavaScript unary operator as property name: 'delete()' in expression @click.prevent='$http.delete('/rest/close')'
1 | <div id='app'>
2 | <a href='#' @click.prevent='$http.delete('/rest/close')'>click</a>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 | </div>
(found in <Root>)"
Let's try to understand what's happening here; based on the issue description, the expectation is that Vue does not throw a warning when $http.delete
is used as delete is a valid HTTP verb (others being GET, POST, PUT, PATCH).
Come to think of it, Vue shouldn't throw a warning when any form of .delete
is used, either with $http
or any other object as delete
is a valid property name on objects. You can read more about property name limitations.
Step 2 - The Solution
So before we get to understanding the project structure and where we can make this change; this issue (and not all issues can be solved in this manner) can be solved as a generic JavaScript problem statement.
To solve this issue, we essentially need to check a string and not throw a warning in case delete()
(or any other unary operator) was invoked as an object property.
For given string
str
,
We need to return a truthy value if thestr
has a.
prefixing thedelete
keyword
The simplest way to solve this for the most basic case would be,
let unaryOp = 'delete';
let str = '.delete';
if (str.charAt[0] === '.' && str.match('delete')) {
// continue and DO NOT throw a warning
}
Now the above code is in no way ideal for a variety of reasons, some being:
It caters to only the
delete
operator; we need to also take care oftypeof
andvoid
for instance.It assumes the string
str
would always be of a particular format.Works only for
.
as a prefix; the logic is not flexible enough to add another prefix.
We need to write this in a more robust manner to cater to the problems mentioned above - as a rule of thumb (and not just for open-source projects), challenge or question the code you've written, because almost always, there's a better way to write it.
We can use the RegExp and the string match method for this!
Now like all experience developers, I too have the lowest level of proficiency with regular expressions, so I'm going to use one I found online.
let re = new RegExp(`
\\bdelete\\s*\\([^\\)]*\\)|
\\btypeof\\s*\\([^\\)]*\\)|
\\bvoid\\s*\\([^\\)]*\\)
`);
// PS: this is the same regex being used in the Vue repo!
let matched = str.match(re);
let allowedPrefixes = ['.'];
if (matched && allowedPrefixes.includes(str.charAt(matched.index - 1))) {
// continue and DO NOT throw a warning
}
Step 3: Finding the right file
To simplify testing and debugging, I created a minimal setup - a vue-oss-testing
folder which resides in the same directory as the cloned vue
repository folder.
Within this folder, we need to setup an example similar to the codepen link in the issue and refer to the local copy of the the Vue dev build.
Directory structure
.
+-- vue
+-- vue-oss-testing
| +-- index.html
| +-- app.js
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="test">
<div>
<button @click="obj.delete()">Click here</button>
</div>
</div>
<script src="../vue/dist/vue.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
let app = new Vue({
data() {
return {
obj: {
delete: function() {
console.log('Calling delete function');
}
}
}
}
})
app.$mount('#test') // this is the entry point
The quickest way to find the desired file is to use this complicated series of steps called "Find All" 😁
Just go to VS Code (or whatever editor you prefer) and search for the error,
avoid using JavaScript unary operator as property name
This led me to a file called errorDetector.js
which had the following function which seems to be what we need to fix!
Pro tip: You can run your vue-oss-testing
project and set a break-point at this line in the dist vue.js file in DevTools and go through the call stack to understand the execution flow right from the first app.$mount()
function.
A quick glance at the function gives the notion that it allows for unary operators to be prefixed by $
only, so we need to extend this solution to allow for more than just $
.
We could fix making the following changes (similar to what we did earlier),
const allowedPrefixes = ['.', '$']
if (keywordMatch && !allowedPrefixes.includes(stripped.charAt(keywordMatch.index - 1)))
Nothing else changes in the function,
You can now run your code again and observe the console - Vue doesn't throw a warning anymore!
Step 4 - Write a test case
Now again, to find the right spec file, let's use our Cmd/Ctrl + Shift + F
superpower! and we'll find this in the template.spec.js
file,
Let's add our spec after this,
And that's it!
As the final step in the build/contribution step is to (raise a Pull Request)[https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request].
For this specific issue, there is already a PR in review with a very similar fix!
Recap
- Go to any open-source repo of your choice
- Filter through features or issues marked as "good first issue"
- Clone the code and replicate the issue
- Add a fix, refactor it to be robust!
- Raise a PR and wait for review comments
Next Steps
Although I've covered a front-end repository here, I hope I was able to keep the steps generic enough for you to apply them to a language of your choice.
Here's a list of all open issues - labelled "good first issue" or "Hacktoberfest" - across all languages, so you can filter!
What more? ... Participate!
Another way to be involved is to participate in the community channels, interact with developers - there are a lot of really good people out there and there's a lot to learn!
Don't be afraid to ask questions, there's no such thing as a stupid question.
Link to the VueJS discord channel - https://chat.vuejs.org/
And finally, I would love to hear your thoughts on this article. ✌
PS: Shout out to all the light-theme coders!
Top comments (1)
Crisp and clear article, One should definitely follow the steps.