<?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: Renan Paixão</title>
    <description>The latest articles on DEV Community by Renan Paixão (@renanpaixao).</description>
    <link>https://dev.to/renanpaixao</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%2F677606%2Fcf9b93fc-f16d-43dc-9dc5-a6561490f8b8.jpg</url>
      <title>DEV Community: Renan Paixão</title>
      <link>https://dev.to/renanpaixao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/renanpaixao"/>
    <language>en</language>
    <item>
      <title>How To Set up Lefthook to handle git hooks in react applications</title>
      <dc:creator>Renan Paixão</dc:creator>
      <pubDate>Sat, 29 Jun 2024 03:55:54 +0000</pubDate>
      <link>https://dev.to/renanpaixao/how-to-set-up-lefthook-to-handle-git-hooks-in-react-applications-527i</link>
      <guid>https://dev.to/renanpaixao/how-to-set-up-lefthook-to-handle-git-hooks-in-react-applications-527i</guid>
      <description>&lt;h2&gt;
  
  
  First of all, why Lefthook?
&lt;/h2&gt;

&lt;p&gt;I will point some reasons to you choose lefthook when you need to decide a git hooks manager.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Configuration
&lt;/h3&gt;

&lt;p&gt;Lefthook is very straightforward and has a smooth setup, that can be worthy if you want to test if it's what you are looking for. We need a yaml file only, with a bunch of possibilities like docker support, flexible list of files and glob/regexp filters.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Velocity
&lt;/h3&gt;

&lt;p&gt;As Lefhook is written in go, and we can run commands in parallel, that grant for us a faster execution, not being possible in some others git hooks managers.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Environment agnostic
&lt;/h3&gt;

&lt;p&gt;Lefthook is a go binary with wrappers to other languages. So, it gives you the possibility to share your config with teams using different programming languages, from front end to back end for instance.&lt;/p&gt;

&lt;p&gt;I hope that you are already convinced. If are not, take a look how simple is the setup.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup&lt;br&gt;&lt;br&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Installation&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;npm install lefthook --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once installed, a new file named lefthook.yml will be on your project root. You can now add the needed configuration to git hooks.&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Editing config file (lefthook.yml)
&lt;/h3&gt;

&lt;p&gt;Git has a bunch of hooks that you can handle with the lefthook. Here we have a &lt;a href="https://git-scm.com/docs/githooks"&gt;list with all&lt;/a&gt;, so feel free to get exactly what you want. This article will handle the &lt;code&gt;pre-commit&lt;/code&gt; and &lt;code&gt;pre-push&lt;/code&gt; ones, presenting a real example.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;Pre-commit&lt;/strong&gt;&lt;br&gt;
&lt;/h4&gt;

&lt;p&gt;In the lefthook.yml, we can add the git hook name, followed by the commands that will run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pre-commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;eslint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;stage_fixed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;glob&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.{ts,tsx}"&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn lint --fix {staged_files} --quiet&lt;/span&gt; &lt;span class="c1"&gt;# See "yarn lint" as eslint --ext ts,tsx&lt;/span&gt;
    &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vitest related {staged_files} --run --silent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h5&gt;
  
  
  &lt;strong&gt;Step by step&lt;/strong&gt;
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Parallel&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This property will do all commands run in parallel (really?), saving time, mainly in big projects. This is great as in CI/CD as local.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Commands&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we can name all commands needed for the hook. In the example we have the eslint to ensure the code consistency, and test to ensure quality over the app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inside eslint&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;stage_fixed:&lt;/strong&gt; This is related to run git add after fix the files when the command has finished.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;glob:&lt;/strong&gt; Filter the files that will be on {staged_files} using the extension in this case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;run:&lt;/strong&gt; The command.&lt;/li&gt;
&lt;li&gt;{staged_files}: All files being modified at the moment (in the staging area). Note that even the command running with selected extensions (&lt;code&gt;--ext&lt;/code&gt; flag), we still need the glob pattern because we are setting the files directly with staged_files. Eslint command will ignore the flag in this case.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inside test command&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have added the run property only, and we already know what it is, but I want to mention the &lt;code&gt;related&lt;/code&gt; flag from vitest. This allow us to run all tests that import a file (in this case a list of).&lt;/p&gt;

&lt;p&gt;e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// checkout.test.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Checkout&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, if we change the &lt;code&gt;Checkout&lt;/code&gt; component, it will be on our {staged_files} list, and even not changing tests, vitest will look for all tests importing the component and will run each one, like the &lt;code&gt;checkout.test.js&lt;/code&gt; .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;see docs: &lt;a href="https://vitest.dev/guide/cli.html#vitest-related"&gt;vitest related&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Pre-push&lt;/strong&gt;&lt;br&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pre-push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;parallel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn lint . --quiet&lt;/span&gt;
    &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vitest --run --silent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, nothing new here. We are now running all tests before push, and also running the eslint in all files. It is useful for companies that cannot pay for infrastructure to run tests on CI/CD, but still want to have some quality assurance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important notice that if you have something in your staging area that makes the test pass before the push, the tests will run without errors even if the code being pushed is with an error.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h3&gt;
  
  
  Registering hooks
&lt;/h3&gt;



&lt;p&gt;After the config file is done, we can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;lefthook install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It  will do the hooks be registered and run when it's time. Remember to run it whenever you change the lefhook.yml file, or change something related the commands, for instance remove a command from package json that is being used by your hooks.&lt;/p&gt;

&lt;p&gt;After this, it's time to commit and forget it (at least until need to change again).&lt;/p&gt;



&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/evilmartians/lefthook"&gt;Lefthook docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>unittest</category>
      <category>githooks</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
