<?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: Jake Patterson</title>
    <description>The latest articles on DEV Community by Jake Patterson (@jake8n).</description>
    <link>https://dev.to/jake8n</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%2F538708%2F2ba1b834-7985-4bf2-bf34-7a9e67e8c981.jpg</url>
      <title>DEV Community: Jake Patterson</title>
      <link>https://dev.to/jake8n</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jake8n"/>
    <language>en</language>
    <item>
      <title>Practising Git hygiene with fixup commits</title>
      <dc:creator>Jake Patterson</dc:creator>
      <pubDate>Sun, 04 Feb 2024 12:01:35 +0000</pubDate>
      <link>https://dev.to/jake8n/practising-git-hygiene-with-fixup-commits-5a4f</link>
      <guid>https://dev.to/jake8n/practising-git-hygiene-with-fixup-commits-5a4f</guid>
      <description>&lt;p&gt;Git takes a long time to become comfortable with. Still now, years after I first used it, I hold my breath doing rebases and cross my fingers there are no conflicts. It is not controversial to say Git is unintuitive, with strangely named commands and a lacking command line interface. Unfortunately, we're stuck with it for the time being...&lt;/p&gt;

&lt;p&gt;"Git hygiene" refers to good organisation of a Git repository and its commit history. Commits act as documentation and are often used to generate release notes, so it is important they describe changes accurately. For me, each commit should represent the project in a working state. I should be able to checkout something from a couple weeks ago and run the project without error. That said, it is common to see the following in pull requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;feat(Button): add size variant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chore: fix linting&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fix: pull request feedback&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fix: failing test&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few problems with the above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Too many commits. In the context of a PR the commits &lt;em&gt;are&lt;/em&gt; useful. The reviewer can understand how and why the branch is changing. Outside of the pull request, though, that information is not useful. Typically, developers will squash commits to address this problem, ensuring the final commit message is appropriate. In itself that presents further problems:

&lt;ul&gt;
&lt;li&gt;What if we want multiple final commits in a pull request? We may have a larger pull requests, with logically separated commits, each of them able to be individually reverted.&lt;/li&gt;
&lt;li&gt;What if the commits themselves are under scrutiny by the code reviewer and/or automation?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If I checkout the first commit linting and tests will fail. Not a problem if the commits are squashed, but if they aren't, our &lt;code&gt;main&lt;/code&gt; branch is polluted with broken commits. Later on, identifying which commit introduced an issue becomes harder.&lt;/li&gt;
&lt;li&gt;With each round of code review further changes will need new commits, likely meaning the commit messages get sloppier and less legible. Following something like &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; is wasted cognitive load when we know we are squashing the commits anyway.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fixup commits offer us an alternative here. Let's start with the commit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;feat(Button): add size variant&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Imagine I open the pull request and an automated workflow tells me there are lint issues. Instead of naming a new commit I can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit --fixup [COMMIT_SHA]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which results in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;feat(Button): add size variant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fixup! feat(Button): add size variant&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When I first saw that I thought it was perfect. It indicates exactly my intentions to the the reader: I want one commit, but I am "fixing" it with further revisions. Now, we could rebase locally and push only a single commit back to the remote branch, but in my experience GitHub doesn't like that. In the case of some feedback being addressed I want to compare the previous state to the new one and I need multiple commits for that.&lt;/p&gt;

&lt;p&gt;Still, we do need to squash the commits before merging since we don't want them ending up on &lt;code&gt;main&lt;/code&gt;. Thankfully, we can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase main -i --autosquash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies all the fixup commits, resulting in one (or more) clean and hygienic commits that are ready to be merged. I do wish GitHub would integrate this functionality into its user interface. Currently that command must be run locally, instead of using the "Rebase and merge" button.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Who manages the package managers?</title>
      <dc:creator>Jake Patterson</dc:creator>
      <pubDate>Sat, 27 Jan 2024 12:13:10 +0000</pubDate>
      <link>https://dev.to/jake8n/who-manages-the-package-managers-4g74</link>
      <guid>https://dev.to/jake8n/who-manages-the-package-managers-4g74</guid>
      <description>&lt;p&gt;The JavaScript ecosystem is notorious for moving quickly. Just a few years ago Yarn (now Yarn Classic) was ubiquitous. Since then, 3 major &lt;code&gt;yarn&lt;/code&gt; versions have been released and new competitors have entered the market. While upgrade paths can be straight forward—with pnpm even providing &lt;code&gt;pnpm upgrade&lt;/code&gt;—the problem of managing package managers arises.&lt;/p&gt;

&lt;p&gt;Consider an organisation with hundreds of JavaScript repositiories. Some have long been abandoned and others have an active development team keen to use the best-in-class tooling. Maybe at a glance it is obvious which flavour of package manager a repository depends on; we may see a &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt; file. However, further inspection is needed to determine which version of NPM or Yarn created those. It is too easy for a developer to end up recreating a lock file after running the wrong command. Not a great experience!&lt;/p&gt;

