<?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: Owen Kelly</title>
    <description>The latest articles on DEV Community by Owen Kelly (@ojkelly).</description>
    <link>https://dev.to/ojkelly</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%2F77382%2Fcfd8550b-2a35-4318-bfff-d826fc1c6c88.jpeg</url>
      <title>DEV Community: Owen Kelly</title>
      <link>https://dev.to/ojkelly</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ojkelly"/>
    <language>en</language>
    <item>
      <title>yarn.BUILD: a plugin to run fast parallel builds with yarn v2</title>
      <dc:creator>Owen Kelly</dc:creator>
      <pubDate>Sun, 22 Nov 2020 12:00:01 +0000</pubDate>
      <link>https://dev.to/ojkelly/introducing-yarn-build-14fo</link>
      <guid>https://dev.to/ojkelly/introducing-yarn-build-14fo</guid>
      <description>&lt;p&gt;TLDR -&amp;gt; instructions at &lt;a href="https://yarn.build"&gt;yarn.build&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;Tooling in the Javascript (and Typescript) ecosystem is generally pretty good (no really). But for the longest time on piece of a puzzle I keep facing has been missing.&lt;/p&gt;

&lt;p&gt;Most of what I build ends up being applications with more than one deployable artifact. Sometimes they're just a front-end client and a simple server. Other times it is that plus a GraphQL schema, multiple Lambdas, and so on.&lt;/p&gt;

&lt;p&gt;Since Lerna appeared both the idea and tooling for Javascript monorepos started to take off. For me, it wasn't until Yarn that linking between local packages became a thing - so say, your front-end client and server packages could depend&lt;br&gt;
on your GraphQL schema package. Yarn v2 took this to another level and added a degree of stability and correctness that make this even more enticing.&lt;/p&gt;

&lt;p&gt;But among all of that, building the packages was still a problem. Namely, if a local package depended on another local package being built, you need to orchestrate that somehow. And as much as I tried, it always ended up feeling less than ideal - and certainly not easily repeatable.&lt;/p&gt;

&lt;p&gt;In my dabbling into other langauges and tooling, I tried using Bazel. In some ways it's great. I used it to great success with a Golang monorepo with multiple build and testing artifacts.&lt;/p&gt;

&lt;p&gt;But for Javascript, well, it's not pretty. Javascript's package ecosystem is reasonably mature at this point. Sure it still has it's flaws, though work is continually being done to address them. (Yarn v2 vendors your &lt;code&gt;node_modules&lt;/code&gt; as zip files, for example.)&lt;/p&gt;

&lt;p&gt;Javascript and Bazel mix reasonably well. But Javascript and NPM or Yarn don't. Having two systems both trying to own dependency management is just painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yarn v2
&lt;/h2&gt;

&lt;p&gt;At the start of 2020 I started playing around with Yarn v2.&lt;br&gt;
&lt;a href="https://yarnpkg.com/features/pnp"&gt;Plug'n'Play&lt;/a&gt; and the &lt;code&gt;zipfs&lt;/code&gt; approach to &lt;a href="https://yarnpkg.com/features/offline-cache"&gt;vendoring dependencies&lt;/a&gt; had me&lt;br&gt;
intrigued immediately. Both are areas I've found our tooling lacking.&lt;/p&gt;

&lt;p&gt;In practice, at the start of 2020 support was growing but still limited. Enough things worked to convince me this is a workable approach though.&lt;/p&gt;

&lt;p&gt;And then I discovered that Yarn v2 was far more hackable than v1. Not only that, with the new focus on correctness and reproducibility the only thing missing to make a Bazel for Javascript was the build tool itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;At a high level the plugin is pretty straight forward. Yarn's already built the dependency graph. We just need to know where to start from on that graph. That's also relatively easy. If you're in the directory of a package, well we can work out which package it is. If not, we can build everything.&lt;/p&gt;

&lt;p&gt;Once we know what we need to build, we have a look at anything it depends on, and if they depend on anything. And so on. Once we know that, we can build a plan for how to build it all with as much parallelisation as you have threads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Feature
&lt;/h2&gt;

&lt;p&gt;Having worked all of that out, there was one last feature I really wanted to include. And to be honest, it's the main thing I've wanted from the start.&lt;/p&gt;

&lt;p&gt;I wanted a command that will create a zip file ready for AWS Lambda, Kubernetes or Docker.&lt;/p&gt;

&lt;p&gt;Now I hear what you're saying "what about the Serverless&lt;br&gt;
framework?". While I know it's a valuable tool, and plenty of us use it with much success. It's never fit my requirements. Any abstraction over Cloudformation that obscures the actual Cloudformation templates always ended up getting in my way.&lt;/p&gt;

&lt;p&gt;Yarn PnP makes this a bit hard. Locally linked packages make this really hard. And vendoring &lt;code&gt;node_modules&lt;/code&gt; makes this near impossible.&lt;/p&gt;

&lt;p&gt;Especially in a monorepo where your dependencies are shared and hoisted up. Meaning you can't just copy the adjacent &lt;code&gt;node_modules&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;We need something smarter.&lt;/p&gt;

