<?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: Worms David</title>
    <description>The latest articles on DEV Community by Worms David (@wdavidw).</description>
    <link>https://dev.to/wdavidw</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%2F641171%2F2af85d79-21eb-4017-a222-8c58b8fd1b94.jpeg</url>
      <title>DEV Community: Worms David</title>
      <link>https://dev.to/wdavidw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wdavidw"/>
    <language>en</language>
    <item>
      <title>JS monorepos in prod 1: project initialization</title>
      <dc:creator>Worms David</dc:creator>
      <pubDate>Mon, 31 May 2021 21:01:28 +0000</pubDate>
      <link>https://dev.to/adaltas/js-monorepos-in-prod-1-project-initialization-129c</link>
      <guid>https://dev.to/adaltas/js-monorepos-in-prod-1-project-initialization-129c</guid>
      <description>&lt;p&gt;Every project journey begins with the step of initialization. When your overall project is composed of multiple projects, it is tempting to create one Git repository per project. In Node.js, a project translates to a package. However, managing too many closely related repositories is confusing and time-consuming.&lt;/p&gt;

&lt;p&gt;Placing multiple projects inside a single Git repository and using a tool like &lt;a href="https://lerna.js.org/"&gt;Lerna&lt;/a&gt; to facilitate their management worth the effort. This architecture is called a monorepo. It simplifies the versioning and publishing of the components as well as their manipulation and development.&lt;/p&gt;

&lt;p&gt;At Adaltas, we have been developing and maintaining several monorepos for a couple of years. This article is the first one from a serie of five in which we share our best practices. It covers the project initialization using Yarn and Lerna:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part 1: &lt;a href="https://www.adaltas.com/en/2021/01/05/js-monorepos-project-initialization/"&gt;project initialization&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 2: &lt;a href="https://www.adaltas.com/en/2021/01/11/js-monorepos-versioning-publishing/"&gt;versioning and publishing strategies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 3: &lt;a href="https://www.adaltas.com/en/2021/02/02/js-monorepos-commits-changelog/"&gt;commit enforcement and changelog generation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 4: &lt;a href="https://www.adaltas.com/en/2021/02/25/js-monorepos-unit-testing/"&gt;unit testing with Mocha and Should.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 5: &lt;a href="https://www.adaltas.com/en/2021/05/21/js-monorepos-merging-git-repositories/"&gt;merging Git repositories and preserve commit history&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Part 6: CI/CD, continuous testing and deployment with Travis CI&lt;/li&gt;
&lt;li&gt;Part 7: CI/CD, continuous testing and deployment with GitHub Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Starting a new project
&lt;/h2&gt;

&lt;p&gt;The idea for an example project comes from our past work. Over the years, we have accumulated several &lt;a href="https://www.gatsbyjs.com/docs/what-is-a-plugin/"&gt;Gatsby plugins&lt;/a&gt; that have never been published and shared with the open-source community. Those plugins are copy/pasted from one Gatsby website to another, sometimes with bug fixes and enhancements. Since we have multiple copies more or less up-to-dates between each other, older websites don't benefit from those changes. The idea is to centralize the development of those plugins inside a single repository and share them by publishing them on NPM.&lt;/p&gt;

&lt;p&gt;A new project is started from scratch. It is called &lt;code&gt;remark-gatsby-plugins&lt;/code&gt; and is hosted on &lt;a href="https://github.com/adaltas/remark-gatsby-plugins"&gt;GitHub&lt;/a&gt;. This repository is a container for multiple packages that are plugins for &lt;a href="https://www.gatsbyjs.com/"&gt;Gatsby&lt;/a&gt; and &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-transformer-remark/"&gt;&lt;code&gt;gatsby-transformer-remark&lt;/code&gt; plugin&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Repository initialization&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;remark-gatsby-plugins
&lt;span class="nb"&gt;cd &lt;/span&gt;remark-gatsby-plugins
git init
&lt;span class="c"&gt;# Create and commit a new file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# remark and Gatsby plugins by Adaltas"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
git add README.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"docs: project creating"&lt;/span&gt;
&lt;span class="c"&gt;# Define the GitHub remote server&lt;/span&gt;
git remote add origin https://github.com/adaltas/remark-gatsby-plugins.git
&lt;span class="c"&gt;# Push commits to remote&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin master
&lt;span class="c"&gt;# Next push commands will simply be `git push`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commit message is prefixed by &lt;code&gt;docs&lt;/code&gt; and it is not by hazard. This aspect is covered later by the Conventional Commits chapter in the following article &lt;em&gt;commit enforcement and changelog generation&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ignoring files from Git
&lt;/h2&gt;

