<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jacky Efendi</title>
    <description>The latest articles on DEV Community by Jacky Efendi (@jackyef).</description>
    <link>https://dev.to/jackyef</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F169440%2F4d5afe27-35ee-416d-af75-18e3238a1184.jpg</url>
      <title>DEV Community: Jacky Efendi</title>
      <link>https://dev.to/jackyef</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jackyef"/>
    <language>en</language>
    <item>
      <title>Writing Your Own Changelog Generator with Git</title>
      <dc:creator>Jacky Efendi</dc:creator>
      <pubDate>Sun, 20 Oct 2019 10:09:44 +0000</pubDate>
      <link>https://dev.to/jackyef/writing-your-own-changelog-generator-with-git-25b2</link>
      <guid>https://dev.to/jackyef/writing-your-own-changelog-generator-with-git-25b2</guid>
      <description>&lt;h4&gt;
  
  
  Turn your commit messages into release notes for your users
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lC6TTdAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2As1Kr_0A-w5ZCES9A" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lC6TTdAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2As1Kr_0A-w5ZCES9A" alt=""&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@yancymin?utm_source=medium&amp;amp;utm_medium=referral"&gt;Yancy Min&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Changelogs are great. They give us a record of what changes in our project were made at a particular time. If you’re writing a library, it also gives your users awareness of what changed and gives the impression that your library is well-maintained and can be relied on. Tools such as &lt;a href="https://github.com/conventional-changelog/conventional-changelog"&gt;conventional-changelog&lt;/a&gt; allow us to generate a very neat changelog easily, provided we adhere to their conventions on how to write commit messages. One of the most popular ones is &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o1WcNvTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A2iVPZeYudHvIaIXRyT-WyQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o1WcNvTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A2iVPZeYudHvIaIXRyT-WyQ.png" alt=""&gt;&lt;/a&gt;Example of a generated changelog in &lt;a href="https://github.com/angular/angular/blob/master/CHANGELOG.md"&gt;Angular’s repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under the hood, these tools use Git to do this. In this article, we’ll go through some steps to write our own fully-functional changelog generator!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Git?
&lt;/h3&gt;

&lt;p&gt;Git is really powerful software. It’s a tool for collaborative software development. It’s used by almost every developer in the world! Even though I also use Git all the time, I’d be the first to admit that I don’t really know a whole lot about Git. I can do the basic stuff and understand some of the concepts, enough for me to be productive. But for the more advanced things you can actually do with Git? I have a long, long way to go. Seeing tweets like this makes me feel better about myself because it means that other developers are also discovering new stuff about Git.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--A-APnvR9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/715433404100059137/AYjfw8tH_normal.jpg" alt="Jason Lengstorf but spoopier 👻 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Jason Lengstorf but spoopier 👻
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/jlengstorf"&gt;@jlengstorf&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Cool thing I just learned: if you want to see only the Git commits in a certain folder of a repo, you can do that!&lt;br&gt;&lt;br&gt;git log --oneline folder-name&lt;br&gt;&lt;br&gt;(Or leave out `--oneline` to see the full commit log.)
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      17:27 PM - 15 Jul 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1150819232449306624" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1150819232449306624" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      15
      &lt;a href="https://twitter.com/intent/like?tweet_id=1150819232449306624" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      79
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  Setting Up Our Repository
&lt;/h3&gt;

&lt;p&gt;Let’s create a directory, and initialize it as a Git repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir changelog-generator
cd changelog-generator
git init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In it, we’ll create a simple package.json file that only contains the version field. Think of this as a very simple JavaScript project repository. To make it simple, let’s just set "1" as the version.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": "1"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After that, let’s create a CHANGELOG.md file. Just leave it empty for now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8FzoLbhu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AErngtdWfvT3Uduh8hipG9Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8FzoLbhu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AErngtdWfvT3Uduh8hipG9Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should be how our project looks; we’ll commit this for now. In a conventional commit, that each commit message is required to be prefixed with one of the available prefixes like feat_,_ fix, perf, refactor, chore_,_ etc. For our repository, let’s say we have to use two prefixes, chore and feature. For our initial commit, let’s use the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "chore: Initial commit for changelog generator"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, just so we can have two commits in our repo, let’s create a file named index.js. Leave it empty; we’ll write code there later. Do another commit, and for this one, set feature: Added index.js script as the commit message.&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing the Changelog Generator
&lt;/h3&gt;

