<?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>Forem: Truong Vu</title>
    <description>The latest articles on Forem by Truong Vu (@vukhanhtruong).</description>
    <link>https://forem.com/vukhanhtruong</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%2F114286%2F60341084-1656-4818-99e1-eccb6b202b5a.jpeg</url>
      <title>Forem: Truong Vu</title>
      <link>https://forem.com/vukhanhtruong</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vukhanhtruong"/>
    <language>en</language>
    <item>
      <title>Claude Rock</title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Thu, 23 Oct 2025 11:04:27 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/claude-rock-395i</link>
      <guid>https://forem.com/vukhanhtruong/claude-rock-395i</guid>
      <description>&lt;p&gt;I've built Claude Rock, a marketplace for Claude Skills.&lt;br&gt;
Its first skill is a Architecture Design that can generate complete, professional-grade architecture documentation — including diagrams, specs, and design rationales — in just minutes.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Runs a short &lt;strong&gt;5–7 question interview&lt;/strong&gt; to gather your system details&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generates a full &lt;strong&gt;11-section architecture doc&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creates C4 + data flow diagrams, OpenAPI specs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🗣️ &lt;strong&gt;How to chat with it:&lt;/strong&gt; Once installed, just talk to Claude naturally — for example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Create architecture documentation for my Node.js e-commerce app.” “Design a serverless architecture on AWS using Python.” “Update the architecture to include Redis caching.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude will ask you a few questions, then generate a complete, professional architecture document — including diagrams and best practices.&lt;/p&gt;

&lt;p&gt;⚡ &lt;strong&gt;Why it’s useful:&lt;/strong&gt; What normally takes hours now takes &lt;strong&gt;a few minutes&lt;/strong&gt; — perfect for dev teams, architects, or anyone standardizing documentation.&lt;/p&gt;

&lt;p&gt;💡 Quick install:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin marketplace add vukhanhtruong/claude-rock  
/plugin install architecture-design@claude-rock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;📘 &lt;strong&gt;Get the skill + guide:&lt;/strong&gt; &lt;a href="https://github.com/vukhanhtruong/claude-rock" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💾 &lt;strong&gt;Sample output:&lt;/strong&gt; Check out a &lt;a href="https://hackmd.io/@B0gg3-MvQL-KX7jvQ4KI8Q/rkErFMUCgl" rel="noopener noreferrer"&gt;Trello clone architecture doc&lt;/a&gt; generated by the skill.&lt;/p&gt;

</description>
      <category>claudeai</category>
      <category>claudeskills</category>
      <category>claudemarketplace</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Build a Note app with Clean Architecture and C4 Model</title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Tue, 04 Feb 2025 04:18:20 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/simple-note-app-built-with-clean-architecture-and-c4-model-dg1</link>
      <guid>https://forem.com/vukhanhtruong/simple-note-app-built-with-clean-architecture-and-c4-model-dg1</guid>
      <description>&lt;p&gt;If you did not read the previous post about &lt;a href="https://hihoay.substack.com/p/visualizing-software-architecture" rel="noopener noreferrer"&gt;how to visualize the software architecture with C4 model&lt;/a&gt;, I would recommend to read it to have a big picture of what/how this app was built.&lt;/p&gt;

&lt;p&gt;As the &lt;a href="https://vukhanhtruong.github.io/note-taker/master/decisions/" rel="noopener noreferrer"&gt;Architecture Decisions Records&lt;/a&gt; were approved, the tech stack will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean Architecture&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Prisma&lt;/li&gt;
&lt;li&gt;Cloudflare Workers with a D1 Database.&lt;/li&gt;
&lt;li&gt;Hono Framework&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;To help you better understand the concepts and see Clean Architecture in action, I’ve prepared a demo application for you. This demo uses the Note Taker App as a real-world example.&lt;/p&gt;

