New blog post
the_architech -
r79:31253d894356
Not Reviewed
Show More
Add another comment
TODOs: 0 unresolved 0 Resolved
COMMENTS: 0 General 0 Inline
@@ -0,0 +1,66
1 ---
2 title: In favor of small modules and plumbing
3 date: 2020-02-27
4 tags: development, process
5 tldr: Don't you want a beautiful chest of drawers?
6 color: gold
7 published: true
8 ---
9
10 In the JavaScript/Node.js community there have been fiery debates over whether publishing super-focused modules to npm is a positive thing or not. Installing a module that consists of maybe 50 lines of code or so but does a specific thing you need **well** is a good thing. No need to copy/paste the same lines of code in all of your projects. Then again, does publishing such modules pollute the world's most popular JavaScript package manager and snatch awesome package names away from multi-faceted modules? As with most things, it boils down to *perspective*. This post examines how I used to be of the mindset that publishing a plethora of "focused" modules is a waste of time but now think is a fantastic idea.
11
12 ## The `left-pad` incident, &c
13
14 Azer Koçulu, the developer of a module called `left-pad`, [unpublished](https://github.com/left-pad/left-pad/issues/4 "npmjs.org tells me that left-pad is not available (404 page)") this and the other 200+ modules he wrote from npm. It was a retaliatory move due to the fact that npm (the company) reverted ownership of another module of his, `kik`, to a company of the same name. To [quote](https://kodfabrik.com/journal/i-ve-just-liberated-my-modules "I've Just Liberated My Modules") the man himself:
15
16 > This situation made me realize that NPM is someone's private land where corporate is more powerful than the people, and I do open source because, Power To The People.
17
18 To be honest, I don't blame him. The `kik` situation was rather messed up in my opinion but when there are patent trolls involved, _someone_ is getting fucked (see npm's [response](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm "kik, left-pad, and npm")). Unfortunately, Azer's actions broke a significant amount of larger modules that depended upon the existence of `left-pad` and the Internet seemed to quite literally blow up for a day. Pundits published think pieces to Medium, Twitter threads proliferated, and insults/disdain toward Azer flew online for days. I'll admit, I got caught up in the frenzy and did a lot of [SMDH](https://www.urbandictionary.com/define.php?term=SMDH "Urband Dictionary definition for SMDH") towards Azer, npm, and kik.
19
20 At the time I was fully content with finding small utility modules like `left-pad` for inclusion within my projects and rather than installing them, I opted to extract the source code and place them in my projects directly. I did this for a few reasons:
21
22 1. Prevent potential fallout from an unpublish from happening to me.
23 2. Protection against a module creator giving up ownership to a spammer/hacker.
24 3. Quality control. Seriously, there is almost too much code out there that mixes tabs/spaces, single/double quotes, semi-colon/no semi-colon, snake/camel casing, and so on. Often in the same damn file! Gross.
25
26 This is not to say that my own code is flawless. I'll look back on my old code and think it's shit but at least it's _consistent_ shit.
27
28 ## Turning Point
29
30 A couple weeks ago I was returning to work on an API rewrite in progress and something would not compile. I was befuddled because I have several API projects that more or less share the same core. That's when I thought, "Why **aren't** most of the these utility functions their own modules?" This question stuck in my mind as I browsed the web and I remembered to look up a rather prolific JavaScript developer by the name of Sindre Sorhus. The man has over one **_thousand_** modules published on npm and all of them are small and/or focused (does one thing well, no bells and whistles). [Here](https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328 "One-line node modules") is his rationale for creating them:
31
32 > You make small focused modules for reusability and to make it possible to build larger more advanced things that are easier to reason about.
33
34 This made perfect sense to me and I had a chat with [Jesse](https://jesseyoungblood.com "Jesse's homepage") about it. He'd the same thought a year prior and started working on publishing modules from the code he was constantly copy/pasting between projects. Jesse's affirmation, coupled with Sindre's node module [boilerplate](https://github.com/sindresorhus/node-module-boilerplate "Boilerplate to kickstart creating a Node.js module") and [this tutorial](https://www.tsmean.com/articles/how-to-write-a-typescript-library "How to write a typescript library") on creating TypeScript libraries encouraged me to get started with publishing more focused modules than I had previously.
35
36 I am in the process of (hopefully) obtaining ownership of an unused (and empty) scope/organization on npm and once that happens, the nine focused modules I've written since my chat with Jesse will be live (these modules are currently published on my personal package registry). I see a couple advantages to [scoping](https://docs.npmjs.com/misc/scope "npm documentation on scopes") one's modules:
37
38 - Any cool name you can think of for your module is available
39 - At a glance, anyone can tell (roughly) who is responsible for the module
40 - Reputation building - become known for creating useful modules
41 - Doesn't "pollute" the npm namespace since everything's under an umbrella, so to speak
42
43 Some _disadvantages_ to this approach:
44
45 - Developers have to type extra to install your module
46 - `npm i @yourScope/packageName` versus
47 - `npm i packageName`
48 - If you have a truly unique package name and it's available, you'd be a fool to not take it
49
50 It's basically like choosing a gTLD over a classic TLD. If `webb.com` was available, I would have purchased that domain. It was not, so I purchased `webb.page`. These are both great but I was lucky that mine is a neat domain hack.
51
52 ## The Bigger Picture
53
54 There's another reason I've decided to go through with all this. To quote Steve Jobs (emphasis mine):
55
56 > When you're a carpenter making a beautiful chest of drawers, you're not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You'll know it's there, so you're going to use a beautiful piece of wood on the back. **For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.**
57
58 You remember that API project I mentioned earlier? I could not escape the nagging suspicion that my project could be, nay, _feel_ a helluva lot better if I knew the components used to create it were stronger. One way to ensure that is to write tests. Another way is to use a typed language...like TypeScript. And, that's exactly what I did for every module I've created leading up to this post. I suppose I just made the case for writing tests, period. 🤔
59
60 Regarding Jobs' quote, here's another way to look at it: the most beautiful hotel in the world wouldn't feel like such if all the toilets overflowed when flushed. I'm a serial creator but I've grown to enjoy working on the plumbing. 🕸
61
62 ## &c
63
64 - My personal package registry is currently running on [Verdaccio](https://github.com/verdaccio/verdaccio "A lightweight private npm proxy registry") but I'm thinking of checking out [Entropic](https://github.com/entropic-dev/entropic "a package registry for anything, but mostly javascript"). We'll see.
65 - There's an [awesome](https://github.com/parro-it/awesome-micro-npm-packages "A curated list of small, focused npm packages.") list of other focused modules to get inspired by or use in your own projects.
66 - This new love of plumbing is at odds with my impatience to get at least three products I have out of beta (and to make money from them). The end goal is for these products to be as automated and fault-tolerant as possible so I can focus on customer experience. No amount of code can replace the human connection.
@@ -2,7 +2,7
2 <feed xmlns="http://www.w3.org/2005/Atom">
2 <feed xmlns="http://www.w3.org/2005/Atom">
3 <id>https://blog.webb.page/</id>
3 <id>https://blog.webb.page/</id>
4 <title>the Webb blog</title>
4 <title>the Webb blog</title>
5 <updated>2020-01-30T21:58:29.550Z</updated>
5 <updated>2020-02-27T07:32:34.371Z</updated>
6 <generator>The 'Net</generator>
6 <generator>The 'Net</generator>
7 <author>
7 <author>
8 <name>Paul Anthony Webb</name>
8 <name>Paul Anthony Webb</name>
@@ -16,6 +16,69
16 <icon>https://blog.webb.page/assets/favicon.svg</icon>
16 <icon>https://blog.webb.page/assets/favicon.svg</icon>
17 <rights>All Rights Reserved, Paul Anthony Webb</rights>
17 <rights>All Rights Reserved, Paul Anthony Webb</rights>
18 <entry>
18 <entry>
19 <title type="html"><![CDATA[In favor of small modules and plumbing]]></title>
20 <id>https://blog.webb.page/2020/small-modules-and-plumbing</id>
21 <link href="https://blog.webb.page/2020/small-modules-and-plumbing"/>
22 <updated>2020-02-27T00:00:00.000Z</updated>
23 <summary type="html"><![CDATA[Don't you want a beautiful chest of drawers?]]></summary>
24 <content type="html"><![CDATA[<p>In the JavaScript/Node.js community there have been fiery debates over whether publishing super-focused modules to npm is a positive thing or not. Installing a module that consists of maybe 50 lines of code or so but does a specific thing you need <strong>well</strong> is a good thing. No need to copy/paste the same lines of code in all of your projects. Then again, does publishing such modules pollute the world&#39;s most popular JavaScript package manager and snatch awesome package names away from multi-faceted modules? As with most things, it boils down to <em>perspective</em>. This post examines how I used to be of the mindset that publishing a plethora of &quot;focused&quot; modules is a waste of time but now think is a fantastic idea.</p>
25 <h2 id="the-left-pad-incident-c">The <code>left-pad</code> incident, &amp;c</h2>
26 <p>Azer Koçulu, the developer of a module called <code>left-pad</code>, <a href="https://github.com/left-pad/left-pad/issues/4" title="npmjs.org tells me that left-pad is not available (404 page)">unpublished</a> this and the other 200+ modules he wrote from npm. It was a retaliatory move due to the fact that npm (the company) reverted ownership of another module of his, <code>kik</code>, to a company of the same name. To <a href="https://kodfabrik.com/journal/i-ve-just-liberated-my-modules" title="I&#39;ve Just Liberated My Modules">quote</a> the man himself:</p>
27 <blockquote>
28 <p>This situation made me realize that NPM is someone&#39;s private land where corporate is more powerful than the people, and I do open source because, Power To The People.</p>
29 </blockquote>
30 <p>To be honest, I don&#39;t blame him. The <code>kik</code> situation was rather messed up in my opinion but when there are patent trolls involved, <em>someone</em> is getting fucked (see npm&#39;s <a href="https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm" title="kik, left-pad, and npm">response</a>). Unfortunately, Azer&#39;s actions broke a significant amount of larger modules that depended upon the existence of <code>left-pad</code> and the Internet seemed to quite literally blow up for a day. Pundits published think pieces to Medium, Twitter threads proliferated, and insults/disdain toward Azer flew online for days. I&#39;ll admit, I got caught up in the frenzy and did a lot of <a href="https://www.urbandictionary.com/define.php?term=SMDH" title="Urband Dictionary definition for SMDH">SMDH</a> towards Azer, npm, and kik.</p>
31 <p>At the time I was fully content with finding small utility modules like <code>left-pad</code> for inclusion within my projects and rather than installing them, I opted to extract the source code and place them in my projects directly. I did this for a few reasons:</p>
32 <ol>
33 <li>Prevent potential fallout from an unpublish from happening to me.</li>
34 <li>Protection against a module creator giving up ownership to a spammer/hacker.</li>
35 <li>Quality control. Seriously, there is almost too much code out there that mixes tabs/spaces, single/double quotes, semi-colon/no semi-colon, snake/camel casing, and so on. Often in the same damn file! Gross.</li>
36 </ol>
37 <p>This is not to say that my own code is flawless. I&#39;ll look back on my old code and think it&#39;s shit but at least it&#39;s <em>consistent</em> shit.</p>
38 <h2 id="turning-point">Turning Point</h2>
39 <p>A couple weeks ago I was returning to work on an API rewrite in progress and something would not compile. I was befuddled because I have several API projects that more or less share the same core. That&#39;s when I thought, &quot;Why <strong>aren&#39;t</strong> most of the these utility functions their own modules?&quot; This question stuck in my mind as I browsed the web and I remembered to look up a rather prolific JavaScript developer by the name of Sindre Sorhus. The man has over one <strong><em>thousand</em></strong> modules published on npm and all of them are small and/or focused (does one thing well, no bells and whistles). <a href="https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328" title="One-line node modules">Here</a> is his rationale for creating them:</p>
40 <blockquote>
41 <p>You make small focused modules for reusability and to make it possible to build larger more advanced things that are easier to reason about.</p>
42 </blockquote>
43 <p>This made perfect sense to me and I had a chat with <a href="https://jesseyoungblood.com" title="Jesse&#39;s homepage">Jesse</a> about it. He&#39;d the same thought a year prior and started working on publishing modules from the code he was constantly copy/pasting between projects. Jesse&#39;s affirmation, coupled with Sindre&#39;s node module <a href="https://github.com/sindresorhus/node-module-boilerplate" title="Boilerplate to kickstart creating a Node.js module">boilerplate</a> and <a href="https://www.tsmean.com/articles/how-to-write-a-typescript-library" title="How to write a typescript library">this tutorial</a> on creating TypeScript libraries encouraged me to get started with publishing more focused modules than I had previously.</p>
44 <p>I am in the process of (hopefully) obtaining ownership of an unused (and empty) scope/organization on npm and once that happens, the nine focused modules I&#39;ve written since my chat with Jesse will be live (these modules are currently published on my personal package registry). I see a couple advantages to <a href="https://docs.npmjs.com/misc/scope" title="npm documentation on scopes">scoping</a> one&#39;s modules:</p>
45 <ul>
46 <li>Any cool name you can think of for your module is available</li>
47 <li>At a glance, anyone can tell (roughly) who is responsible for the module</li>
48 <li>Reputation building - become known for creating useful modules</li>
49 <li>Doesn&#39;t &quot;pollute&quot; the npm namespace since everything&#39;s under an umbrella, so to speak</li>
50 </ul>
51 <p>Some <em>disadvantages</em> to this approach:</p>
52 <ul>
53 <li>Developers have to type extra to install your module<ul>
54 <li><code>npm i @yourScope/packageName</code> versus</li>
55 <li><code>npm i packageName</code></li>
56 </ul>
57 </li>
58 <li>If you have a truly unique package name and it&#39;s available, you&#39;d be a fool to not take it</li>
59 </ul>
60 <p>It&#39;s basically like choosing a gTLD over a classic TLD. If <code>webb.com</code> was available, I would have purchased that domain. It was not, so I purchased <code>webb.page</code>. These are both great but I was lucky that mine is a neat domain hack.</p>
61 <h2 id="the-bigger-picture">The Bigger Picture</h2>
62 <p>There&#39;s another reason I&#39;ve decided to go through with all this. To quote Steve Jobs (emphasis mine):</p>
63 <blockquote>
64 <p>When you&#39;re a carpenter making a beautiful chest of drawers, you&#39;re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You&#39;ll know it&#39;s there, so you&#39;re going to use a beautiful piece of wood on the back. <strong>For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.</strong></p>
65 </blockquote>
66 <p>You remember that API project I mentioned earlier? I could not escape the nagging suspicion that my project could be, nay, <em>feel</em> a helluva lot better if I knew the components used to create it were stronger. One way to ensure that is to write tests. Another way is to use a typed language...like TypeScript. And, that&#39;s exactly what I did for every module I&#39;ve created leading up to this post. I suppose I just made the case for writing tests, period. 🤔</p>
67 <p>Regarding Jobs&#39; quote, here&#39;s another way to look at it: the most beautiful hotel in the world wouldn&#39;t feel like such if all the toilets overflowed when flushed. I&#39;m a serial creator but I&#39;ve grown to enjoy working on the plumbing. 🕸</p>
68 <h2 id="c">&amp;c</h2>
69 <ul>
70 <li>My personal package registry is currently running on <a href="https://github.com/verdaccio/verdaccio" title="A lightweight private npm proxy registry">Verdaccio</a> but I&#39;m thinking of checking out <a href="https://github.com/entropic-dev/entropic" title="a package registry for anything, but mostly javascript">Entropic</a>. We&#39;ll see.</li>
71 <li>There&#39;s an <a href="https://github.com/parro-it/awesome-micro-npm-packages" title="A curated list of small, focused npm packages.">awesome</a> list of other focused modules to get inspired by or use in your own projects.</li>
72 <li>This new love of plumbing is at odds with my impatience to get at least three products I have out of beta (and to make money from them). The end goal is for these products to be as automated and fault-tolerant as possible so I can focus on customer experience. No amount of code can replace the human connection.</li>
73 </ul>
74 ]]></content>
75 <author>
76 <name>Paul Anthony Webb</name>
77 <email>paul+blog@webb.page</email>
78 <uri>https://webb.page</uri>
79 </author>
80 </entry>
81 <entry>
19 <title type="html"><![CDATA[Migrating from MongoDB to RethinkDB]]></title>
82 <title type="html"><![CDATA[Migrating from MongoDB to RethinkDB]]></title>
20 <id>https://blog.webb.page/2020/migrating-from-mongo-to-rethink</id>
83 <id>https://blog.webb.page/2020/migrating-from-mongo-to-rethink</id>
21 <link href="https://blog.webb.page/2020/migrating-from-mongo-to-rethink"/>
84 <link href="https://blog.webb.page/2020/migrating-from-mongo-to-rethink"/>
@@ -11,6 +11,19
11 },
11 },
12 "items": [
12 "items": [
13 {
13 {
14 "id": "https://blog.webb.page/2020/small-modules-and-plumbing",
15 "content_html": "<p>In the JavaScript/Node.js community there have been fiery debates over whether publishing super-focused modules to npm is a positive thing or not. Installing a module that consists of maybe 50 lines of code or so but does a specific thing you need <strong>well</strong> is a good thing. No need to copy/paste the same lines of code in all of your projects. Then again, does publishing such modules pollute the world&#39;s most popular JavaScript package manager and snatch awesome package names away from multi-faceted modules? As with most things, it boils down to <em>perspective</em>. This post examines how I used to be of the mindset that publishing a plethora of &quot;focused&quot; modules is a waste of time but now think is a fantastic idea.</p>\n<h2 id=\"the-left-pad-incident-c\">The <code>left-pad</code> incident, &amp;c</h2>\n<p>Azer Koçulu, the developer of a module called <code>left-pad</code>, <a href=\"https://github.com/left-pad/left-pad/issues/4\" title=\"npmjs.org tells me that left-pad is not available (404 page)\">unpublished</a> this and the other 200+ modules he wrote from npm. It was a retaliatory move due to the fact that npm (the company) reverted ownership of another module of his, <code>kik</code>, to a company of the same name. To <a href=\"https://kodfabrik.com/journal/i-ve-just-liberated-my-modules\" title=\"I&#39;ve Just Liberated My Modules\">quote</a> the man himself:</p>\n<blockquote>\n<p>This situation made me realize that NPM is someone&#39;s private land where corporate is more powerful than the people, and I do open source because, Power To The People.</p>\n</blockquote>\n<p>To be honest, I don&#39;t blame him. The <code>kik</code> situation was rather messed up in my opinion but when there are patent trolls involved, <em>someone</em> is getting fucked (see npm&#39;s <a href=\"https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm\" title=\"kik, left-pad, and npm\">response</a>). Unfortunately, Azer&#39;s actions broke a significant amount of larger modules that depended upon the existence of <code>left-pad</code> and the Internet seemed to quite literally blow up for a day. Pundits published think pieces to Medium, Twitter threads proliferated, and insults/disdain toward Azer flew online for days. I&#39;ll admit, I got caught up in the frenzy and did a lot of <a href=\"https://www.urbandictionary.com/define.php?term=SMDH\" title=\"Urband Dictionary definition for SMDH\">SMDH</a> towards Azer, npm, and kik.</p>\n<p>At the time I was fully content with finding small utility modules like <code>left-pad</code> for inclusion within my projects and rather than installing them, I opted to extract the source code and place them in my projects directly. I did this for a few reasons:</p>\n<ol>\n<li>Prevent potential fallout from an unpublish from happening to me.</li>\n<li>Protection against a module creator giving up ownership to a spammer/hacker.</li>\n<li>Quality control. Seriously, there is almost too much code out there that mixes tabs/spaces, single/double quotes, semi-colon/no semi-colon, snake/camel casing, and so on. Often in the same damn file! Gross.</li>\n</ol>\n<p>This is not to say that my own code is flawless. I&#39;ll look back on my old code and think it&#39;s shit but at least it&#39;s <em>consistent</em> shit.</p>\n<h2 id=\"turning-point\">Turning Point</h2>\n<p>A couple weeks ago I was returning to work on an API rewrite in progress and something would not compile. I was befuddled because I have several API projects that more or less share the same core. That&#39;s when I thought, &quot;Why <strong>aren&#39;t</strong> most of the these utility functions their own modules?&quot; This question stuck in my mind as I browsed the web and I remembered to look up a rather prolific JavaScript developer by the name of Sindre Sorhus. The man has over one <strong><em>thousand</em></strong> modules published on npm and all of them are small and/or focused (does one thing well, no bells and whistles). <a href=\"https://github.com/sindresorhus/ama/issues/10#issuecomment-117766328\" title=\"One-line node modules\">Here</a> is his rationale for creating them:</p>\n<blockquote>\n<p>You make small focused modules for reusability and to make it possible to build larger more advanced things that are easier to reason about.</p>\n</blockquote>\n<p>This made perfect sense to me and I had a chat with <a href=\"https://jesseyoungblood.com\" title=\"Jesse&#39;s homepage\">Jesse</a> about it. He&#39;d the same thought a year prior and started working on publishing modules from the code he was constantly copy/pasting between projects. Jesse&#39;s affirmation, coupled with Sindre&#39;s node module <a href=\"https://github.com/sindresorhus/node-module-boilerplate\" title=\"Boilerplate to kickstart creating a Node.js module\">boilerplate</a> and <a href=\"https://www.tsmean.com/articles/how-to-write-a-typescript-library\" title=\"How to write a typescript library\">this tutorial</a> on creating TypeScript libraries encouraged me to get started with publishing more focused modules than I had previously.</p>\n<p>I am in the process of (hopefully) obtaining ownership of an unused (and empty) scope/organization on npm and once that happens, the nine focused modules I&#39;ve written since my chat with Jesse will be live (these modules are currently published on my personal package registry). I see a couple advantages to <a href=\"https://docs.npmjs.com/misc/scope\" title=\"npm documentation on scopes\">scoping</a> one&#39;s modules:</p>\n<ul>\n<li>Any cool name you can think of for your module is available</li>\n<li>At a glance, anyone can tell (roughly) who is responsible for the module</li>\n<li>Reputation building - become known for creating useful modules</li>\n<li>Doesn&#39;t &quot;pollute&quot; the npm namespace since everything&#39;s under an umbrella, so to speak</li>\n</ul>\n<p>Some <em>disadvantages</em> to this approach:</p>\n<ul>\n<li>Developers have to type extra to install your module<ul>\n<li><code>npm i @yourScope/packageName</code> versus</li>\n<li><code>npm i packageName</code></li>\n</ul>\n</li>\n<li>If you have a truly unique package name and it&#39;s available, you&#39;d be a fool to not take it</li>\n</ul>\n<p>It&#39;s basically like choosing a gTLD over a classic TLD. If <code>webb.com</code> was available, I would have purchased that domain. It was not, so I purchased <code>webb.page</code>. These are both great but I was lucky that mine is a neat domain hack.</p>\n<h2 id=\"the-bigger-picture\">The Bigger Picture</h2>\n<p>There&#39;s another reason I&#39;ve decided to go through with all this. To quote Steve Jobs (emphasis mine):</p>\n<blockquote>\n<p>When you&#39;re a carpenter making a beautiful chest of drawers, you&#39;re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You&#39;ll know it&#39;s there, so you&#39;re going to use a beautiful piece of wood on the back. <strong>For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.</strong></p>\n</blockquote>\n<p>You remember that API project I mentioned earlier? I could not escape the nagging suspicion that my project could be, nay, <em>feel</em> a helluva lot better if I knew the components used to create it were stronger. One way to ensure that is to write tests. Another way is to use a typed language...like TypeScript. And, that&#39;s exactly what I did for every module I&#39;ve created leading up to this post. I suppose I just made the case for writing tests, period. 🤔</p>\n<p>Regarding Jobs&#39; quote, here&#39;s another way to look at it: the most beautiful hotel in the world wouldn&#39;t feel like such if all the toilets overflowed when flushed. I&#39;m a serial creator but I&#39;ve grown to enjoy working on the plumbing. 🕸</p>\n<h2 id=\"c\">&amp;c</h2>\n<ul>\n<li>My personal package registry is currently running on <a href=\"https://github.com/verdaccio/verdaccio\" title=\"A lightweight private npm proxy registry\">Verdaccio</a> but I&#39;m thinking of checking out <a href=\"https://github.com/entropic-dev/entropic\" title=\"a package registry for anything, but mostly javascript\">Entropic</a>. We&#39;ll see.</li>\n<li>There&#39;s an <a href=\"https://github.com/parro-it/awesome-micro-npm-packages\" title=\"A curated list of small, focused npm packages.\">awesome</a> list of other focused modules to get inspired by or use in your own projects.</li>\n<li>This new love of plumbing is at odds with my impatience to get at least three products I have out of beta (and to make money from them). The end goal is for these products to be as automated and fault-tolerant as possible so I can focus on customer experience. No amount of code can replace the human connection.</li>\n</ul>\n",
16 "url": "https://blog.webb.page/2020/small-modules-and-plumbing",
17 "title": "In favor of small modules and plumbing",
18 "summary": "Don't you want a beautiful chest of drawers?",
19 "image": "https://blog.webb.page/assets/og.png",
20 "date_modified": "2020-02-27T00:00:00.000Z",
21 "author": {
22 "name": "Paul Anthony Webb",
23 "url": "https://webb.page"
24 }
25 },
26 {
14 "id": "https://blog.webb.page/2020/migrating-from-mongo-to-rethink",
27 "id": "https://blog.webb.page/2020/migrating-from-mongo-to-rethink",
15 "content_html": "<p>RethinkDB, seemingly on life support for quite some time, is seeing a <a href=\"https://rethinkdb.com/blog/2.4.0-release\" title=\"Announcing RethinkDB 2.4.0: Night Of The Living Dead\">revival</a> of sorts. As such, I thought it prudent to make available evergreen content for my favorite database these days. If you are interested in trying RethinkDB you can check out <a href=\"https://pusher.com/tutorials/live-node-rethinkdb\" title=\"How to build a realtime application with Node.js and RethinkDB\">these</a> <a href=\"https://www.pluralsight.com/guides/a-practical-introduction-to-rethinkdb\" title=\"A Practical Introduction to RethinkDB\">two</a> tutorials (my guide will not cover installation or setup).</p>\n<h2 id=\"preparing-mongodb-exports\">Preparing MongoDB exports</h2>\n<pre><code class=\"language-sh\"># Command\nmongoexport --port PORT_NUMBER --db DATABASE_NAME --collection COLLECTION_NAME --out COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json --pretty --jsonArray \n\n# Example\nmongoexport --port 98765 --db dawebb --collection users --out users-`date &quot;+%Y-%m-%d&quot;`.json --pretty --jsonArray</code></pre>\n<p>There&#39;s a bit to unpack here so I&#39;ll break it down. Keep in mind that all the parameters yelling at you are <em>placeholders</em> (for you to replace with your own parameters).</p>\n<p>Actually, the placeholders are self-explanatory but the second half of the command is interesting.</p>\n<p><code>COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json</code> makes it so the exported collection looks like <code>users-2020-01-24.json</code>, with the date being whenever you ran the above command. Super nifty for backups too.</p>\n<p>The <code>--pretty</code> flag isn&#39;t necessary for the import into RethinkDB to work, it&#39;s for <strong>you</strong> to inspect the export for any reason.</p>\n<p><a href=\"https://docs.mongodb.com/manual/reference/program/mongoexport/#cmdoption-mongoexport-jsonarray\" title=\"MongoDB reference about the &#39;jsonArray&#39; flag\">The last flag</a>, <code>--jsonArray</code>, is the most important. For <em>some reason</em>, MongoDB exports each item in a collection as its own object <strong>not</strong> separated by commas. Maybe MongoDB&#39;s import process doesn&#39;t choke on malformed JSON but everything else does. <code>--jsonArray</code> puts the contents of the export into a single JSON array. Like you&#39;d expect by default...maybe that&#39;s just me.</p>\n<p>NOTE: <code>--out</code> is the destination path so if you haven&#39;t prefaced <code>COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json</code> with a path, the export will be in your home directory.</p>\n<p>Anyhoo once you&#39;ve exported the collections you care about, SFTP into that server to grab them and place them on your Desktop so you don&#39;t have a brain fart and forget where you put them moments later.</p>\n<h2 id=\"migrating-phase-01\">Migrating, phase 01</h2>\n<p>MongoDB comes with some oddities that you may not want in your new database. Notably, how it deals with IDs. Here&#39;s an example:</p>\n<pre><code class=\"language-json\">{\n &quot;_id&quot;: {\n &quot;$oid&quot;: &quot;6bf9b676c24869077c37f61e&quot;\n },\n &quot;admin&quot;: true,\n &quot;dashboard&quot;: [],\n &quot;language&quot;: &quot;en_US&quot;,\n &quot;loginMethod&quot;: &quot;link&quot;,\n &quot;nameFirst&quot;: &quot;&quot;,\n &quot;nameLast&quot;: &quot;&quot;,\n &quot;plan&quot;: &quot;free&quot;,\n &quot;summaries&quot;: [],\n &quot;timezone&quot;: &quot;gmt-05-02&quot;,\n &quot;verified&quot;: true,\n &quot;email&quot;: &quot;user@domain.tld&quot;,\n &quot;__v&quot;: 0\n}</code></pre>\n<p>In RethinkDB IDs are simply <code>id</code> and you have no need for <code>__v</code> so you probably don&#39;t want these values in your shiny new database. Also, you may have decided to use this migration period switch up your schema. Combine <code>nameFirst</code> with <code>nameLast</code>? Drop <code>plan</code>? Update <code>timzeone</code>? Replace <code>createdAt</code> with <code>created</code>? Regardless, you&#39;re gonna need to do a bit of legwork to clean your MongoDB export(s).</p>\n<p>The entire script I use is hosted <a href=\"https://gist.github.com/NetOperatorWibby/5084bf5c64306093e067fc43cfa4fcdb\" title=\"MongoDB to RethinkDB migration script\">here</a> but I&#39;ll point out some relevant pieces.</p>\n<p>If you have any fields with dates/milliseconds, your import will fail unless you wrap those fields in <code>new Date</code> like so:</p>\n<pre><code class=\"language-json\">…,\ntimestamp: new Date(timestamp),\n…,</code></pre>\n<p>To reuse the IDs that were generated in MongoDB for usage in RethinkDB, you&#39;re gonna need to do something like this:</p>\n<pre><code class=\"language-json\">…,\nid: record._id[&quot;$oid&quot;],\n…,</code></pre>\n<p>You&#39;ll also need to make sure to explicity select the fields you want to transfer into your new export. The gist linked above should answer remaining questions you may have.</p>\n<h2 id=\"importing-into-rethinkdb\">Importing into RethinkDB</h2>\n<p>Even though you&#39;ve already installed RethinkDB, you need to install <a href=\"https://rethinkdb.com/docs/install-drivers/python\" title=\"RethinkDB Python driver installation instructions\">the Python driver</a> as well (for importing functionality, at least I had to do this for macOS).</p>\n<p>Also, make sure you are importing your newly processed/migrated data into RethinkDB, not the original nonsense from your MongoDB export (unless of course, that&#39;s your plan).</p>\n<pre><code class=\"language-sh\"># Command\nrethinkdb import -f PATH_TO_PROCESSED_EXPORT_FILE --table DATABASE.TABLE -c CONNECTION_URL --password-file PASSWORD_FILE --force\n\n# Example\nrethinkdb import -f ~/Desktop/migrated/users-2020-01-24.json --table dawebb.users -c localhost:98765 --password-file ~/Desktop/rethinkpass.txt --force </code></pre>\n<p>If you don&#39;t have a password on your RethinkDB database, you can safely omit the <code>--password-file</code> flag. Otherwise, make sure the password file only contains the password. If your IDE automatically generates new lines in files, just create the password file with <code>nano</code>.</p>\n<p>Make sure you run the above command while RethinkDB is running and you&#39;ll see freshly created tables successfully created.</p>\n<h2 id=\"migrating-phase-02\">Migrating, phase 02</h2>\n<p>Alright, we&#39;re almost at the finish line!</p>\n<p>One of the neat things about RethinkDB (and a feature that convinced me to make the jump) is its Data Explorer. It&#39;s a UI that allows you to manipulate or check out your tables. There are just two remaining things we need to do and they&#39;re quick and easy: 1) set up indexes for our tables and 2) update time-based data to a format RethinkDB <em>really</em> likes.</p>\n<p>Visit <code>http://localhost:8080</code> (default port, unless you changed it) and click on &quot;Data Explorer&quot; in the header. In the text field you&#39;ll be able to perform queries using JavaScript.</p>\n<h3 id=\"setting-up-indexes\">Setting up indexes</h3>\n<p>By default <code>id</code> is an index but you may want more. Indexes are for fields with unique values so it&#39;s easy to think of which field(s) would be suitable.</p>\n<p>Sometimes, only the ID would be unique and that&#39;s fine.</p>\n<pre><code class=\"language-js\">// Command\nr.db(&quot;DATABASE_NAME&quot;).table(&quot;TABLE_NAME&quot;).index_create(&quot;FIELD_WITH_UNIQUE_VALUE&quot;); \n\n// Examples\nr.db(&quot;dawebb&quot;).table(&quot;users&quot;).index_create(&quot;email&quot;);\nr.db(&quot;dawebb&quot;).table(&quot;posts&quot;).index_create(&quot;slug&quot;);</code></pre>\n<p>Now let&#39;s update our time-based fields:</p>\n<pre><code class=\"language-js\">// Command\nr.db(&quot;DATABASE_NAME&quot;).table(&quot;TABLE_NAME&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n updated: r.iso8601(r.row[&quot;updated&quot;]).to_iso8601()\n});\n\n// Examples\nr.db(&quot;dawebb&quot;).table(&quot;users&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n updated: r.iso8601(r.row[&quot;updated&quot;]).to_iso8601()\n});\n\nr.db(&quot;dawebb&quot;).table(&quot;visits&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n timestamp: r.iso8601(r.row[&quot;timestamp&quot;]).to_iso8601() \n});</code></pre>\n<h2 id=\"fin\">FIN</h2>\n<p>And there you have it! A super easy guide to move from MongoDB to RethinkDB. I&#39;ve been using RethinkDB for several months now and I am way happier than I was with MongoDB. While super easy to get into, once you get in too deep it becomes an exercise in frustration to find solutions to ambiguous errors and the MongoDB docs are not user-friendly.</p>\n<p>Contrast that with RethinkDB&#39;s Data Explorer, clear error messages, and clean documentation and it&#39;s not difficult to imagine why I&#39;d make the switch. 🕸</p>\n<p>P.S. New year, <a href=\"https://socii.network/NetOpWibby/status/e3HWCaoqTZYzZvZ47RXfp\" title=\"Sneak peek at codebase\">new projects</a>, and now I feel like I need a new design for this blog. And then I remembered that first I need to create a <a href=\"/2019/a-personal-api\" title=\"A Personal API\">personal API</a> so this blog can just become the presentation layer for the content.</p>\n<p><strong><em>2020.01.30 update</em></strong></p>\n<blockquote>\n<p>Another reason to migrate is the license of MongoDB: SSPL vs. Apache 2 of RethinkDB.<br/>— <a href=\"https://lobste.rs/u/af\">af</a></p>\n</blockquote>\n<p>For others who may not know what <a href=\"https://lukasatkinson.de/2019/mongodb-no-longer-seeks-osi-approval-for-sspl\">SSPL</a> entails (like me until I read the linked post):</p>\n<p>Basically, SSPL means one cannot offer MongoDB as a hosted service. That makes sense from their end as they offer hosting. However, it&#39;s a bit of a punk move because they are preventing potential competition from forcing them to improve their product.</p>\n",
28 "content_html": "<p>RethinkDB, seemingly on life support for quite some time, is seeing a <a href=\"https://rethinkdb.com/blog/2.4.0-release\" title=\"Announcing RethinkDB 2.4.0: Night Of The Living Dead\">revival</a> of sorts. As such, I thought it prudent to make available evergreen content for my favorite database these days. If you are interested in trying RethinkDB you can check out <a href=\"https://pusher.com/tutorials/live-node-rethinkdb\" title=\"How to build a realtime application with Node.js and RethinkDB\">these</a> <a href=\"https://www.pluralsight.com/guides/a-practical-introduction-to-rethinkdb\" title=\"A Practical Introduction to RethinkDB\">two</a> tutorials (my guide will not cover installation or setup).</p>\n<h2 id=\"preparing-mongodb-exports\">Preparing MongoDB exports</h2>\n<pre><code class=\"language-sh\"># Command\nmongoexport --port PORT_NUMBER --db DATABASE_NAME --collection COLLECTION_NAME --out COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json --pretty --jsonArray \n\n# Example\nmongoexport --port 98765 --db dawebb --collection users --out users-`date &quot;+%Y-%m-%d&quot;`.json --pretty --jsonArray</code></pre>\n<p>There&#39;s a bit to unpack here so I&#39;ll break it down. Keep in mind that all the parameters yelling at you are <em>placeholders</em> (for you to replace with your own parameters).</p>\n<p>Actually, the placeholders are self-explanatory but the second half of the command is interesting.</p>\n<p><code>COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json</code> makes it so the exported collection looks like <code>users-2020-01-24.json</code>, with the date being whenever you ran the above command. Super nifty for backups too.</p>\n<p>The <code>--pretty</code> flag isn&#39;t necessary for the import into RethinkDB to work, it&#39;s for <strong>you</strong> to inspect the export for any reason.</p>\n<p><a href=\"https://docs.mongodb.com/manual/reference/program/mongoexport/#cmdoption-mongoexport-jsonarray\" title=\"MongoDB reference about the &#39;jsonArray&#39; flag\">The last flag</a>, <code>--jsonArray</code>, is the most important. For <em>some reason</em>, MongoDB exports each item in a collection as its own object <strong>not</strong> separated by commas. Maybe MongoDB&#39;s import process doesn&#39;t choke on malformed JSON but everything else does. <code>--jsonArray</code> puts the contents of the export into a single JSON array. Like you&#39;d expect by default...maybe that&#39;s just me.</p>\n<p>NOTE: <code>--out</code> is the destination path so if you haven&#39;t prefaced <code>COLLECTION_NAME-`date &quot;+%Y-%m-%d&quot;`.json</code> with a path, the export will be in your home directory.</p>\n<p>Anyhoo once you&#39;ve exported the collections you care about, SFTP into that server to grab them and place them on your Desktop so you don&#39;t have a brain fart and forget where you put them moments later.</p>\n<h2 id=\"migrating-phase-01\">Migrating, phase 01</h2>\n<p>MongoDB comes with some oddities that you may not want in your new database. Notably, how it deals with IDs. Here&#39;s an example:</p>\n<pre><code class=\"language-json\">{\n &quot;_id&quot;: {\n &quot;$oid&quot;: &quot;6bf9b676c24869077c37f61e&quot;\n },\n &quot;admin&quot;: true,\n &quot;dashboard&quot;: [],\n &quot;language&quot;: &quot;en_US&quot;,\n &quot;loginMethod&quot;: &quot;link&quot;,\n &quot;nameFirst&quot;: &quot;&quot;,\n &quot;nameLast&quot;: &quot;&quot;,\n &quot;plan&quot;: &quot;free&quot;,\n &quot;summaries&quot;: [],\n &quot;timezone&quot;: &quot;gmt-05-02&quot;,\n &quot;verified&quot;: true,\n &quot;email&quot;: &quot;user@domain.tld&quot;,\n &quot;__v&quot;: 0\n}</code></pre>\n<p>In RethinkDB IDs are simply <code>id</code> and you have no need for <code>__v</code> so you probably don&#39;t want these values in your shiny new database. Also, you may have decided to use this migration period switch up your schema. Combine <code>nameFirst</code> with <code>nameLast</code>? Drop <code>plan</code>? Update <code>timzeone</code>? Replace <code>createdAt</code> with <code>created</code>? Regardless, you&#39;re gonna need to do a bit of legwork to clean your MongoDB export(s).</p>\n<p>The entire script I use is hosted <a href=\"https://gist.github.com/NetOperatorWibby/5084bf5c64306093e067fc43cfa4fcdb\" title=\"MongoDB to RethinkDB migration script\">here</a> but I&#39;ll point out some relevant pieces.</p>\n<p>If you have any fields with dates/milliseconds, your import will fail unless you wrap those fields in <code>new Date</code> like so:</p>\n<pre><code class=\"language-json\">…,\ntimestamp: new Date(timestamp),\n…,</code></pre>\n<p>To reuse the IDs that were generated in MongoDB for usage in RethinkDB, you&#39;re gonna need to do something like this:</p>\n<pre><code class=\"language-json\">…,\nid: record._id[&quot;$oid&quot;],\n…,</code></pre>\n<p>You&#39;ll also need to make sure to explicity select the fields you want to transfer into your new export. The gist linked above should answer remaining questions you may have.</p>\n<h2 id=\"importing-into-rethinkdb\">Importing into RethinkDB</h2>\n<p>Even though you&#39;ve already installed RethinkDB, you need to install <a href=\"https://rethinkdb.com/docs/install-drivers/python\" title=\"RethinkDB Python driver installation instructions\">the Python driver</a> as well (for importing functionality, at least I had to do this for macOS).</p>\n<p>Also, make sure you are importing your newly processed/migrated data into RethinkDB, not the original nonsense from your MongoDB export (unless of course, that&#39;s your plan).</p>\n<pre><code class=\"language-sh\"># Command\nrethinkdb import -f PATH_TO_PROCESSED_EXPORT_FILE --table DATABASE.TABLE -c CONNECTION_URL --password-file PASSWORD_FILE --force\n\n# Example\nrethinkdb import -f ~/Desktop/migrated/users-2020-01-24.json --table dawebb.users -c localhost:98765 --password-file ~/Desktop/rethinkpass.txt --force </code></pre>\n<p>If you don&#39;t have a password on your RethinkDB database, you can safely omit the <code>--password-file</code> flag. Otherwise, make sure the password file only contains the password. If your IDE automatically generates new lines in files, just create the password file with <code>nano</code>.</p>\n<p>Make sure you run the above command while RethinkDB is running and you&#39;ll see freshly created tables successfully created.</p>\n<h2 id=\"migrating-phase-02\">Migrating, phase 02</h2>\n<p>Alright, we&#39;re almost at the finish line!</p>\n<p>One of the neat things about RethinkDB (and a feature that convinced me to make the jump) is its Data Explorer. It&#39;s a UI that allows you to manipulate or check out your tables. There are just two remaining things we need to do and they&#39;re quick and easy: 1) set up indexes for our tables and 2) update time-based data to a format RethinkDB <em>really</em> likes.</p>\n<p>Visit <code>http://localhost:8080</code> (default port, unless you changed it) and click on &quot;Data Explorer&quot; in the header. In the text field you&#39;ll be able to perform queries using JavaScript.</p>\n<h3 id=\"setting-up-indexes\">Setting up indexes</h3>\n<p>By default <code>id</code> is an index but you may want more. Indexes are for fields with unique values so it&#39;s easy to think of which field(s) would be suitable.</p>\n<p>Sometimes, only the ID would be unique and that&#39;s fine.</p>\n<pre><code class=\"language-js\">// Command\nr.db(&quot;DATABASE_NAME&quot;).table(&quot;TABLE_NAME&quot;).index_create(&quot;FIELD_WITH_UNIQUE_VALUE&quot;); \n\n// Examples\nr.db(&quot;dawebb&quot;).table(&quot;users&quot;).index_create(&quot;email&quot;);\nr.db(&quot;dawebb&quot;).table(&quot;posts&quot;).index_create(&quot;slug&quot;);</code></pre>\n<p>Now let&#39;s update our time-based fields:</p>\n<pre><code class=\"language-js\">// Command\nr.db(&quot;DATABASE_NAME&quot;).table(&quot;TABLE_NAME&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n updated: r.iso8601(r.row[&quot;updated&quot;]).to_iso8601()\n});\n\n// Examples\nr.db(&quot;dawebb&quot;).table(&quot;users&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n updated: r.iso8601(r.row[&quot;updated&quot;]).to_iso8601()\n});\n\nr.db(&quot;dawebb&quot;).table(&quot;visits&quot;).update({\n created: r.iso8601(r.row[&quot;created&quot;]).to_iso8601(),\n timestamp: r.iso8601(r.row[&quot;timestamp&quot;]).to_iso8601() \n});</code></pre>\n<h2 id=\"fin\">FIN</h2>\n<p>And there you have it! A super easy guide to move from MongoDB to RethinkDB. I&#39;ve been using RethinkDB for several months now and I am way happier than I was with MongoDB. While super easy to get into, once you get in too deep it becomes an exercise in frustration to find solutions to ambiguous errors and the MongoDB docs are not user-friendly.</p>\n<p>Contrast that with RethinkDB&#39;s Data Explorer, clear error messages, and clean documentation and it&#39;s not difficult to imagine why I&#39;d make the switch. 🕸</p>\n<p>P.S. New year, <a href=\"https://socii.network/NetOpWibby/status/e3HWCaoqTZYzZvZ47RXfp\" title=\"Sneak peek at codebase\">new projects</a>, and now I feel like I need a new design for this blog. And then I remembered that first I need to create a <a href=\"/2019/a-personal-api\" title=\"A Personal API\">personal API</a> so this blog can just become the presentation layer for the content.</p>\n<p><strong><em>2020.01.30 update</em></strong></p>\n<blockquote>\n<p>Another reason to migrate is the license of MongoDB: SSPL vs. Apache 2 of RethinkDB.<br/>— <a href=\"https://lobste.rs/u/af\">af</a></p>\n</blockquote>\n<p>For others who may not know what <a href=\"https://lukasatkinson.de/2019/mongodb-no-longer-seeks-osi-approval-for-sspl\">SSPL</a> entails (like me until I read the linked post):</p>\n<p>Basically, SSPL means one cannot offer MongoDB as a hosted service. That makes sense from their end as they offer hosting. However, it&#39;s a bit of a punk move because they are preventing potential competition from forcing them to improve their product.</p>\n",
16 "url": "https://blog.webb.page/2020/migrating-from-mongo-to-rethink",
29 "url": "https://blog.webb.page/2020/migrating-from-mongo-to-rethink",
@@ -167,10 +167,9 post { // stylelint-disable-line selector-type-no-unknown
167 background-color: rgba($black, 0.3);
167 background-color: rgba($black, 0.3);
168 }
168 }
169
169
170 code,
170 pre {
171 pre {
171 ::selection {
172 background-image: linear-gradient(150deg, rgba($black, 0.7), $black 100%);
172 background-color: $white;
173 }
174 }
173 }
175
174
176 a {
175 a {
@@ -14,8 +14,8
14 },
14 },
15 "dependencies": {
15 "dependencies": {
16 "chewit": "^2019.7.23",
16 "chewit": "^2019.7.23",
17 "fastify": "2.11.0",
17 "fastify": "2.12.0",
18 "fastify-compress": "^2.0.0",
18 "fastify-compress": "^2.0.1",
19 "fastify-helmet": "^3.0.2",
19 "fastify-helmet": "^3.0.2",
20 "fastify-static": "^2.6.0",
20 "fastify-static": "^2.6.0",
21 "feed": "^4.1.0",
21 "feed": "^4.1.0",
@@ -23,8 +23,8
23 },
23 },
24 "description": "Blog of Paul Anthony Webb",
24 "description": "Blog of Paul Anthony Webb",
25 "devDependencies": {
25 "devDependencies": {
26 "@babel/cli": "^7.8.3",
26 "@babel/cli": "^7.8.4",
27 "@babel/core": "^7.8.3",
27 "@babel/core": "^7.8.4",
28 "@babel/plugin-external-helpers": "7.8.3",
28 "@babel/plugin-external-helpers": "7.8.3",
29 "@babel/plugin-proposal-class-properties": "7.8.3",
29 "@babel/plugin-proposal-class-properties": "7.8.3",
30 "@babel/plugin-proposal-decorators": "7.8.3",
30 "@babel/plugin-proposal-decorators": "7.8.3",
@@ -36,29 +36,29
36 "@babel/plugin-syntax-dynamic-import": "7.8.3",
36 "@babel/plugin-syntax-dynamic-import": "7.8.3",
37 "@babel/plugin-syntax-import-meta": "7.8.3",
37 "@babel/plugin-syntax-import-meta": "7.8.3",
38 "@babel/polyfill": "^7.8.3",
38 "@babel/polyfill": "^7.8.3",
39 "@babel/preset-env": "^7.8.3",
39 "@babel/preset-env": "^7.8.4",
40 "@babel/register": "^7.8.3",
40 "@babel/register": "^7.8.3",
41 "@inc/eslint-config": "^2019.10.22",
41 "@inc/eslint-config": "^2019.10.22",
42 "@inc/stylelint-config": "^2019.12.1",
42 "@inc/stylelint-config": "^2019.12.1",
43 "alphabetic-compare": "^1.1.4",
43 "alphabetic-compare": "^1.1.4",
44 "chronver": "^2019.10.2-7.1",
44 "chronver": "^2020.2.24",
45 "colorette": "^1.1.0",
45 "colorette": "^1.1.0",
46 "cwd": "^0.10.0",
46 "cwd": "^0.10.0",
47 "eslint": "^6.8.0",
47 "eslint": "^6.8.0",
48 "glob": "^7.1.6",
48 "glob": "^7.1.6",
49 "graceful-fs": "^4.2.3",
49 "graceful-fs": "^4.2.3",
50 "html-minifier": "^4.0.0",
50 "html-minifier": "^4.0.0",
51 "husky": "^4.2.1",
51 "husky": "^4.2.3",
52 "js-yaml": "^3.13.1",
52 "js-yaml": "^3.13.1",
53 "link-module-alias": "^1.2.0",
53 "link-module-alias": "^1.2.0",
54 "nodemon": "^2.0.2",
54 "nodemon": "^2.0.2",
55 "npm-run-all": "^4.1.5",
55 "npm-run-all": "^4.1.5",
56 "pino-pretty": "^3.5.0",
56 "pino-pretty": "^3.6.0",
57 "recursive-readdir": "^2.2.2",
57 "recursive-readdir": "^2.2.2",
58 "sass": "^1.25.1-test.1",
58 "sass": "^1.26.1",
59 "snazzy": "^8.0.0",
59 "snazzy": "^8.0.0",
60 "standardx": "^5.0.0",
60 "standardx": "^5.0.0",
61 "stylelint": "^13.0.0",
61 "stylelint": "^13.2.0",
62 "stylelint-order": "^4.0.0",
62 "stylelint-order": "^4.0.0",
63 "tiny-relative-date": "^1.3.0",
63 "tiny-relative-date": "^1.3.0",
64 "updates": "^9.3.3",
64 "updates": "^9.3.3",
@@ -98,5 +98,5
98 "app/dist"
98 "app/dist"
99 ]
99 ]
100 },
100 },
101 "version": "2020.01.30"
101 "version": "2020.02.27"
102 }
102 }
Comments 0
You need to be logged in to leave comments. Login now