&lt;p&gt;Now we’re getting to the main part! If we type git log into our terminal, we’ll see git provides us with a list of the commits we have made so far in the repo.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 1c3ec7c03f2796790eaf7271ef47b2141b22cb63 (HEAD -&amp;gt; master)
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 14:39:42 2019 +0700

feature: Added index.js script

commit 05fbe5c5eee29cc33065474800e5401370e7e929
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 14:39:37 2019 +0700

chore: Initial commit for changelog generator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Whoa, that’s a lot of stuff! Remember, we want to create a changelog that is similar to the CHANGELOG.md in &lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt;’s repository. This means for every commit, we only need the commit message and the commit SHA1 hash. Fortunately, &lt;a href="https://git-scm.com/docs/git-log#Documentation/git-log.txt---formatltformatgt"&gt;git log&lt;/a&gt; can be configured with different formats. If we type git log --format=%B%H, Git will give us only the raw commit body and the hash.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature: Added index.js script
1c3ec7c03f2796790eaf7271ef47b2141b22cb63
chore: Initial commit for changelog generator
05fbe5c5eee29cc33065474800e5401370e7e929
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, we can create a script that just runs this command, gets the string output and then transforms it into an array. Let’s write some code in index.js:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Basically, we are just running the git log while adding a —--—DELIMITER—--— string to help us split the string. We also filtered out the commit if it doesn’t have a SHA hash. If we run the script, we will see the following output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ node index.js
{ commitsArray:
   [ { sha: '1c3ec7c03f2796790eaf7271ef47b2141b22cb63',
       message: 'feature: Added index.js script' },
     { sha: '05fbe5c5eee29cc33065474800e5401370e7e929',
       message: 'chore: Initial commit for changelog generator' } ] }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nice, now we have an array of commits, which are just objects with sha and message. We can use this array to write things into our CHANGELOG.md. Let’s do that for now. A lot of the code is just reading from a file, manipulating the string, and then writing the new string into a file, so I won’t bore you with the details. Here is the new code that can generate a changelog for us.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;If we run our new code, we’ll see a nice changelog:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oETXBZBm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AAlEd8JIHPxkQEW0QvpozDQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oETXBZBm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AAlEd8JIHPxkQEW0QvpozDQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works! Let’s manually bump the version in our package.json file to "2" and commit everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "chore: Bump to version 2"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But, we have a problem. If we run the script again, we’ll see we have repeated items in the list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wc4zJQrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1016/1%2Ayl3nwoQ4S3JDZkjDx6lEHg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wc4zJQrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1016/1%2Ayl3nwoQ4S3JDZkjDx6lEHg.png" alt=""&gt;&lt;/a&gt;Items in version 2 list should not appear again in version 3 list…&lt;/p&gt;

&lt;p&gt;This happens because we are only running git log, which will return all the commits. What we want is to only get the logs from a particular commit, up to the current state. We need some kind of versioning.&lt;/p&gt;
&lt;h3&gt;
  
  
  Versioning
&lt;/h3&gt;

&lt;p&gt;The easiest way to achieve versioning using Git is by using Git tags. Basically, the purpose of Git tags is to tag a particular commit (duh). Let’s try creating one. Run git log in your terminal again:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 50df6552c5e709b38dfd915aad3fa8e07e2b86e1 (HEAD -&amp;gt; master)
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 15:27:36 2019 +0700

chore: Bump to version 2

commit 1c3ec7c03f2796790eaf7271ef47b2141b22cb63
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 14:39:42 2019 +0700

feature: Added index.js script

commit 05fbe5c5eee29cc33065474800e5401370e7e929
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 14:39:37 2019 +0700

chore: Initial commit for changelog generator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We see that the latest commit in our repo is the one with the hash 50df6552c5e709b38dfd915aad3fa8e07e2b86e1. yours will be different, so check it on your machine. Let’s tag this latest commit as version2. The way to do it is with the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git tag -a -m "Tag for version 2" version2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The command will create an annotated tag, with “Tag for version 2” as the annotation, and version2 as the tag name. Now, let’s try running git log again:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 50df6552c5e709b38dfd915aad3fa8e07e2b86e1 (HEAD -&amp;gt; master, tag: version2)
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 15:27:36 2019 +0700