&lt;p&gt;Source code: You can explore the full &lt;a href="https://github.com/vukhanhtruong/note-taker" rel="noopener noreferrer"&gt;source code&lt;/a&gt; on GitHub. Feel free to clone the repo, experiment with the code.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://note-taker-staging.vukhanhtruong.workers.dev/" rel="noopener noreferrer"&gt;Frontend&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://note-taker-staging.vukhanhtruong.workers.dev/v1/docs" rel="noopener noreferrer"&gt;Swagger API documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Clean Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuuqtkphu1j6yzerh0q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuuqtkphu1j6yzerh0q9.png" alt="Note Taker App built with Clean Architecture" width="800" height="778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This diagram makes more sense to me compared to the original circular one. The color code is still consistent with the original. I hope it works for you too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clean Architecture is a set of rules that help us structure our application in such way that it will be easier to maintain and test. It’s kind of like a common language that helps developers understand each other.&lt;/p&gt;

&lt;p&gt;I would highly recommend to read &lt;a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt; book, it can elevate your understanding of software design to a new level. Here’s a quick summary based on my experience. Let me know your thought — feedback is always welcome:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;At high-level, Clean Architecture provides a structured and abstract way to interact with the core business logic, similar like how an ORM abstracts and organizes interactions with a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It prioritizes independence and loose coupling, allowing different parts of your system to function independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clean Architecture helps to organize the system with the core business logic at the center.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unlike traditional layered architectures (e.g., 3-Tier or N-Tier), Clean Architecture focuses on controlling dependencies to keep components decoupled and maintainable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The business logic is not couple to any framework, meaning you could later create a CLI or any type application without modifying the business logic. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All communication with business logic is facilitated through interfaces (abstractions).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testable - Since the business logic doesn’t rely on external dependencies, it’s easy to test. The Use Case Interactor (or just "Use Case")  is the primary location where you should focus on testing business logic and application rules. It is the core component that orchestrates and enforces the application's business rules, making it the ideal layer for concentrated testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Note Taker App
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project Structure (important ones only)
&lt;/h3&gt;

&lt;p&gt;How you organize your project is up to your team, as long as everyone stays on the same page and communicates effectively day to day. Here’s an example structure for this app: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;core&lt;/code&gt;: Contains reusable classes that can be used across multiple domains.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;controller/http&lt;/code&gt;: Whatever consuming the business logic will be here. In this demo, it’s the Hono framework.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;provider.ts&lt;/code&gt;: Manages dependency injection, setting up the DI container and modules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;prisma&lt;/code&gt;: Handles schema definitions and migrations using Prisma ORM.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;domain&lt;/code&gt;: The most critical folder—it contains the core business rules&lt;/p&gt;

&lt;p&gt;&lt;code&gt;entity&lt;/code&gt;: Holds the models &lt;/p&gt;

&lt;p&gt;&lt;code&gt;exceptions&lt;/code&gt;: Defines custom error handling.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interactor&lt;/code&gt;: Where business use cases are executed. Unit tests go here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;infra&lt;/code&gt;: Contains database implementations (e.g., D1 in this case) and third-party services.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;port&lt;/code&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;persistence&lt;/code&gt;: Acts as the Output Port in Clean Architecture. This is the repository interface, enabling the Use Case Interactor to query, save, or update data without knowing the details of the database implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;usecase&lt;/code&gt;: Acts as the Input Port in Clean Architecture. It abstracts how external layers (like controllers) interact with business logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;At first glance, Clean Architecture might seem like over-engineering, but it's really about creating discipline and predictability in your code base. By defining clear rules about where everything belongs, it simplifies feature development and makes your code easier to work with.&lt;/p&gt;

&lt;p&gt;Without structure, your code base will eventually turn into a mess, slowing down progress and forcing you to come up with rules the hard way. Clean Architecture saves you from that pain by providing a proven approach that’s been tested over time. Learn it once, and you can use it in any project, making your code maintainable and scalable from the start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should NOT apply Clean Architecture to every project. For projects with strict time constraints or smaller scopes, the added complexity may outweigh the benefits. Additionally, if team members are unfamiliar with Clean Architecture, the learning curve can slow development and reduce efficiency. It's best suited for larger, long-term projects where maintainability and scalability are critical.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start by applying Clean Architecture principles to a real-world project, just start with a small one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deepen your understanding of related concepts like SOLID principles, Domain-Driven Design (DDD).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explore advanced topics like Dependency Injection (DI), design patterns, and event-driven architecture to enhance your architectural skills.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cleanarchitecture</category>
      <category>c4model</category>
      <category>typescript</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Caching Problems You Should Know</title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Mon, 18 Nov 2024 03:53:30 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/lessons-learned-app-crash-since-caches-go-wrong-2odf</link>
      <guid>https://forem.com/vukhanhtruong/lessons-learned-app-crash-since-caches-go-wrong-2odf</guid>
      <description>&lt;p&gt;Caching is one of the most powerful tools to improve application performance and scalability, reduces back-end load, decreases latency, better user experience. However, it also comes up with challenges.&lt;/p&gt;