&lt;p&gt;There are two strategies to choose from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To selectively define the path to be ignored.&lt;/li&gt;
&lt;li&gt;To define global ignore rules and selectively exclude path from those rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I usually choose the latest strategy to ignore all hidden files by default. I start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;CONTENT&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; .gitignore
.*
node_modules
!.gitignore
&lt;/span&gt;&lt;span class="no"&gt;CONTENT
&lt;/span&gt;git add .gitignore
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: ignore hidden files and node modules'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project initialization
&lt;/h2&gt;

&lt;p&gt;I am personally using Yarn instead of NPM. Both package managers are perfectly fine, but I had issues in the past using NPM with monorepos and links. In this setup, Yarn also seems to be the tool of choice across the community. Its native support for monorepos, called workspaces, works well with &lt;a href="https://lerna.js.org/"&gt;Lerna&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To initialize a package with &lt;code&gt;yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn init
yarn init v1.22.5
question name &lt;span class="o"&gt;(&lt;/span&gt;remark-gatsby-plugins&lt;span class="o"&gt;)&lt;/span&gt;: 
question version &lt;span class="o"&gt;(&lt;/span&gt;1.0.0&lt;span class="o"&gt;)&lt;/span&gt;: 0.0.0
question description: A selection of remark and Gatsby plugins developed and used by Adaltas
question entry point &lt;span class="o"&gt;(&lt;/span&gt;index.js&lt;span class="o"&gt;)&lt;/span&gt;: 
question repository url &lt;span class="o"&gt;(&lt;/span&gt;https://github.com/adaltas/remark-gatsby-plugins.git&lt;span class="o"&gt;)&lt;/span&gt;: 
question author &lt;span class="o"&gt;(&lt;/span&gt;David Worms &amp;lt;david@adaltas.com&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;: 
question license &lt;span class="o"&gt;(&lt;/span&gt;MIT&lt;span class="o"&gt;)&lt;/span&gt;: 
question private: 
git add package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"build: package initialization"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It created a &lt;code&gt;package.json&lt;/code&gt; file and committed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monorepo with Lerna
&lt;/h2&gt;

&lt;p&gt;The project contains a &lt;code&gt;package.json&lt;/code&gt; file. Following the Node.js terminology, the project is now a Node.js package. However, it will not be published on NPM, the official Node.js repository. Only the packages inside this package will be published.&lt;/p&gt;

&lt;p&gt;Instead of creating a Git repository for each package, it is easier to maintain a single repository storing multiple Node.js packages. Since multiple packages are managed inside the same repository, we call this a monorepo.&lt;/p&gt;

&lt;p&gt;Multiple tools exist to manage monorepos. &lt;a href="https://github.com/lerna/lerna"&gt;Lerna&lt;/a&gt; is a popular choice but not the only one. At Adaltas, we have been using it for some time and we continue for this article.&lt;/p&gt;

&lt;p&gt;Besides having just one Git repository to manage, there are additional advantages to legitimate the usage of monorepos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When multiple packages are developed, many duplicated dependencies are declared inside the &lt;code&gt;package.json&lt;/code&gt; file. Declaring the dependencies inside the top-most project managed with Lerna reduces space and time. It is called &lt;a href="https://github.com/lerna/lerna/blob/main/doc/hoist.md"&gt;"hoisting" dependencies&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;When packages depend on each other's, changes in one package often need to be instantly reflected in the other packages. A single feature may span multiple packages. Publishing the changes of the dependent packages is not possible, it takes too much time and there could be too many changes not justifying a release. The solution is to link the dependencies by creating symbolic links. For large projects, this is a tedious task. A tool like Lerna automates the creation of those links.&lt;/li&gt;
&lt;li&gt;Having one central location federates the execution of your commands. For example, you install all the dependencies of all your packages with a single command, &lt;code&gt;yarn install&lt;/code&gt;. For testing, the command &lt;code&gt;lerna test&lt;/code&gt; runs all your tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, Lerna helps us to manage our versions with respect to the &lt;a href="https://semver.org/"&gt;Semantic Versioning (SemVer)&lt;/a&gt; specification.&lt;/p&gt;

&lt;p&gt;The command to initialize Lerna is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add lerna
yarn lerna init &lt;span class="nt"&gt;--independent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--independent&lt;/code&gt; flag tells Lerna to manage the version of each package independently. Without it, Lerna aligns the versions of the packages it manages.&lt;/p&gt;

&lt;p&gt;These commands add the &lt;code&gt;lerna&lt;/code&gt; dependency to the &lt;code&gt;package.json&lt;/code&gt; and creates a new &lt;code&gt;lerna.json&lt;/code&gt; file:&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;"packages"&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="s2"&gt;"packages/*"&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;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"independent"&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;Then, we commit our pending changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add lerna.json package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: lerna initialization'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Publishing or ignoring lock files
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;yarn add&lt;/code&gt; command has generated a &lt;code&gt;yarn.lock&lt;/code&gt; file. With NPM, the file would have been &lt;code&gt;package-lock.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My approach is to publish lock files for my final applications. I don't publish the lock files for the packages which are meant to be used as dependencies. Some people agree with my opinion. However, the Yarn documentation states the contrary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All &lt;code&gt;yarn.lock&lt;/code&gt; files should be checked into source control (e.g. git or mercurial). This allows Yarn to install the same exact dependency tree across all machines, whether it be your coworker’s laptop or a CI server.&lt;br&gt;&lt;br&gt;
  Framework and library authors should also check &lt;code&gt;yarn.lock&lt;/code&gt; into source control. Don’t worry about publishing the &lt;code&gt;yarn.lock&lt;/code&gt; file as it won’t have any effect on users of the library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am perplexed. If it is not used, then why committing a huge file. Anyway, let's ignore them for now. The end result is that those lock files will be ignored from Git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'package-lock.json'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'yarn.lock'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
git add .gitignore
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"build: ignore lock files"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Yarn integration
&lt;/h2&gt;

&lt;p&gt;Since we are using Yarn instead of NPM, add these properties to &lt;code&gt;lerna.json&lt;/code&gt;:&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;"npmClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"useWorkspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;The &lt;code&gt;useWorkspaces&lt;/code&gt; property tells Lerna to not use &lt;code&gt;lerna.json#packages&lt;/code&gt; but instead to look for &lt;code&gt;packages.json#workspaces&lt;/code&gt;. According to the &lt;a href="https://github.com/lerna/lerna/tree/main/commands/bootstrap#--use-workspaces"&gt;Lerna Bootstrap&lt;/a&gt; documentation, both are similar except that Yarn doesn't support recursive globs &lt;code&gt;**&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Update Lerna to remove the &lt;code&gt;packages&lt;/code&gt; property from &lt;code&gt;lerna.json&lt;/code&gt;, it now contains only:&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;"npmClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"useWorkspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"independent"&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;Update the &lt;code&gt;packages.json&lt;/code&gt; file to contain:&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;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&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="s2"&gt;"packages/*"&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;The &lt;code&gt;private&lt;/code&gt; property is required. Any attempt to register a new dependency without it raises an error from Yarn in the form of "Workspaces can only be enabled in private projects". Note, it was possible to define the project as &lt;code&gt;private&lt;/code&gt; when we were initializing it with &lt;code&gt;yarn init&lt;/code&gt;. Now, that our project is a monorepo, it is a good time to mark the root package as &lt;code&gt;private&lt;/code&gt; since it will not be published on NPM. Only the packages inside it are for publishing.&lt;/p&gt;

&lt;p&gt;Note, executing &lt;code&gt;lerna init&lt;/code&gt; now will sync the &lt;code&gt;packages.json#workspaces&lt;/code&gt; back inside &lt;code&gt;lerna.json#packages&lt;/code&gt; with the new values.&lt;/p&gt;

&lt;p&gt;Now, save the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: activate yarn usage'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not familiar with Git, the &lt;code&gt;-a&lt;/code&gt; flag adds all the modified files to the commit. New files are disregarded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Package location
&lt;/h2&gt;

&lt;p&gt;By default, Lerna manages packages inside the "packages" folder. The majority of projects using Lerna uses this convention. It is a good idea to respect it. But in our case, we have two types of plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Gatsby plugins&lt;/li&gt;
&lt;li&gt;The Gatsby Remark plugins which extend the &lt;code&gt;gatsby-transformer-remark&lt;/code&gt; plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thus, I modify the &lt;code&gt;workspaces&lt;/code&gt; array in the &lt;code&gt;packages.json&lt;/code&gt; file to be:&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;"workspaces"&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="s2"&gt;"gatsby/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gatsby-remark/*"&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;The packages' location is saved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: workspaces declaration'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Packages creation
&lt;/h2&gt;

&lt;p&gt;Let's import two packages for the sake of testing. They are currently located inside my &lt;code&gt;/tmp&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /tmp/gatsby-caddy-redirects-conf
total 16
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;@ 1 david  staff   981B Nov 26 21:20 gatsby-node.js
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;@ 1 david  staff   239B Nov 26 21:19 package.json
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /tmp/gatsby-remark-title-to-frontmatter
total 16
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;  1 david  staff   1.2K Nov 26 11:35 index.js
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;@ 1 david  staff   309B Nov 26 21:14 package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To import the packages and commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;gatsby gatsby-remark
&lt;span class="c"&gt;# Import first plugin&lt;/span&gt;
&lt;span class="nb"&gt;mv&lt;/span&gt; /tmp/gatsby-caddy-redirects-conf gatsby/caddy-redirects-conf
git add gatsby/caddy-redirects-conf
&lt;span class="c"&gt;# Import second plugin&lt;/span&gt;
&lt;span class="nb"&gt;mv&lt;/span&gt; /tmp/gatsby-remark-title-to-frontmatter gatsby-remark/title-to-frontmatter
git add gatsby-remark/title-to-frontmatter
&lt;span class="c"&gt;# Commit the changes&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: import project'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cheat sheet
&lt;/h2&gt;

&lt;p&gt;Package initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monorepo initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add lerna
yarn lerna init
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn lerna init &lt;span class="nt"&gt;--independent&lt;/span&gt;
&lt;span class="c"&gt;# then&lt;/span&gt;
git add lerna.json package.json
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'build: lerna initialization'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ignore lock file (optional):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'package-lock.json'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'yarn.lock'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
git add .gitignore
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"build: ignore lock files"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yarn integration (unless using NPM), remove the &lt;code&gt;package&lt;/code&gt; property from &lt;code&gt;lerna.json&lt;/code&gt; and:&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;"npmClient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"useWorkspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Update the &lt;code&gt;packages.json&lt;/code&gt; file to contain:&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;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&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="s2"&gt;"packages/*"&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;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;The following article cover &lt;em&gt;the versioning and publishing strategies&lt;/em&gt; of packages with Lerna.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>node</category>
      <category>javascript</category>
      <category>git</category>
    </item>
  </channel>
</rss>