chore: Bump to version 2
(...)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can see that our commit now has tag: version2 written beside it. This means that the tag version2 is now referring to this particular commit, just like our current HEAD. Now, we can run git describe --long, and Git will tell us the latest tag we have in our Git repository.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ git describe --long
version2-0-g50df655
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The output might seem a bit cryptic but is actually very simple. The string has three parts in it, all delimited by the — character. Here is the explanation for each part:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;version2: The latest tag found in this Git commit history&lt;/li&gt;
&lt;li&gt;0: The number of refs between the latest tag and the current HEAD&lt;/li&gt;
&lt;li&gt;g50df655: The abbreviated commit SHA of the current HEAD, prefixed with “g”.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What we care about here is the name of the latest tag. We can pass this information to git log. The git log command can accept two Git refs, and return only the logs between those two refs. For example, we can do git log version2..HEAD. Git will return nothing, because version2 and HEAD currently refer to the same Git commit. Let’s try adding a dummy.txt file and just commit it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch dummy.txt
git add .
git commit -m "chore: Added dummy.txt file"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, if we run git log version2..HEAD again, we will see only one commit.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit b9491e3c9a22bddff528e48fd599b08c0eafcce1 (HEAD -&amp;gt; master)
Author: Jacky Efendi &amp;lt;[not-a-real@email.com](mailto:not-a-real@email.com)&amp;gt;
Date: Sun Oct 20 15:45:19 2019 +0700

chore: Added dummy.txt file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I hope now you get the idea of what we are going to do with these commands; let’s get back to coding!&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing the Changelog Generator (Continued)
&lt;/h3&gt;

&lt;p&gt;In the first part of our code, we now want to run git describe --long to get the latest tag, and only run git log from that tag until our current HEAD.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the last part of our code, we want to now automatically update the version number in the package.json file, create a commit, and tag that commit as the new version:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now, let’s commit our new changelog generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "feature: Implemented versioning for the changelog generator"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And let’s run the script again to generate another changelog:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9UVKguSo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A68TJKmn1IW2pIkdcDlQI6Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9UVKguSo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A68TJKmn1IW2pIkdcDlQI6Q.png" alt=""&gt;&lt;/a&gt;It works!&lt;/p&gt;

&lt;p&gt;Now, we have a fully functional changelog generator with support for versioning as well.&lt;/p&gt;

&lt;p&gt;To see if this is really working, let’s put some text into the dummy.txt file and commit it. Then, we’ll run the script again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y1sCLhVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbzV9qVZSuQF1Pkw2dDG9Rw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y1sCLhVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AbzV9qVZSuQF1Pkw2dDG9Rw.png" alt=""&gt;&lt;/a&gt;Yep, everything still work!&lt;/p&gt;

&lt;p&gt;Now you can just push all the tags to your remote repository so that they appear there as well. Simply run git push --tags to do so. In GitHub web, you can see the list of tags on the &lt;a href="https://github.com/jackyef/changelog-generator/tags"&gt;tags page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;We basically only needed git log, git describe, and git tag combined with some scripting to make this work. This is actually very similar to what tools like conventional-changelog do under the hood to give you that simple generated changelog. Of course, our generator is &lt;em&gt;very&lt;/em&gt; simple and definitely doesn’t handle as many cases as conventional-changelog does, but the core idea is similar. By enforcing a specific format of writing the commit message, we can automate changelog generation.&lt;/p&gt;