&lt;p&gt;As a developer, I’ve relied on caching to optimize application performance, one of my frequently used approach is Cache-Aside strategy - it’s simple, works well for most scenarios. Along the way, I’ve encountered issues like &lt;a href="https://en.wikipedia.org/wiki/Thundering_herd_problem#:~:text=In%20computer%20science%2C%20the%20thundering,able%20to%20handle%20the%20event." rel="noopener noreferrer"&gt;Thundering herd problem&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Cache_stampede" rel="noopener noreferrer"&gt;Cache Stampede&lt;/a&gt;, and several others, which make me to rethink how I handling caching.&lt;/p&gt;

&lt;p&gt;In this post, I’ll share my personal experiences with these problems, what went wrong, and how to resolved them.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Cache-Aside Strategy Works
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frya8al9v0ipm4ykzkwx7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frya8al9v0ipm4ykzkwx7.gif" alt="How cache-aside works" width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, the application will determine whether the item is currently held in the cache. Then if item is not available, it will read the item from the database (MySQL). After that, it will store a copy of the item in the cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  What went wrong
&lt;/h3&gt;

&lt;p&gt;One of my projects involved a high-traffic API for delivering editorial content. We used cache-aside strategy to store the content within a 5-minute expiration. It worked fine until it didn’t.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The popular contents expired at the same time&lt;/li&gt;
&lt;li&gt;The back-end is flooded with requests, struggling to handle the load.&lt;/li&gt;
&lt;li&gt;A huge number of requests reading the same key which had expired. Then, all of them directly read data from database, it just simply couldn’t keep up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Solutions
&lt;/h3&gt;

&lt;p&gt;After digging into the issue, it became clear that the back-end had scaled up to its maximum allowed capacity, while the database was overwhelmed by the surge in requests. This was leading to degraded performance or even system crashes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Thundering Herd Problem
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Workaround:&lt;/strong&gt; One of approaches is to use randomized expiration times for cache keys. This prevents them from expiring simultaneously. There are other solutions to solve this issue as well, and if you find it interesting, a quick googling will reveal many of helpful resources and solutions.&lt;/p&gt;

&lt;p&gt;Pseudo-code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffy9sfn2kcjj71gfjsd1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffy9sfn2kcjj71gfjsd1a.png" alt="resolve thundering herd problem" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Cache Stampede
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Workaround:&lt;/strong&gt;: Since I was using Redis as the caching layer, I tackled this problem by implementing a Redis &lt;a href="https://redis.io/glossary/redis-lock/" rel="noopener noreferrer"&gt;distributed lock&lt;/a&gt;. The lock ensures that only one process can update the cache at a time, while other processes must wait for the update to complete. This approach effectively prevents multiple processes from overwhelming the back-end simultaneously.&lt;/p&gt;

&lt;p&gt;Pseudo-code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few2jy06zxybhvg8rotxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few2jy06zxybhvg8rotxx.png" alt="resolve cache stempede by using redis distributed lock" width="800" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lesson Learned
&lt;/h3&gt;

&lt;p&gt;If you’re using caching, challenges like Thundering Herd, Cache Stampede, and others are inevitable. My experience has shown me that nothing is perfect, it’s better to have proper planning.&lt;/p&gt;

&lt;p&gt;Have you faced similar caching challenges? How did you overcome them?&lt;/p&gt;

</description>
      <category>cachingstrategies</category>
      <category>devmistakes</category>
      <category>thunderingherd</category>
      <category>lessonlearned</category>
    </item>
    <item>
      <title>Level up the quality of your javascript code base with Babel and ESLint. </title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Sat, 20 Apr 2019 10:36:27 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/level-up-the-quality-of-your-javascript-code-base-with-babel-and-eslint-2abj</link>
      <guid>https://forem.com/vukhanhtruong/level-up-the-quality-of-your-javascript-code-base-with-babel-and-eslint-2abj</guid>
      <description>&lt;p&gt;In this post, we will setup ESlint, Prettier to ensure that our code has the same format throughout this project. Babel is a transpiler that can turn our ES6 code into ES5. I’m going to assume you know how to use both node and npm and have them both installed on your machine.&lt;/p&gt;