&lt;p&gt;Much smarter.&lt;/p&gt;

&lt;p&gt;Once again though, we have access to the dependency graph we've already defined for Yarn. Combining this, with the &lt;code&gt;zipfs&lt;/code&gt; tooling in Yarn v2, it was not too much extra work to get this going.&lt;/p&gt;

&lt;p&gt;Now, in a package running &lt;code&gt;yarn bundle&lt;/code&gt; copies the whole workspace (so likely you repository) into a temporary folder. Then, using Yarn's dependency graph, we chuck out everything we don't need. Delete the local packages that aren't used,&lt;br&gt;
and the vendored packages that aren't used.&lt;/p&gt;

&lt;p&gt;At this point we have a zip file that looks like your repo, with a bunch of stuff chucked out. Which is great, but there's two remaining issues to tackle.&lt;/p&gt;

&lt;p&gt;The first, Yarn PnP. It's great, and it means our zip file is faster to work with and smaller than a &lt;code&gt;node_modules&lt;/code&gt; directory. But, we need to run everything via the &lt;code&gt;pnp.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The second, is that as we're recreating the whole workspace in the zip file, and not just your package, you need to know exactly where it is to specify your entrypoint or index file.&lt;/p&gt;

&lt;p&gt;The solution was pretty simple. Drop a file called &lt;code&gt;entrypoint.js&lt;/code&gt; at the root of the zip file. Have it load &lt;code&gt;pnp.js&lt;/code&gt; first, then load your file, referenced in&lt;br&gt;
&lt;code&gt;main&lt;/code&gt; in your &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And just like that, &lt;code&gt;yarn bundle&lt;/code&gt; can create a zip file ready to run in Lambda et al.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started
&lt;/h2&gt;

&lt;p&gt;This all sounds great, but how do you actually use it?&lt;/p&gt;

&lt;p&gt;First, you have to be using Yarn v2. If you're not already here's a great &lt;a href="https://yarnpkg.com/getting-started"&gt;getting started guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next install the plugin by running the following command in your Yarn workspace:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn plugin import https://yarn.build/latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command downloads and installs (or updates) the &lt;a href="https://yarn.build"&gt;yarn.build&lt;/a&gt; plugin to the latest version. &lt;/p&gt;

&lt;p&gt;The plugin is downloaded and vendored in you repository. It's not re-downloaded on every build.&lt;/p&gt;

&lt;p&gt;Currently there's two commands you can run.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn build&lt;/code&gt; which will run the &lt;code&gt;build&lt;/code&gt; script defined in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;yarn bundle&lt;/code&gt; which will create the zip file described above, ready for Lambda et al.&lt;/p&gt;

&lt;p&gt;There's still plenty of work to be done on this plugin, but in it's current state it's ready to start being used.&lt;/p&gt;

&lt;p&gt;You can find the source here &lt;a href="https://github.com/ojkelly/yarn.build"&gt;github.com/ojkelly/yarn.build&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And the site is at &lt;a href="https://yarn.build"&gt;yarn.build&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think here or on twitter &lt;a href="https://twitter.com/ojkelly"&gt;@ojkelly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@sl33vo?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Danny Sleeuwenhoek&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>devops</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The Four Layers to Great Documentation</title>
      <dc:creator>Owen Kelly</dc:creator>
      <pubDate>Thu, 07 Jun 2018 13:05:58 +0000</pubDate>
      <link>https://dev.to/ojkelly/the-four-layers-to-great-documentation-dj7</link>
      <guid>https://dev.to/ojkelly/the-four-layers-to-great-documentation-dj7</guid>
      <description>&lt;p&gt;When I started to publish some open source projects, I did a deep dive into how to document them. This is the most useful method I’ve found.&lt;/p&gt;

&lt;p&gt;Good documentation requires four layers, each building on the previous layer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;Guides&lt;/li&gt;
&lt;li&gt;Concepts&lt;/li&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best way to write these is to start from the bottom (API) at work your way up to the top (Getting Started). Incidentally, readers of your documentation will start from the top, and only occasionally find their way to the bottom. Even then, starting writing from the bottom up helps to better inform the top layers.&lt;/p&gt;

&lt;h2&gt;
  
  
  API
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This is the only section of your code that can be auto-generated.&lt;br&gt;
Documentation is written exclusively for humans, and that usually means a&lt;br&gt;
human needs to write it. You can auto-generate your API docs from your source&lt;br&gt;
code, if you have commented it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This should be comprehensive documentation of how to use the API of the project, typically generated from the source code.&lt;/p&gt;

&lt;p&gt;You should be documenting your code, so that when you come back to it in 12 months you can understand it again. Be selfish, and kind to your future self, let them know what you did and why. You will not remember. (This side benefit here, is everyone else can understand too).&lt;/p&gt;

&lt;h2&gt;
  
  
  Concepts
&lt;/h2&gt;

&lt;p&gt;What are the fundamental building blocks for this project? Try to break the project up into pieces, and write a detailed explanation of each one.&lt;/p&gt;