&lt;p&gt;When handling monorepo though, things get more difficult. lerna, a tool to manage a monorepo, has its own scripts, combined with conventional-changelog to handle monorepo uses cases. If you are curious and want to learn more, try improving on this generator to handle monorepo as well. I am sure you will learn much more in the process!&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging"&gt;Git tags&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-log#Documentation/git-log.txt---formatltformatgt"&gt;Git log documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-describe"&gt;Git describe documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/conventional-changelog/conventional-changelog"&gt;conventional-changelog repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>programming</category>
      <category>javascript</category>
      <category>changelog</category>
      <category>git</category>
    </item>
    <item>
      <title>WebAssembly — Is it as scary as it sounds?</title>
      <dc:creator>Jacky Efendi</dc:creator>
      <pubDate>Tue, 16 Jul 2019 10:10:50 +0000</pubDate>
      <link>https://dev.to/jackyef/webassembly-is-it-as-scary-as-it-sounds-31g7</link>
      <guid>https://dev.to/jackyef/webassembly-is-it-as-scary-as-it-sounds-31g7</guid>
      <description>&lt;h3&gt;
  
  
  WebAssembly — Is it as scary as it sounds? 😱
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKoFqaWev5QQ_CjhzAojv4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKoFqaWev5QQ_CjhzAojv4g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebAssembly (&lt;em&gt;Wasm&lt;/em&gt;)&lt;/strong&gt; has been around for more than 2 years. It is still a relatively new piece of technology. For some reason, something about it always feels scary to me. Maybe because it has “ &lt;strong&gt;&lt;em&gt;Assembly”&lt;/em&gt;&lt;/strong&gt; written on its name? Or maybe simply picturing having to code in a language that is very different compared to JavaScript already stroke fear into me? Have I grown very attached to the quirks and features of JavaScript that the thought of NOT writing code in JavaScript just seems so unappetising? Whatever it was, the curiosity in me can’t stand not knowing it. After watching the &lt;a href="https://www.youtube.com/watch?v=njt-Qzw0mVY" rel="noopener noreferrer"&gt;talk&lt;/a&gt; by &lt;a href="https://medium.com/u/2d30b2439b4b" rel="noopener noreferrer"&gt;Surma&lt;/a&gt; on this year I/O, I finally brought myself to try to learn WebAssembly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A3D7N8Qr7UE0BGj7D-8ppMQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A3D7N8Qr7UE0BGj7D-8ppMQ.png"&gt;&lt;/a&gt;The face JavaScript developers make when trying to learn C++. (Pictures taken from &lt;a href="https://medium.com/u/2d30b2439b4b" rel="noopener noreferrer"&gt;Surma&lt;/a&gt;’s talk)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;What is WebAssembly anyway? Why does it matter?&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;[WebAssembly] provides a way to run code written in multiple languages on the web at near native speed, with client apps running on the web that previously couldn’t have done so. — &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, WebAssembly allows us to compile a code written in some languages like C, Rust, etc. (&lt;a href="https://github.com/appcypher/awesome-wasm-langs" rel="noopener noreferrer"&gt;a complete list of languages can be found here&lt;/a&gt;) to a &lt;em&gt;.wasm&lt;/em&gt; file and then run it on the browser. It is incredible in term of opening all new kinds of possibilities for the web platform. If you have tried &lt;a href="https://unity.com/" rel="noopener noreferrer"&gt;Unity&lt;/a&gt; to build games before, you might be familiar with this picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A3zDCsIwsZU6Tm7VmZT0oDg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A3zDCsIwsZU6Tm7VmZT0oDg.png"&gt;&lt;/a&gt;The Unity game: Tanks!&lt;/p&gt;

&lt;p&gt;It is a sample 3D game made with unity, ported to the browser with the help of WebAssembly! The crazy thing is: it’s not sluggish to play! You can try it out yourself &lt;a href="https://wasm.bootcss.com/demo/Tanks/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Another story is AutoCAD. AutoCAD was ported to the web as well. You can watch &lt;a href="https://youtu.be/BnYq7JapeDA?t=1612" rel="noopener noreferrer"&gt;this video&lt;/a&gt; to know more about it. WebAssembly isn’t magic. It won’t automatically take your existing program written in C++ and then compile it and it will run in the browser. What WebAssembly allows is for us to reuse code from other languages, and run it on the browser at near native speed!&lt;/p&gt;

&lt;h4&gt;
  
  
  I can see its benefits, but do I need to learn it though?
&lt;/h4&gt;

&lt;p&gt;If your web app does not do heavy computations, but only do light tasks such as rendering the UI, making request to APIs, etc. then you probably don’t need WebAssembly. WebAssembly allows us as web developer to achieve things we previously can’t (or at least not feasibly) do with just JavaScript. It acts as a complement to JavaScript instead of a replacement for it. With that being said though, while you might not use it, it is always beneficial to have learned it and tried it out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Foreword
&lt;/h3&gt;