&lt;h1&gt;
  
  
  Project Setup
&lt;/h1&gt;

&lt;p&gt;Create a directory and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For this tutorial, I will be adding an index.js file to the &lt;code&gt;src&lt;/code&gt; folder, and this will be our entry point. Our file directory should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-project/
|--src/
  |--index.js
|--package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Install Packages
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Nodemon
&lt;/h2&gt;

&lt;p&gt;Nodemon is a tool that helps develop Js/Nodejs based applications by automatically restarting the node application when file changes detected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;nodemon &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Babel
&lt;/h2&gt;

&lt;p&gt;Babel is a tool that is used to convert ECMAScript 2015+ code into a backward compatible version of JavaScript so that older browsers and environment will be able to understand your code.&lt;/p&gt;

&lt;p&gt;Run the following command to install babel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @babel/core &lt;span class="se"&gt;\ &lt;/span&gt;
            @babel/cli &lt;span class="se"&gt;\ &lt;/span&gt;
            @babel/preset-env &lt;span class="se"&gt;\&lt;/span&gt;
            @babel/node &lt;span class="se"&gt;\&lt;/span&gt;
            @babel/runtime &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, we need to tell babel how to transpile our files by creating a &lt;code&gt;.babelrc&lt;/code&gt; file in the root directory and adding the following code to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;presets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;[Optional] If you want to set up a custom alias for directories, specific files, or even other npm modules. Let's take a look to this handy &lt;a href="https://github.com/tleunen/babel-plugin-module-resolver"&gt;plugin&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ESLint + Airbnb JS style guide + Prettier
&lt;/h2&gt;

&lt;p&gt;These tools will be identifying, reporting and formatting on patterns found in ECMAScript/JavaScript code, with the goal of making the code more consistent and avoiding bugs.&lt;/p&gt;

&lt;p&gt;Run the following command to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;eslint &lt;span class="se"&gt;\&lt;/span&gt;
            eslint-config-airbnb-base &lt;span class="se"&gt;\&lt;/span&gt;
            eslint-config-prettier &lt;span class="se"&gt;\&lt;/span&gt;
            eslint-plugin-import &lt;span class="se"&gt;\&lt;/span&gt;
            eslint-plugin-prettier &lt;span class="se"&gt;\&lt;/span&gt;
            prettier &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Prettier Configuration
&lt;/h3&gt;

&lt;p&gt;Create the file named &lt;code&gt;.prettierrc&lt;/code&gt; in the root directory and adding the following code to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trailingComma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;es5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tabWidth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;semi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;singleQuote&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you'd like a JSON schema to validate your configuration, one is available here: &lt;a href="http://json.schemastore.org/prettierrc"&gt;http://json.schemastore.org/prettierrc&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eslint Configuration
&lt;/h3&gt;

&lt;p&gt;Create the file named &lt;code&gt;.eslintrc.json&lt;/code&gt; in the root directory and add the following code to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"extends"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"airbnb-base"&lt;/span&gt;, &lt;span class="s2"&gt;"plugin:prettier/recommended"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"plugins"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"prettier"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"rules"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"prettier/prettier"&lt;/span&gt;: &lt;span class="s2"&gt;"error"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;  
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Scripts
&lt;/h2&gt;

&lt;p&gt;Open up &lt;code&gt;package.json&lt;/code&gt; then add the following code to the scripts section&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;babel ./src --out-dir ./build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nodemon --exec babel-node src/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eslint .&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Integrated with VSCode
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;Prettier&lt;/a&gt; and &lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint"&gt;ESLint&lt;/a&gt; extensions&lt;/p&gt;