&lt;p&gt;A better approach is to use a combination of the following tools. Firstly, fnm (Fast Node Manager) is a well established Node version manager. After &lt;a href="https://github.com/Schniz/fnm?tab=readme-ov-file#shell-setup"&gt;setting up your shell environment&lt;/a&gt;, navigating to a project folder is all that is required to detect and switch to the correct Node version, provided a &lt;code&gt;.node-version&lt;/code&gt; file exists. We can take this a step further by adding &lt;code&gt;packageManager&lt;/code&gt; to our &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ "packageManager": "pnpm@8.14.3"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On its own that isn't going to do much. A developer would still need to open &lt;code&gt;package.json&lt;/code&gt; to find the correct package manager to download. We can automate that with Corepack. Corepack is an experimental feature of Node that looks for the &lt;code&gt;packageManager&lt;/code&gt; field and silently downloads the version when running scripts. It also throws an error if the wrong package manager is used in the scope of the project. It is an opt-in feature though, so &lt;code&gt;corepack enable&lt;/code&gt; must be run after Node is installed. Alternatively, fnm can be configured to do that automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- eval "$(fnm env --use-on-cd)"
&lt;/span&gt;&lt;span class="gi"&gt;+ eval "$(fnm env --use-on-cd --corepack-enabled)"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, running any package manager command comes with a guarantee; with the above configuration, &lt;code&gt;pnpm -v&lt;/code&gt; always resolves to 8.14.3 and &lt;code&gt;yarn -v&lt;/code&gt; errors. Note that package managers previously installed globally should be uninstalled first. Without doing that, we won't see the wonderful error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Usage Error: This project is configured to use pnpm&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>4 ways to improve type checking in Vue components</title>
      <dc:creator>Jake Patterson</dc:creator>
      <pubDate>Thu, 31 Dec 2020 01:49:11 +0000</pubDate>
      <link>https://dev.to/jake8n/4-ways-to-improve-type-checking-in-vue-components-3dk</link>
      <guid>https://dev.to/jake8n/4-ways-to-improve-type-checking-in-vue-components-3dk</guid>
      <description>&lt;p&gt;TypeScript is increasingly becoming a go-to when starting new projects. It has proven to catch pesky bugs arising from loosely typed code and ease the refactoring of larger codebases. For that we are eternally grateful 🙌.&lt;/p&gt;

&lt;p&gt;However, when it comes to using TypeScript with Vue there are some pain points. The main culprit being Single File Components, which do not come under full scrutiny by the TypeScript compiler. Type errors within a &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; tag are not detected and can slip through into a production environment. Component property violations, for example, are only detected at run time.&lt;/p&gt;

&lt;p&gt;Here I will outline 4 methods to ensure 100% of your Vue component is type checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://www.npmjs.com/package/vue-jsx-factory"&gt;Vue JSX Factory&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The first two recommendations ditch Single File Components in favour of JSX.&lt;/p&gt;

&lt;p&gt;Ultimately &lt;code&gt;.vue&lt;/code&gt; files are a proprietary syntax known only by Vue and other community maintained projects. JSX is not a standard either, but in the world of TypeScript is can be considered as such. We can take advantage of that!&lt;/p&gt;

&lt;p&gt;Vue JSX Factory is the only method where by we can directly use &lt;code&gt;tsc&lt;/code&gt; (or esbuild) to compile our code. Babel is an optional enhancement - not a requirement - and so our project setup is very lightweight. In fact, the only necessary package is &lt;code&gt;vue-jsx-factory&lt;/code&gt;. After updating &lt;code&gt;tsconfig.json&lt;/code&gt; to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsxFactory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"j"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;components can be defined using JSX. Importantly, the &lt;code&gt;j&lt;/code&gt; function must be within scope wherever we define components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Header.tsx&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;j&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-jsx-factory&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&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;defineComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue/composition-api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do lose out on some directives (e.g. &lt;code&gt;v-model&lt;/code&gt;), although these could enabled at a later date. Going down this route removes a lot of fluffy dependencies, such as Vue Loader or Vue Jest.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://github.com/vuejs/jsx"&gt;Babel Preset JSX&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;JSX can also be written with the aid of a Babel preset. It is officially supported by the Vue core team and has more features than Vue JSX Factory. Presuming Babel is already integrated in your project, just install the packages and update the Babel configuration:&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 -D @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// babel.config.js&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;presets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue/babel-preset-jsx&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to some Babel magic, the render function is automatically imported in to scope, so no need for a manual import in component files.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://vuejs.github.io/vetur/guide/vti.html"&gt;Vetur Terminal Interface (VTI)&lt;/a&gt; ⚠
&lt;/h2&gt;

&lt;p&gt;An extension to the famous Vetur VS Code plugin and also available as a command line tool, VTI enables type checking on Single File Components. Unfortunately, it is still marked as unstable, although I am excited to see where it is headed! At the time of writing this article it can run via a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx vti &lt;span class="c"&gt;# at project root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. &lt;a href="https://github.com/znck/vue-developer-experience/tree/master/packages/typecheck"&gt;TypeCheck for Vue&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Last but not least, Vue Developer Experience provides us with TypeCheck, another method for checking Single File Components. Currently it runs as a command alongside your build and, like VTI, is still early days; the first public release being 28th December 2020!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using Vue together with TypeScript can at times feel premature. Relying on community maintained dependencies to achieve type safety is risky and in an ideal world avoidable. While there is hope with Vue 3 and Vite, it will take some time for the ecosystem to catch up. In the mean time, those using Vue 2 can find an extra layer of assurance with these additional tools.&lt;/p&gt;

&lt;p&gt;If you would like to get those benefits early, without fully migrating to Vue 3, the Composition API is already available in Vue 2. &lt;code&gt;defineComponent&lt;/code&gt; has massively better type inference than &lt;code&gt;Vue.extend&lt;/code&gt; or the Class Component Syntax (&lt;a href="https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121"&gt;soon to be deprecated&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