&lt;p&gt;In this article, we will use wasm to decode QR code from an image input. We will be using Rust and &lt;a href="https://rustwasm.github.io/docs/wasm-bindgen/" rel="noopener noreferrer"&gt;wasm-bindgen&lt;/a&gt; to help us in doing this. The final result Rust &lt;em&gt;Crate&lt;/em&gt; can be seen in the following repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jackyef/rqrr-wasm/tree/master/rust-src" rel="noopener noreferrer"&gt;jackyef/rqrr-wasm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Be warned though, I am by no means an expert in WebAssembly and/or Rust. My experience in software engineering mostly consists of web development and writing JavaScript. This basically means what I am doing in this article might not be a good practice, and some of it maybe not technically accurate; but it is a genuine learning journey of a guy that is new to this environment. Hopefully, you will find this useful in a way or another!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Setting up&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;First, we will need to install Rust. Just follow &lt;a href="https://doc.rust-lang.org/book/ch01-01-installation.html" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to do it. Once done with that, we will add wasm as a compilation target to the Rust compiler. We do it by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rustup target add wasm32-unknown-unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, we should install the &lt;code&gt;wasm-bindgen-cli&lt;/code&gt; because we will be using it later. We will install it using cargo. It should already be installed along with Rust. Think of it like npm, but for Rust. Run the following command to install wasm-bindgen-cli.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install wasm-bindgen-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That’s all we need for now! Before we start, let me give you an overview of what we are going to do.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a function in Rust that can decode QR code&lt;/li&gt;
&lt;li&gt;Compile the Rust code to wasm&lt;/li&gt;
&lt;li&gt;Try using the wasm file in a simple HTML + JS webpage 🎉&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Writing code in Rust
&lt;/h3&gt;

&lt;p&gt;If you are familiar with Node, usually we start a project by running &lt;code&gt;npm init&lt;/code&gt;. In Rust, we do &lt;code&gt;cargo new hello_world&lt;/code&gt; instead. This will create a directory named hello_world with some files pre-made for us. In Rust, this project is called a package. We can import third-party &lt;em&gt;crates&lt;/em&gt; as well, just like in Node we can import third-party modules. Now, let’s take a look at the &lt;code&gt;Cargo.toml&lt;/code&gt; file. Yours probably looks a bit empty right now, but it’s okay. Just modify it to follow the following snippet.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;You might see that this file contains the information of this package, and its dependencies. This file is much like a package.json file, it is the &lt;em&gt;manifest&lt;/em&gt; of the package. The important thing here is that in [lib] section, we are defining the crate-type as ["cdylib"]. This is required when we are targeting Wasm. Also, we are not going to write a QR decoder ourselves, so we will be using third-party crate. We will use &lt;a href="https://docs.rs/rqrr/0.2.0/rqrr/" rel="noopener noreferrer"&gt;rqrr&lt;/a&gt; as the QR decoder. To create an image that will be fed to the decoder, we will use the &lt;a href="https://docs.rs/image/0.21.2/image/" rel="noopener noreferrer"&gt;image&lt;/a&gt; crate, and we will also use &lt;a href="https://docs.rs/wasm-bindgen/0.2.48/wasm_bindgen/" rel="noopener noreferrer"&gt;wasm-bindgen&lt;/a&gt; to help provide &lt;em&gt;“Rust-to-JavaScript”&lt;/em&gt; bindings for us.&lt;/p&gt;