&lt;p&gt;Configure VS Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;..&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor.formatOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Check my &lt;a href="https://gist.github.com/vukhanhtruong/670c6b4d1c02a5798cb40a50762c7548"&gt;gist&lt;/a&gt; to find the final files. &lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>babel</category>
      <category>eslint</category>
      <category>prettier</category>
    </item>
    <item>
      <title>Things to remember when reinstall Ubuntu.</title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Sat, 19 Jan 2019 12:06:07 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/things-to-remember-when-reinstall-ubuntu-5c91</link>
      <guid>https://forem.com/vukhanhtruong/things-to-remember-when-reinstall-ubuntu-5c91</guid>
      <description>&lt;p&gt;This is just about my checklist when I reinstall the software on my machine. Hope you have find this useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backup the essential things.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The most important thing is the folder named &lt;strong&gt;~/.ssh&lt;/strong&gt;  where contains all my credentials to access to different servers. As you well know if you lost it, you have to re-generate keys and add them to Github, Gitlab, Bitbucket, etc. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all source code was backed up or pushed to the remote repository. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My favorite IDE is Visual Studio Code, and there are a lot of extensions was installed. All I need to do is backup the folder named &lt;strong&gt;.vscode&lt;/strong&gt; in my home directory &lt;code&gt;~/.vscode&lt;/code&gt;. If you were using another IDE, you should find out where the configuration store then saves it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I work with the terminal every day, so I have to backup the file named &lt;strong&gt;.zshrc&lt;/strong&gt; and the folder named &lt;strong&gt;.oh-my-zsh&lt;/strong&gt;, to avoid re-configuration the terminal and install a dozen of plugins.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  After finishing installing Ubuntu
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Move all the backed up folder to the same path like before. So, now my Linux environment similar to the old one. Definitely, it saves my time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the favorite apps. Here are my favorite applications, just focused on development.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  System
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 18.10 (current)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  IDE
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/"&gt;Visual studio code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Internet
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.google.com/chrome/"&gt;Chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rambox.pro/#home"&gt;Rambox&lt;/a&gt; All-in-one chat apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Terminal
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.zsh.org/"&gt;zsh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/romkatv/powerlevel10k"&gt;p10k&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neovim/neovim"&gt;neovim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tmux.github.io/"&gt;tmux&lt;/a&gt; and &lt;a href="https://github.com/tmuxinator/tmuxinator"&gt;tmuxinator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/robbyrussell/oh-my-zsh"&gt;oh-my-zsh&lt;/a&gt; A delightful community-driven (with 1,200+ contributors) framework for managing your zsh configuration. Below is my favorite plugins:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  zsh-completions
  zsh-autosuggestions
  zsh-syntax-highlighting
  history-substring-search
  git
  docker
  docker-compose
  dotenv
  nvm
  httpie
  rsync
  yarn
  tmux
  node
  helm
  composer
  minikube
  kubectl
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/amix/vimrc"&gt;vimrc&lt;/a&gt; — This configuration is the ultimate vimrc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/vim-plug"&gt;vim-plug&lt;/a&gt; — Plugins management.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sheerun/vim-polyglot"&gt;vim languages pack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/w0rp/ale"&gt;vim syntax checker&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;call plug#begin&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'~/.vim/plugged'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="s2"&gt;" Make sure you use single quotes

"&lt;/span&gt; On-demand loading
Plug &lt;span class="s1"&gt;'scrooloose/nerdtree'&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'on'&lt;/span&gt;:  &lt;span class="s1"&gt;'NERDTreeToggle'&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="s2"&gt;" Language pack for VIM
Plug 'sheerun/vim-polyglot'

"&lt;/span&gt; VIM check syntax
Plug &lt;span class="s1"&gt;'w0rp/ale'&lt;/span&gt; 

&lt;span class="s2"&gt;" Initialize plugin system
call plug#end()

"&lt;/span&gt; Shortcut key to open file explorer
nmap &amp;lt;F6&amp;gt; :NERDTreeToggle&amp;lt;CR&amp;gt;

&lt;span class="s2"&gt;" ALE linting tool
let g:ale_linters = {
&lt;/span&gt;&lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="s2"&gt;  'javascript': ['eslint'],
&lt;/span&gt;&lt;span class="se"&gt;\}&lt;/span&gt;&lt;span class="s2"&gt;

let g:ale_sign_error = '❌'
let g:ale_sign_warning = '⚠️'
highlight ALEErrorSign ctermbg=NONE ctermfg=red
highlight ALEWarningSign ctermbg=NONE ctermfg=yellow