&lt;p&gt;The goal here is to explain the building blocks of your project. Expect anyone who will implement your project to read through this section. You want this to be detailed and thorough. You don’t need an essay on each, a few hundred words and a diagram might be enough.&lt;/p&gt;

&lt;p&gt;If you need to write a long page for a concept, be kind to the reader, and try to create sections for easy reference. While some will read it from top to bottom, it’s more likely it will be skimmed for the most relevant part for the reader at that time. Some headings and a table of contents is all you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guides
&lt;/h2&gt;

&lt;p&gt;A guide or tutorial, is the ideal way to explain how to use your project to solve a specific use case.&lt;/p&gt;

&lt;p&gt;They should be written with the end use in mind, considering their use case and knowledge. It’s better to over explain, than not. Something may be simple and obvious to you, but unheard of to your user.&lt;/p&gt;

&lt;p&gt;Think about why you started the project in the first place, and make a list of the use cases you wanted to solve. It may help to write a small user story for each, something like: “As a project maintainer, I would like to know how to write good documentation, so that I can get more users of my project”. The typical format to produce a user story is: “As a [role], I can [feature] so that [reason]”.&lt;/p&gt;

&lt;p&gt;In that last paragraph, I did two things. First, I said making a list of user stories will help with working out what guides to write, but then I gave an example of a user story, and the template to write them. You could have searched to find out what a user story is, but by explaining it right there I’ve not only saved you a bit of time — I’ve removed the ambiguity of what we’re talking about. A user story may mean something slightly different to you.&lt;/p&gt;

&lt;p&gt;But back to guides. You want to have at least 3 to 5 to explain how to use your project. It could be how to use it on each particular operating system, or how to integrate with the 3 most popular frameworks.&lt;/p&gt;

&lt;p&gt;Or, how to integrate with a focus on a particular concept from the previous section.&lt;/p&gt;

&lt;p&gt;Most likely you’ll have 1-3 guides when you publish your project. As issues and frequently asked questions appear, turn these into guides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;This is the single most important section you will write, and does not consist of a single ‘Getting Started’ page.&lt;/p&gt;

&lt;p&gt;If you’re project is a small library, you may be able to get away with just a Getting Started section. Typically in this scenario, you would only have one main concept, and a set of examples functioning as the Guide section.&lt;/p&gt;

&lt;p&gt;First, work out what your landing pages are. You may have a website, a GitHub readme. You might also have a page on npm, godoc, pypi, or another package manager. Normally all of these except the website will be direct copies of your readme, so lets start with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Readme.md
&lt;/h3&gt;

&lt;p&gt;To start you need to answer the following questions clearly, and concisely:&lt;/p&gt;

&lt;p&gt;What is this project called? What does this project do?&lt;/p&gt;

&lt;p&gt;Then, explain how to get it. Maybe it’s a download via a package manager, or a link to a releases page containing binaries.&lt;/p&gt;

&lt;p&gt;Now, show a simple use case. Here you’re showing the public interface of the project. For many projects the best &lt;em&gt;Getting Started&lt;/em&gt;, is literally showing the implementation code. Don’t show everything, just enough to run it once.&lt;/p&gt;

&lt;p&gt;We’re now in the footer of the readme. It’s nice to add information on how to develop on this project, so information on how to setup a development environment, and examples of how to run the tests should be here.&lt;/p&gt;

&lt;p&gt;It’s strongly recommended to include information about how to contribute to the project, where to raise issues, the process for new features and pull requests.&lt;/p&gt;

&lt;p&gt;You should include information about SemVer if you’re using it. (If you’re not using SemVer, please consider it — your users will thank you).&lt;/p&gt;

&lt;p&gt;Many projects like to acknowledge their major authors and contributors in the footer area too.&lt;/p&gt;

&lt;p&gt;And finally, at the very bottom include a license. This is typically a note of the license type, with a link to a LICENSE.md file. You must include a license, without one people will be wary to use your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Badges
&lt;/h3&gt;

&lt;p&gt;You don’t need them. Although they can be useful to your users. Use your own discretion here, don’t go overboard. They can provide a bit of social proof.&lt;/p&gt;

&lt;h3&gt;
  
  
  Website
&lt;/h3&gt;

&lt;p&gt;If you also have a website (you don’t always need one), your “Getting Started” consists of the front page, and a dedicated getting started page. If you want to include them both on the once page, just ensure theres a link that can take a reader directly to the “Getting Started” section.&lt;/p&gt;

&lt;p&gt;The front page usually covers the same information as the Readme, and is often wrapped in a nice design. Don’t go overboard here, you’re focus is on readability above all else. Sometimes a cool graphic or animation can get a project shared around — but don’t focus on that at the expense of your actual users.&lt;/p&gt;




&lt;p&gt;Documentation is the best marketing tool for your project, and the best indicator of the trustworthiness and maturity. It takes effort to document a project well, but if you want users it’s worth it.&lt;/p&gt;

&lt;p&gt;As an example of this approach to documentation you can look at a project I recently published &lt;a href="http://bunjil.js.org/"&gt;Bunjil&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>marketing</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