&lt;p&gt;Now, rename &lt;code&gt;src/main.rs&lt;/code&gt; to &lt;code&gt;src/lib.rs&lt;/code&gt; and write the following code in it. lib.rs is the entry point of our package when we compile it to wasm later.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;I am not very familiar with Rust, but I will try my best to explain. The &lt;code&gt;extern crate&lt;/code&gt; and &lt;code&gt;use&lt;/code&gt; statement is used to import the crates we will use, in this case, they are &lt;code&gt;wasm_bindgen&lt;/code&gt;, &lt;code&gt;rqrr&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, we create a public function using the &lt;code&gt;pub fn&lt;/code&gt; keyword, named &lt;code&gt;decode_qr&lt;/code&gt;. This function accepts an array of unsigned 8-bit integer named &lt;em&gt;bytes&lt;/em&gt; (&lt;code&gt;bytes:&amp;amp;[u8]&lt;/code&gt;) representing the image data. It will decode the image and return a String. The &lt;code&gt;#[wasm_bindgen]&lt;/code&gt; attribute tells &lt;code&gt;wasm-bindgen&lt;/code&gt; that we want this function to be exposed to our JavaScript when we use it. This information is used by &lt;code&gt;wasm-bindgen&lt;/code&gt; to create appropriate bindings for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[wasm_bindgen]
pub fn decode_qr(bytes: &amp;amp;[u8]) -&amp;gt; String {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We then create an image from this array, using the load_from_memory method provided by image crate. Since this operation can fail, we use the match keyword, and handle cases when the method returns Ok and Err results. On error, we will just return the string &lt;code&gt;“[Error] Failed when trying to load image”&lt;/code&gt; to JavaScript side.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let img = match image::load_from_memory(&amp;amp;bytes) {
 Ok(v) =&amp;gt; v,
 Err(_e) =&amp;gt; return format!("{}", "[Error] Failed when trying to load image"),
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, we convert this image to a grayscale image before feeding it to &lt;code&gt;rqrr&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let img = img.to_luma();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Note: You might be thinking: “Where do all these methods name come from?”. All of these methods along with other information can be found in the crate documentation pages. I have linked to the documentation pages above, but I will provide it again here in case you missed it.&lt;/em&gt; &lt;a href="https://docs.rs/rqrr/0.2.0/rqrr/" rel="noopener noreferrer"&gt;&lt;em&gt;rqrr docs&lt;/em&gt;&lt;/a&gt;&lt;em&gt;;&lt;/em&gt; &lt;a href="https://docs.rs/image/0.21.2/image/" rel="noopener noreferrer"&gt;&lt;em&gt;image docs&lt;/em&gt;&lt;/a&gt;&lt;em&gt;;&lt;/em&gt; &lt;a href="https://docs.rs/crate/wasm-bindgen/0.2.8" rel="noopener noreferrer"&gt;&lt;em&gt;wasm_bindgen docs&lt;/em&gt;&lt;/a&gt;&lt;em&gt;;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Moving on. We then prepare the image and then feed it to &lt;code&gt;rqrr&lt;/code&gt;, along with the case handling as well. Finally, we return the String to JavaScript side.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Prepare for detection 
let mut img = rqrr::PreparedImage::prepare(img);

// Search for grids, without decoding 
let grids = img.detect_grids(); 

if grids.len() != 1 { 
 return format!("{}", "[Error] No QR code detected in image") }

// Decode the grid 
let (_meta, content) = match grids[0].decode() {
 Ok(v) =&amp;gt; v,
 Err(_e) =&amp;gt; return format!("{}", "[Error] Failed decoding the image"),
};

return format!("{}", content);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Compiling to Wasm
&lt;/h3&gt;

&lt;p&gt;Now that we have our Rust code, we can compile it to wasm easily using the following command.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo build --target wasm32-unknown-unknown --release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will generate a wasm file in &lt;code&gt;target/wasm32-unknown-unknown/release&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F485%2F1%2A9k1yhri_k4azV91GlZKVmA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F485%2F1%2A9k1yhri_k4azV91GlZKVmA.png"&gt;&lt;/a&gt;We generated our first .wasm file! 🎉&lt;/p&gt;

&lt;p&gt;Note that the name of the file is &lt;code&gt;qr_rust.wasm&lt;/code&gt;. This is because the name of my package is &lt;code&gt;qr-rust&lt;/code&gt;, so the output file is named accordingly.&lt;/p&gt;

&lt;p&gt;We are not done though! Since we are using &lt;code&gt;wasm-bindgen&lt;/code&gt;, we need to run &lt;code&gt;wasm-bindgen&lt;/code&gt; against this wasm file to generate another wasm file with a JavaScript file containing the bindings needed to help us use the wasm file easily! Run the following command to do this.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm-bindgen target/wasm32-unknown-unknown/release/qr_rust.wasm --out-dir ./dist --no-modules --no-typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should now see 2 new files in the dist directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F224%2F1%2AiznfL6STxbAPlVb8FE6K_A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F224%2F1%2AiznfL6STxbAPlVb8FE6K_A.png"&gt;&lt;/a&gt;The output files after using wasm-bindgen cli to create bindings&lt;/p&gt;

&lt;p&gt;If you try to look inside the .js file, you will see a bunch of codes that is generated by &lt;code&gt;wasm-bindgen&lt;/code&gt; so we can easily use the wasm module. 2 notable things that it does for us is that it helps us instantiate the wasm module in the &lt;code&gt;init()&lt;/code&gt; function:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;and it provides the necessary stuffs needed to pass data between JavaScript and Wasm:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If we are not using &lt;code&gt;wasm-bindgen&lt;/code&gt;, we would have to write these stuffs ourselves.&lt;/p&gt;

&lt;p&gt;And now…&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s try using it!
&lt;/h3&gt;

&lt;p&gt;First, let’s create a simple HTML file that includes the JavaScript bindings generated by &lt;code&gt;wasm-bindgen&lt;/code&gt;. The bindings have to be executed before we can do anything with the wasm module. Let’s create this index.html file in the &lt;code&gt;./dist&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
 &amp;lt;!-- the javascript bindings --&amp;gt;
 &amp;lt;script src="qr_rust.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The bindings create a &lt;code&gt;wasm_bindgen&lt;/code&gt; variable in the global scope. Which we can use to load our wasm module.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
 &amp;lt;!-- the javascript bindings --&amp;gt;
 &amp;lt;script src="qr_rust.js"&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script&amp;gt;
 wasm_bindgen("qr_rust_bg.wasm")
 .then(() =&amp;gt; {
 console.log('it is loaded!');
 })
 .catch(console.error);
 &amp;lt;/script&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, let’s try serving this HTML file locally and see what happens. The easiest way to do it would be to use &lt;code&gt;http-server&lt;/code&gt; npm module and serve our &lt;code&gt;./dist&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install http-server -g
http-server ./dist -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Open the URL, if everything is correct, you should see It is loaded! in the browser console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AYz0ietXZ1zROg0mP7DwLpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AYz0ietXZ1zROg0mP7DwLpw.png"&gt;&lt;/a&gt;We loaded our wasm module on the browser! 🎉&lt;/p&gt;

&lt;p&gt;The function that we wrote in Rust, can be accessed from the global wasm_bindgen variable.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { decode_qr } = wasm_bindgen;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At this point, we can just pass an array of unsigned 8-bit integer to the function and log the output. Here, I am passing &lt;code&gt;new Uint8Array([1,2,3,4,5]);&lt;/code&gt; to the function.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
 &amp;lt;!-- the javascript bindings --&amp;gt;
 &amp;lt;script src="qr_rust.js"&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script&amp;gt;
 wasm_bindgen('qr_rust_bg.wasm')
 .then(() =&amp;gt; {
 console.log('it is loaded!');

const { decode_qr } = wasm_bindgen;
 const output = decode_qr(new Uint8Array([1,2,3,4,5]));
 console.log("output of decode_qr:", output);
 })
 .catch(console.error);
 &amp;lt;/script&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F519%2F1%2ATJugIUHLU7Ck35FVX593bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F519%2F1%2ATJugIUHLU7Ck35FVX593bg.png"&gt;&lt;/a&gt;It failed!&lt;/p&gt;

&lt;p&gt;Apparently, it fails trying to load the image. This is expected because we are just passing a random array that is not actually representing an image data. Let’s create a &lt;code&gt;&amp;lt;video /&amp;gt;&lt;/code&gt; element from which we will get the image data from.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;video id="video" autoplay&amp;gt;&amp;lt;/video&amp;gt;

// some other stuffs here

&amp;lt;script&amp;gt;
// other scripts

// inside wasm_bindgen().then()
 const video = document.getElementById('video');
 navigator.mediaDevices.getUserMedia({ video: true })
 .then(stream =&amp;gt; {
 video.srcObject = stream;
 });

&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you refresh the browser, your browser should be asking permission to use the camera now. Allow it, and you should see your camera feed in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F703%2F1%2AFSFAhsvkFwLo1QSNzPUafA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F703%2F1%2AFSFAhsvkFwLo1QSNzPUafA.png"&gt;&lt;/a&gt;Me, holding a QR code image in front of the webcam&lt;/p&gt;

&lt;p&gt;Next, we want to be able to get the current frame of the video, get the image data as an array of unsigned 8-bit integers, and send it to the decode_qr() function. We will do this with the help of &lt;code&gt;canvas&lt;/code&gt; and &lt;code&gt;FileReader&lt;/code&gt;. Here is a &lt;code&gt;captureImage&lt;/code&gt; function that will do just that.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Now, we just need to periodically call this function. We can simply do this with setInterval. We will start off the interval after the video stream is created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;navigator.mediaDevices.getUserMedia({ video: true })
 .then(stream =&amp;gt; {
 video.srcObject = stream;

setInterval(captureImage, 300);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So, our final HTML file should look like this.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Refresh your browser, time to try it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2As7bcO3XFUDd35gApqD9Kig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2As7bcO3XFUDd35gApqD9Kig.png"&gt;&lt;/a&gt;It works! The QR code says “&lt;a href="http://en.m.wikipedia.org%E2%80%9D" rel="noopener noreferrer"&gt;http://en.m.wikipedia.org”&lt;/a&gt; 🎉&lt;/p&gt;

&lt;p&gt;Sometimes, you might see an error that says “unreachable code”. I haven’t figured out why that happens yet. If you do know the cause, please let me know!&lt;/p&gt;

&lt;h3&gt;
  
  
  What you can try to do next
&lt;/h3&gt;

&lt;p&gt;We have taken a functioning QR decoder written in Rust, compile it to WebAssembly and use it in the browser with the help of &lt;code&gt;wasm-bindgen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, if you look at the network requests in devtools, you would see that the size of this wasm file is HUGE!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F739%2F1%2A_W0QWawQhnEf0526rJRMiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F739%2F1%2A_W0QWawQhnEf0526rJRMiw.png"&gt;&lt;/a&gt;736 KB for a QR decoder!?&lt;/p&gt;

&lt;p&gt;Note that we haven’t do any compression and optimisation. You can try looking up wasm-opt to optimise the size. &lt;a href="https://rustwasm.github.io/docs/wasm-bindgen/examples/add.html" rel="noopener noreferrer"&gt;This guide&lt;/a&gt; will help you with that. Then, you can compress it down with any compression algorithm you want, a common one is gzip. See how small you can get the wasm file size down to. I am currently at 264 KB gzipped!&lt;/p&gt;

&lt;p&gt;Next, you can try publishing your creation as an npm module so other people can use it easily. I have done this exercise myself. If you want to take a look at my implementation, you can check out my repository below. It contains mostly the same code that I included in this writing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jackyef/rqrr-wasm" rel="noopener noreferrer"&gt;jackyef/rqrr-wasm&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;So, is WebAssembly scary? For me, the answer is no. The reason why it seemed so scary at first because it was a mysterious piece of technology that I was very unfamiliar with. As a guy who mostly coded in JavaScript, it was a bit odd to code in Rust. After reading and watching stuffs about WebAssembly, I could no longer ignore it and decided I had to get over my fear of WebAssembly; and apparently, a good way to get over the fear of it is to actually dive into it.&lt;/p&gt;

&lt;p&gt;Note that you don’t even have to create your own Wasm! There is an increasing number of Wasm module created by other people being published to npm. We can just consume these modules in our projects. The purpose of the exercise we did is to get to know WebAssembly better. In practice though, we probably might not have to do that. But, if one day you need to, at least you have an overview of how it works already.&lt;/p&gt;

&lt;p&gt;WebAssembly opens up a whole lot of possibilities for the web platform, especially for tasks that were too heavy to do with just JavaScript. Your use cases might not need WebAssembly. For example, our QR decoder (after some optimisations) is 264 KB big. There is &lt;a href="https://github.com/jackyef/rqrr-wasm" rel="noopener noreferrer"&gt;this&lt;/a&gt; QR scanner written in JavaScript that is only ~12.4 KB gzipped. Depending on your use case, you could argue that even with the performance advantage, the WebAssembly solution is overkill for this purpose and you could be right. The point is, at the end of the day, tools are just tools; and WebAssembly is a great addition to our toolbox. Whether it makes sense to use the tool will be decided by us, the builder.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can learn more about WebAssembly by watching one of the talk at 2019’s Google I/O&lt;/em&gt; &lt;a href="https://www.youtube.com/watch?v=njt-Qzw0mVY" rel="noopener noreferrer"&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. You can also play around with it in the online IDE:&lt;/em&gt; &lt;a href="https://webassembly.studio/" rel="noopener noreferrer"&gt;&lt;em&gt;webassembly.studio&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>webassembly</category>
    </item>
  </channel>
</rss>