let g:ale_fixers['javascript'] = ['eslint']

"&lt;/span&gt; Fix files automatically on save
&lt;span class="nb"&gt;let &lt;/span&gt;g:ale_fix_on_save &lt;span class="o"&gt;=&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  DevOps Tools
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/"&gt;docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/docker/compose"&gt;docker-compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/minikube"&gt;minikube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/GoogleContainerTools/skaffold/"&gt;skaffold&lt;/a&gt; A command line tool that facilitates continuous development for Kubernetes applications. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/kubernetes/kompose"&gt;kompose&lt;/a&gt; Converts Docker Compose to Kubernetes.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl"&gt;kubectl&lt;/a&gt; Command line interface for running commands against Kubernetes clusters.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ahmetb/kubect"&gt;kubectx&lt;/a&gt; Fast way to switch between clusters and namespaces in kubectl.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/garethr/kubeval"&gt;kubeval&lt;/a&gt; Validate your Kubernetes configuration files, supports multiple Kubernetes versions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/wagoodman/dive"&gt;dive&lt;/a&gt; A tool for exploring each layer in a docker image&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Utilities Dev Tools
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/sharkdp/fd/releases"&gt;fd&lt;/a&gt; - A simple, fast and user-friendly alternative to 'find'.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/chubin/cheat.sh#installation"&gt;cheat.sh&lt;/a&gt; The only cheat sheet you need.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jakubroztocil/httpie"&gt;httpie&lt;/a&gt; — Modern command line HTTP client — user-friendly curl alternative with intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.getpostman.com/"&gt;postman&lt;/a&gt; Postman Makes API Development Simple.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ngrok.com/download"&gt;ngrok&lt;/a&gt; or &lt;a href="https://github.com/localtunnel/localtunnel"&gt;localtunnel&lt;/a&gt; Exposes your localhost to the world for easy testing and sharing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/knqyf263/pet"&gt;pet&lt;/a&gt; — Simple command-line snippet manager.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tmux.github.io/"&gt;tmux&lt;/a&gt; — Terminal multiplexer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/gpakosz/.tmux"&gt;tmux config&lt;/a&gt; — The best tmux configuration.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dbcli/mycli"&gt;mycli&lt;/a&gt; — A Terminal Client for MySQL with AutoCompletion and Syntax Highlighting.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/typicode/json-server"&gt;json-server&lt;/a&gt; — Get a full fake REST API with zero coding in less than 30 seconds.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tsenart/vegeta"&gt;vegeta&lt;/a&gt; HTTP load testing tool and library.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/FiloSottile/mkcert"&gt;mkcert&lt;/a&gt; A simple zero-config tool to make locally trusted development certificates with any names you'd like.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/thlorenz/doctoc"&gt;doctoc&lt;/a&gt; Generates table of contents for markdown files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Troubleshooting
&lt;/h4&gt;

&lt;p&gt;If you got the following issue with ssh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sign_and_send_pubkey signing failed agent refused operation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following command to fix:&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;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ssh-agent &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ssh-add ~/.ssh/id_rsa
&lt;span class="nb"&gt;chmod &lt;/span&gt;700 ~/.ssh
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.ssh/id_rsa
&lt;span class="nb"&gt;chmod &lt;/span&gt;644 ~/.ssh/id_rsa.pub

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

&lt;/div&gt;



&lt;h5&gt;
  
  
  That's it. If you have anything to share, feel free to leave your comment.
&lt;/h5&gt;

</description>
      <category>ubuntu</category>
      <category>tips</category>
      <category>utilities</category>
      <category>tools</category>
    </item>
    <item>
      <title>Structuring Node.js Project</title>
      <dc:creator>Truong Vu</dc:creator>
      <pubDate>Thu, 22 Nov 2018 05:07:14 +0000</pubDate>
      <link>https://forem.com/vukhanhtruong/structuring-nodejs-project-204e</link>
      <guid>https://forem.com/vukhanhtruong/structuring-nodejs-project-204e</guid>
      <description>&lt;p&gt;If you are looking for the NodeJS project structure based on the best practices to build the RESTful API. It might be helpful for you guys. &lt;/p&gt;

&lt;p&gt;Some of the good practices followed in this repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code Style Practices via &lt;a href="https://github.com/i0natan/nodebestpractices" rel="noopener noreferrer"&gt;Node Best Practices&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ES6 Support.&lt;/li&gt;
&lt;li&gt;Morgan Logger.&lt;/li&gt;
&lt;li&gt;Error Handling.&lt;/li&gt;
&lt;li&gt;Open API Specification implemented through &lt;a href="http://apidocjs.com/" rel="noopener noreferrer"&gt;apidocjs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;JWT Authentication.&lt;/li&gt;
&lt;li&gt;Joi &amp;amp; Express Validation.&lt;/li&gt;
&lt;li&gt;Environment variables via &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Linting with Prettier.&lt;/li&gt;
&lt;li&gt;Security (Helmet, CORS, Express Brute).&lt;/li&gt;
&lt;li&gt;Husky as git hook for linting &amp;amp; running unit test before commit.&lt;/li&gt;
&lt;li&gt;Unit &amp;amp; E2E Testing with Jest.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jaredpalmer/backpack" rel="noopener noreferrer"&gt;Backpack&lt;/a&gt; build system&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;Node Package Management (&lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone the project &lt;code&gt;git clone git@github.com:vukhanhtruong/nodejs-api-boilerplate.git&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install dependencies &lt;code&gt;yarn install&lt;/code&gt; or &lt;code&gt;npm i&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Running Docker
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;docker-compose up -d&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Raven Log
&lt;/h2&gt;

&lt;p&gt;Create account at &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;, then put your url to &lt;code&gt;.env&lt;/code&gt; file at variable &lt;code&gt;SENTRY_DSN&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Api Doc
&lt;/h2&gt;

&lt;p&gt;Api Doc is hosted on &lt;a href="https://surge.sh/" rel="noopener noreferrer"&gt;surge&lt;/a&gt;. For change the url and have your own docs just modify your link in the &lt;code&gt;.env&lt;/code&gt; file. Running the following command to publish your documentation.&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;# Generate document&lt;/span&gt;
yarn doc
&lt;span class="c"&gt;# Deploy document to surge.sh&lt;/span&gt;
yarn doc:deploy

&lt;span class="c"&gt;# or&lt;/span&gt;
npm run doc
npm run doc:deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pre-Commit Hook
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;husky&lt;/code&gt; for linting your code before commit &amp;amp; running unit test before push.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scripts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  DEV
&lt;/h3&gt;



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

&lt;span class="c"&gt;# or&lt;/span&gt;

npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DEBUG
&lt;/h3&gt;

&lt;p&gt;Debug with VSCode. See &lt;a href="https://code.visualstudio.com/updates/v1_22#_node-debugging" rel="noopener noreferrer"&gt;VSCode Auto-Attach&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;yarn debug

&lt;span class="c"&gt;# or&lt;/span&gt;

npm run debug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  TEST
&lt;/h3&gt;



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

&lt;span class="c"&gt;# or&lt;/span&gt;

npm run &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If you have the issue with ENOSPC, run the below command to avoid:&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;fs.inotify.max_user_watches&lt;span class="o"&gt;=&lt;/span&gt;524288 | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/sysctl.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Test Watch
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;test&lt;/span&gt;:watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  COVERAGE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# run jest coverage&lt;/span&gt;
yarn &lt;span class="nb"&gt;test&lt;/span&gt;:cover

&lt;span class="c"&gt;# show html report&lt;/span&gt;
yarn &lt;span class="nb"&gt;test&lt;/span&gt;:cover:open

&lt;span class="c"&gt;# or&lt;/span&gt;

npm run &lt;span class="nb"&gt;test&lt;/span&gt;:cover

npm run &lt;span class="nb"&gt;test&lt;/span&gt;:cover:open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JSDOC
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# generate documentation&lt;/span&gt;
yarn doc

&lt;span class="c"&gt;# Publish documentation to surge.sh&lt;/span&gt;
yarn doc:deploy

&lt;span class="c"&gt;#or&lt;/span&gt;

npm run doc

npm run doc:deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find out &lt;a href="https://github.com/vukhanhtruong/nodejs-api-boilerplate" rel="noopener noreferrer"&gt;more here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>boilerplate</category>
      <category>bestpractices</category>
    </item>
  </channel>
</rss>
