Duy NG
フィード
Scripting tools - A Node.js friendly alternative to makefile
Duy NG
Article originally published at medium.comTL;DR#Using execa and commander is an alternative that can be considered for replacing makefile in a Node.js project.Introduction#At ekino, in some projects handled by our Node.js team, we heavily use Makefile to automate tasks such as testing,lints, Docker integration, code checking, deployment, Kubernetes management, load testing with K6, and all automating stuff.They have been our preferred tool for many years due to their simplicity, efficiency, and adaptability to various workflows.As our projects have grown, these files have become increasingly more complex and harder to maintain and understand, especially for team members who are not familiar with shell scripting.Because of these challenges, we've started looking into using JavaScript tools for automating tasks.Our goal is to simplify our processes, make them easier for everyone on the team to use, and see what advantages this new approach might bring.Challenges with makefile#While make
8日前
[Microblog] Display colors in Makefile
Duy NG
Display colors in Makefile#In a previous micropost, I shared how to create a help command in a Makefile.This time, let’s make it visually appealing by adding colors to the output.Here’s how to do it:# COLORSYELLOW = \033[33mGREEN = \033[32mWHITE = \033[37mRESET = \033[0mhelp: ##@helper Display all commands and descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\n${WHITE}Usage:${RESET}\n make <target>\n"} \/^[.a-zA-Z_-]+:.*?##@/ { \split($$2, parts, " "); \section = parts[1]; \description = substr($$2, length(section) + 2); \sections[section] = sections[section] sprintf(" ${YELLOW}%-15s${RESET} ${GREEN}%s${RESET}\n", $$1, description); \} \END { \for (section in sections) { \printf "\n${WHITE}%s${RESET}\n", section; \printf "%s", sections[section]; \} \}' $(MAKEFILE_LIST)YELLOW, GREEN, WHITE, and RESET are ANSI escape codes for terminal colors.\033[33m sets the color to yellow, \033[32m to green, and \033[37m to white.\033[0m resets the color to the terminal default.It formats the output w
14日前
[Microblog] Display all Makefile commands
Duy NG
Display all Makefiles commands#Makefiles can be hard to navigate, especially as they grow. Adding a help command makes it easy to see all available targets and their purposes.The magic help target#Add this awk snippet to your Makefile:.DEFAULT_GOAL := help.PHONY: helphelp: ##@helper Display all commands and descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\nUsage:\n make <target>\n"} \/^[.a-zA-Z_-]+:.*?##@/ { \split($$2, parts, " "); \section = parts[1]; \description = substr($$2, length(section) + 2); \sections[section] = sections[section] sprintf(" \033[36m%-15s\033[0m %s\n", $$1, description); \} \END { \for (section in sections) { \printf "\n\033[1m%s\033[0m\n", section; \printf "%s", sections[section]; \} \}' $(MAKEFILE_LIST)How it works#Use ##@ to group related targetsAnd place the description of each command after that groupExample Makefile#help: ##@helper Display all commands and their descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\nUsage:\n make <target>\n"} \/^[.a-zA-Z_-]+:.
15日前
[Microblog] Supercharge Git with fzf
Duy NG
Supercharge Git with fzf#Working with Git branches can be annoying, especially with long names or when cleaning up old ones. Try fzf, a tool that makes managing branches easy.Switch branches#Use fzf to select and switch branches interactively:git branch | fzf --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git switchDelete branches#Delete branch interactively with fzf:git branch | fzf -m --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git branch -dI setup them in my shell config to save time:alias gs="git switch"alias gsc="git witch -c"alias gsi="git branch | fzf --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git switch"alias gbd="git branch | fzf -m --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git branch -d"
16日前
[Microblog] Better Git log
Duy NG
Better Git log#The default git log output can be hard to read. Here’s how I make it more visual and informative using aliases.Add these aliases to the global .gitconfig:[alias] # Tree-like log with relative dates logs = log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset' # Limit to 20 commits log = logs -n 20Alternatively, set up aliases in your shell config:alias glog="git log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset' -n 20"alias glogs="git log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'"Example output* c0eb700 - (HEAD -> master, origin/master, origin/HEAD) chore(fish): update alias (woula 26 minutes ago)* 960e14f - chore(nvim): update plugins, active flash, disable cappuchine (woula 16 hours ago)* bc1129d - feat(nvim): add disabled plugins list (woula 3 days ago)* 6e14bad - feat(nix): update config for homebr
17日前
[Microblog] Managing multiple Git accounts
Duy NG
Managing multiple Git accounts#Working with multiple Git accounts (e.g., work, personal, open-source) can be tricky. Here’s how I manage them seamlessly using conditional includes in .gitconfig.Global .gitconfig setup#Add conditional includes to the global .gitconfig:[includeIf "gitdir:~/projects/company1/"] path = ~/projects/company1/.gitconfig[includeIf "gitdir:~/projects/company2/"] path = ~/projects/company2/.gitconfig[includeIf "gitdir:~/projects/oss/"] path = ~/projects/oss/.gitconfigLocal .gitconfig#In each project’s .gitconfig, specify the user and SSH key.Here is example for ~/projects/company1/.gitconfig[user] name = username1 email = [email protected][core] sshCommand = ssh -i ~/.ssh/company1_rsaGit will help us to automatically switch configurations based on the project directory.
18日前
[Microblog] Git aliases
Duy NG
Git aliases#Git aliases are a must have for every developer. They save time, reduce typing, and make your workflow more efficient.You can set them up in two ways: terminal shell aliases or .gitconfig.Terminal shell aliases#Here’s a part how I set up my Git aliases in my shell config (e.g. .zshrc or fish.config ...etc.):# Gitalias g="git"alias gc="git commit -m"alias gca="git commit -a -m"alias gp="git push origin HEAD"alias gpu="git pull origin"alias gpf="git push --force-with-lease"alias gst="git status"alias gs="git switch"alias gsc="git switch -c"alias gdiff="git diff"alias gco="git checkout"alias gcob="git checkout -b"alias gb="git branch"alias gba="git branch -a"alias gadd="git add"alias ga="git add -p"alias gre="git reset".gitconfig alias#Other way to manage git alias with global .gitconfig[alias] # List all aliases aliases = !git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g' # Command shortcuts st = status cm = commit -m co = checkout stl = stash lis
19日前
[Microblog] Run a command if there are unstaged changes
Duy NG
Run a command if there are unstaged changes#A quick one-liner to run a command only if there are unstaged changes: the --quiet flag of git diffThe flag does two things:Disables all output of the commandExits with 1 if there are differences, and 0 if there are no differences.That means you can combine it with boolean operators to only run another command if files have (or have not) changed:# Run `command` if there are unstaged changesgit diff --quiet || command# Run `command` if there are NO unstaged changesgit diff --quiet && commandOther tips#Check for untracked filesgit ls-files --others --exclude-standard | grep -q . && commandInclude staged changesgit diff --cached --quiet || commandCombine with entr for file watchinggit diff --quiet || entr -r commandUse in CI pipelinesgit diff --quiet || echo "Changes detected, running tests..." && npm test
20日前
[Microblog] List all files tracked by Git
Duy NG
List all files tracked by Git#Sometimes you need a list of all files tracked by Git—for example, when using tools like entr to watch files for changes. Instead of fiddling with find, Git provides a clean and concise command git-ls-files:git ls-filesThis lists all files in the repository that are tracked by Git.Other tips#Include ignored files:git ls-files --others --ignored --exclude-standardFilter by file type:git ls-files '*.js' # List only JavaScript filesUse with entr to watch files:git ls-files | entr -r your-command
21日前
[Microblog] Git Checkout vs. Git Switch
Duy NG
Git Checkout vs. Git Switch#git checkout#Switch branches:git checkout <branch> # Switch to an existing branchCreate and switch to a new branch:git checkout -b <new-branch> # Create and switch to a new branchRestore files from a specific commit or branch:git checkout <commit> -- <file> # Restore a file from a specific commitgit switch (modern alternative)#Switch branches:git switch <branch> # Switch to an existing branchCreate and switch to a new branch:git switch -c <new-branch> # Create and switch to a new branchKey differences#CommandPurposeNotesgit checkout <branch>Switch branchesOlder, more versatile command.git checkout -b <branch>Create and switch to a new branchCombines branch creation and switch.git checkout <commit> -- <file>Restore a file from a commitUseful for recovering files.git switch <branch>Switch branchesModern, focused alternative.git switch -c <branch>Create and switch to a new branchSimpler and more intuitive.When to use?#git checkout:Use for restoring files from a
21日前
[Microblog] Git Reset vs. Git Restore
Duy NG
Git Reset vs. Git Restore#git reset#Undo commits (keep changes staged):git reset --soft HEAD~ # Move HEAD but keep changes stagedgit reset --soft <commit> # Move to specific commit, keep changes stagedUnstage changes (keep changes in working directory):git reset HEAD~ # Reset --mixed (default), move HEAD and unstage changesgit reset <commit> # Reset --mixed, move to specific commit and unstage changesgit reset HEAD <file> # Unstage a specific fileDiscard commits and changes (destructive):git reset --hard HEAD~1 # Discard commits and changes permanentlygit restore#Discard working directory changes:git restore <file> # Revert file to its state in the last commitUnstage changes:git restore --staged <file> # Move changes from staging area to working directoryRestore a file from a specific commit:git restore --source=<commit> <file> # Restore file from a specific commitKey differences#CommandBranch pointerStaging areaWorking directorygit reset <commit>MovesResets (unstages)Unchangedgit rese
22日前
[Microblog] Ingore all .DS_store files globally
Duy NG
Ignore all .DS_Store files globally#If you use Git on a Mac, you’ve probably accidentally committed a .DS_Store file to a repo at least once. I used to add .DS_Store to every .gitignore file to avoid this, but there’s a better way!You can create a global .gitignore file that applies to all your repositories. Just run this command:git config --global core.excludesFile '~/.gitignore'Then, add .DS_Store to your ~/.gitignore file:echo ".DS_Store" >> ~/.gitignoreThis command adds the following to your ~/.gitconfig:[core] excludesFile = ~/.gitignoreNow, .DS_Store files will be ignored across all your projects, no more accidental commits!You can directly edit the ~/.gitignore file to globally ignore many other files.
23日前
[Microblog] Update all Git submodules to latest commit
Duy NG
Update all Git submodules to the latest commit#If you use Git submodules often, here's the one-liner to update them to the latest commit on origin (since Git 1.8.2):git submodule update --remote --rebasePrefer merging? Swap --rebase for --merge.
24日前
[Microblog] Run Github actions locally
Duy NG
Run Github actions locally#Run GitHub actions locally with act to skip the long feedback loop! It uses Docker to pull images and run workflows right on your machine.# Run the `push` eventact# Run a specific event or jobact pull_requestact -j test_unitNeed a GitHub token? Use the -s flag with the GitHub CLI:act -s GITHUB_TOKEN="$(gh auth token)"Quick, easy, and no more waiting for GitHub to run workflows!
25日前
[Microblog] First attempt at migrating from Homebrew to Nix with Nix Home Manager
Duy NG
First attempt at migrating from Homebrew to Nix with Nix Home Manager#It didn’t go exactly as planned. I dived into Nix scripts, flakes, and started installing packages with nixpkgs while keeping Homebrew on the side.But... nothing seemed to work correctly. 😵Tools like fish shell, fzf, and ghostty .etc... didn't work.I probably need to configure each program properly, manage environments, and link the ~/.config files with Nix...During the migration, I enabled autoCleanUp Homebrew with "zap" without paying close attention. Big mistake! It wiped out everything I’d installed through Homebrew. 😱 Aie aie aie.Thankfully, I had saved all my tools in a Brewfile in my dotfiles. A quick brew bundle restored everything (though it took time to install).Lesson learned: I need to take it step by step with Nix, learning more about proper configurations before jumping in too deep.For now, I’m sticking with Homebrew but I’ll give Nix another try someday.
1ヶ月前
[Microblog] Tilting window management on macOS with aerospace
Duy NG
Tiling window management on macOS with aerospace#In the past, I was a rectangle user. I used it to move windows into corners or split the screen, basic functionality. Honestly, it never felt transformative. It was fine, but quite basic. I only used it during screen-sharing sessions on Teams calls. I always wanted something more controllable and better organized, with groupings of applications.Recently, I explored raycast, and at first, it seemed like the solution I had been looking for. It offered intuitive window organization, powerful workspace controls, and a lot of cool features.That’s when I came across aerospace, thanks to all the people sharing it on YouTube. And wow! This is the tool I was looking for! (powerful, free, open-source, workspace management simple, entirely keyboard shortcuts)Using aerospace has completely transformed my workflow. I now have workspaces neatly organized by task coding (C), terminal (T), browser (B), music (M)... and switching between them is really s
1ヶ月前
[Microblog] Manage better for my dotfiles.
Duy NG
Manage better for my dotfiles#Up until now, I’ve been handling my dotfiles manually with a Makefile and shell scripts.I used commands like rsync to mirror files from my ~/.config directory to my ~/dotfiles folder,and then saved everything on GitHub. While this approach worked, it was tedious and had a lot of limitations:rsync wouldn’t handle deletions properly, so if I deleted a file in ~/.config, it wouldn’t be removed from the dotfiles folder.I had to run make sync every time I wanted to update my dotfilesRestoring configurations wasn’t properly handledI also wanted to directly manage the ~/.config folder with Git, but my current setup didn’t make that easy.Then, I stumbled across a YouTube video about using GNU Stow to manage dotfiles.It’s such a simple yet powerful tool! Stow creates symlinks from your dotfiles folder to your ~/.config directory,so there’s no need for manual mirroring. Everything stays organized and up-to-date automatically.Now, I manage my ~/dotfiles easily with S
1ヶ月前
[Microblog] CLI tools I love using
Duy NG
CLI tools I love using#I’m a huge fan of Rust, and it’s no surprise that many of the tools I rely on in the terminal are written in rust.Here’s a quick rundown of my favorites:Fzf: Fuzzy finder that makes searching files or commands a breeze.Eza: A modern, colorful alternative to ls that adds more functionality.Zoxide: A smarter cd command that remembers your most-used directories.Fish shell: A user-friendly shell with auto-suggestions and syntax highlighting.Starship prompt: Fast, customizable prompt with support for all major shells.Ripgrep: Lightning-fast search tool, a must-have for large codebases.Sd: Simpler, more intuitive replacement for sed.Fd: Faster, friendlier alternative to find with colorful output.Jq: Power tool for processing JSON data in the terminal.Lazygit: Terminal-based Git interface, perfect for lazy devs.Lazydocker: Easy-to-use terminal tool for managing Docker containers.Bat: Better cat with syntax highlighting and line numbers.Git-delta: Enhanced git diff tool
1ヶ月前
[Microblog] Returning to Neovim for Coding
Duy NG
Returning to Neovim for coding#I’ve started using Neovim for coding again.Early in my career, like many others, I tried to learn Vim. At first, it was difficult to get used to, but I found it fun and rewarding. For some, Vim can feel more "professional," and there's something satisfying about the cool things you can do with it.I really liked Vim, but when it came to coding, I ran into many challenges. Configuring Vim with the right plugins, settings, and workflows took a lot of time. Back then, I was working with many different languages—Python, Ruby, JavaScript, TypeScript, HTML, CSS—and I could never quite get Vim to work smoothly across all of them. I faced too many issues, so eventually, I switched to VSCode and IntelliJ for most of my coding, using Vim only for occasional file edits.Now, with modern terminals like Wezterm and Ghostty, I find myself enjoying the terminal environment more. I want to keep my hands on the keyboard as much as possible, so I decided to give Vim another
1ヶ月前
[Microblog] Ghostty?
Duy NG
Ghostty?#Ghostty has just released its official production-ready version: 1.0, and it’s causing quite a hype among developers across all platforms. I’m really curious to try it out!Ghostty is a terminal emulator built with Zig. Most terminal emulators I’ve used, like WezTerm, Warp, Alacritty, and Zellij, are written in Rust. So it’s exciting to see a terminal tool developed in Zig instead.(I really like both of 2 this languages: rust and zig)I decided to give it a shot, even though I’ve been happily using WezTerm. And I have to say, I’m impressed.It’s fast—faster than WezTerm in terms of startup time and when opening new tabs. It integrates smoothly with Fish shell, which I love.The keybindings are easy to access, and the setup process is a really simple. Plus, it supports a variety of themes.Some standout features include Quick Terminal and the ability to use Cmd + Triple-click for selection—simple yet powerful.So, I’ve made the switch. My terminal is now Ghostty.
1ヶ月前
[Microblog] I’ve started implementing microblog on my website
Duy NG
I’ve started implementing microblog on my website#The goal is to create a space for sharing shorter updates, thoughts, and progress on ongoing projects. I plan to update this space regularly with useful insights and updates.Stay tuned for more posts soon.
1ヶ月前
Support dual package in npm - the easy way
Duy NG
JavaScript is evolving rapidly. Now, it’s really important for libraries to work with both CommonJS (CJS) and ECMAScript Modules (ESM).In this article, we’ll guide you through an easy and practical approach to handle dual-package support. That means more people can use your library, and it’s easier for them to do so.TL;DR#Create a dual-package TypeScript library supporting both ESM and CommonJS:Understand the different of Javascript file extensions: .js, .mjs, .cjsUse only the .js extension for both esm and cjs outputs after compilationWrite source code Typescript in ESMAvoid external build toolsDefine the exports field in package.jsonCompile source files into lib/esm and lib/cjs directories.Add package.json files with the correct type field in lib/esm and lib/cjsPlace a package.json file in lib/esm with {"type": "module"}Place another in lib/cjs with {"type": "commonjs"}Understanding Javascript file extensions#Firstly, we need clarify the different extensions in JavaScript:.cjs: files
3ヶ月前
Essential tsconfig.json options you should use
Duy NG
The tsconfig.json file in TypeScript is more than just a list of settings. It's a tool to manage how your code behaves, how secure it is, and how well it works with other systems. Whether you're an experienced TypeScript user or new to the language, understanding these configuration options will help you build a strong, efficient, and easy-to-maintain codebase.TL;DR#Here’s a quick look at recommended best-practice settings for your tsconfig.json. These options will help improve build speed, enforce code safety, enhance debugging, and ensure compatibility:{ "compilerOptions": { "incremental": true, // Enables incremental compilation, build only the changed code "strict": true, // Enables all strict type-checking options (best practice) "rootDir": "src", // Root directory of input files "outDir": "./build", // Output directory for compiled files "allowJs": true, // Allows JavaScript files to be compiled alongside TypeScript files. "target": "es6", // Specifies the ECMAScript target versi
3ヶ月前
Migrate to ESLint 9.x
Duy NG
Have you updated your ESLint setup to version 9.x? This version includes many breaking changes. Two major changes you need to consider are:Node.js < v18.18.0 and v19 are no longer supported.Flat config is now the default and has some changes.Flat config#ESLint's new flat config system makes setting up easier by using just one JavaScript file (named eslint.config.js, eslint.config.mjs, or eslint.config.cjs). This is different from the old way, which used several different files like .eslintrc* and the package.json.Here is a simple comparison between legacy config and flat config:AspectLegacy ConfigFlat ConfigSources.eslintrc .js, .json, .yml, package.json, etc.eslint.config.js .cjs, .mjsConfiguration styleConvention-based extendsExplicit native importsPlugin definitionPackage-named pluginsPlugins are objectsInheritance treePotentially complexComposable and traceableBenefits of the flat configPerformance: Reduced overhead due to a single configuration source.Maintainability: Easier to ma
7ヶ月前
Why you might be using Enums in TypeScript wrong
Duy NG
The topic of using enums in TypeScript has been discussed a lot, but many developers still remain unaware of their drawbacks. Even though enums are popular and commonly used, they might not always be the best choice. In this article, I'll share my thoughts on why enums can be a problem and show you a better way to do things.TL;DR#enum is a TypeScript-only feature and doesn't exist in JavaScript.enum has several problems:The compiled output can be hard to read and understand, leading to potential bugs.Performance impacts due to runtime creation and initialization.Compatibility issues with type declarations, especially in projects using isolatedModules.Use as const with a generic type helper: export type TypeFrom<T> = T[keyof T] for a simpler, more efficient alternative.If you are a TypeScript developer, you’re likely familiar with using enums. However, have you ever considered what enums in TypeScript actually represent? It's worth noting that JavaScript doesn't have the enum feature.It
8ヶ月前
Should you switch to Deno?
Duy NG
Hi there!Deno, created by Ryan Dahl, the original mind behind Node.js, is a modern runtime for JavaScript and TypeScript. It addresses various limitations and issues found in Node.js.Since its initial stable release with version 1.0, Deno has continued to evolve, with the latest version currently at 1.44. Are you ever curious about Deno's suitability for production projects today? Wondering if developers are actively using it in production?You can read my full article for a detailed analysis here: Should You Switch to Deno?.I hope this helps you make an informed decision. Happy coding!
8ヶ月前
My blog now offers full-text RSS feeds
Duy NG
Guess what? My blog now offers full-text RSS feeds!Not long ago, I discovered a new way to get updates RSS feeds from websites using a reader app. It might seem strange, right? Most people probably already know about this method since it has existed for a long time, but I had no idea about it before. I only knew how to subscribe to newsletters via email.For the past two years, I've been reading a lot more, especially on daily.dev, a platform where people share interesting articles. I've found many new blogs that I want to follow and subscribe to. I don’t remember exactly where I learned about subscribing to RSS feeds, but it was probably from a "subscribe" or "newsletter" tab on a blog, maybe tonsky.me. They explained how to use a reader app to subscribe to RSS feeds. It's totally free and really cool! So, I started using that method to subscribe to other blogs. It's much easier than using email. My blog also supports RSS feeds via atom.xml.However, there's one important thing to menti
8ヶ月前
Transforming website images into WebP with Rust for faster loading times
Duy NG
Hi everyone 👋,Recently, I attended Ekinoday, our company’s annual conference, where my colleagues share knowledge on various topics, from technology to life tips. This event is always very interesting for me.I had a chance to talk with my colleague Raphaël Tho Vo, who gave a presentation on optimising web performance. Raphaël mentioned that many people don’t realise how much image size and format can effect the web performance. Large image files can slow down a website significantly, affecting user experience.Raphaël explained that we can improve performance by using better image formats. He mentioned several modern formats like AVIF, WebP, JPEG 2000. Among these, AVIF and WebP are the most supported by web browsers today.Inspired by Raphaël’s advice, I decided to take a closer look at my website's performance. I host my site on GitHub, using Zola, a static site engine, along with the Tabi theme. This theme is beautifully designed and well-coded.I tested my website with PageSpeed Insi...
8ヶ月前
Dynamic Github profile with Bun and Typescript
Duy NG
In a recent article, I discussed transforming a GitHub profile into an interactive space with icons, badges, and dynamically updated blog posts using Python scripts and GitHub actions.After sharing my work in the "r/javascript" community on Reddit, I received serveral positive feedback and upvotes. I chose to post in this community due to my familiarity with JavaScript and TypeScript. After several hours, moderators removed my post because it wasn't directly related to JavaScript. They made the right decision, and I appreciate their careful moderation of the community. This made me rethink my approach and think about using a language that would better connect with the audience, given the simplicity of the script's principle: fetching feed URL, parsing it, and writing the response to the README.md file, along with automatic updates using a cron job on GitHub action.I decided to explore using JavaScript or TypeScript for this idea. While JavaScript would have been sufficient, I opted for
9ヶ月前
How I made my GitHub profile README dynamic
Duy NG
Have you heard about GitHub profile READMEs?Did you know you can add a README to your GitHub profile to tell others about yourself and create a really cool profile?To do that, you simply create a repository with the same name as your GitHub username. For more details on how to do this and how it works, check out GitHub's guide on managing your profile README.Now, how can you customize it to make a cool GitHub profile?There are numerous ways to do this. Some people design their profiles using HTML and CSS because README.md files are written in markdown, which supports them. Many individuals add more icons and badges to enhance the appearance. You can find various ideas and tools in the repository awesome-github-profile-readme.Here are a couple of examples of cool profiles:JessicaLim8WaylonWalkerHowever, for me, making something dynamic in the README is even cooler. This means displaying information about repositories, stars, languages written, followers, and more. To achieve this, we of
9ヶ月前
New home for my website
Duy NG
Hey there, it's been quite a while since my last article—almost 3 years. I'm not sure if anyone is still reading my posts because I've stopped using analytics for my website. Now, I've moved it to GitHub and use the free domain of GitHub Pages. It might not be great for SEO, but I'm happy with it. After all, the main reason I write is for myself. Each time I write, I learn something new and improve my skills on various topics.So, I've decided to get back into the habit of writing regularly. It's a good practice for developers to improve day by day.But first things first: I need to update my website. In the past, I usually used Jekyll to create my site. It runs on Ruby and used to fit my needs perfectly because it's free, powerful, and offers many themes for customization.For my main website where I display my work, projects, and some information about me, I used Jekyll but did a lot of customization using SCSS. And for the blog, I used a customized theme named "Ghost." It looks really
9ヶ月前
Start a new journey
Duy NG
Hey everyone! I'm excited to share my journey from being a BIM engineer to becoming a full-time developer.In modern construction, digital technologies are being used more and more. A big development is Building Information Modeling (BIM), which involves putting a lot of information about things like materials, planning, costs and more into 3D models.As a BIM engineer, my main job was to make sure this process worked well, fast, and effectively for different construction teams, like architects, engineers, and planners. My aim was to keep high-quality models that each team could use again, reducing the need to do things over. We mainly used a software named Revit for this.To do high-quality work, I used my skills in programming to make processes automatic. So, I spent time writing scripts and plugins in languages like VBA, C#, and Python to make things easier for my company.Balancing two different roles at the same time was complicated. Since learning programming is a big challenge, it m
4年前
Why use Docker compose
Duy NG
What is Docker compose?#If you read this article, I think you maybe already understand what is Docker.Docker is a tool which helps to create, deploy, and run applications by using containers. Docker provides developers and operators with a friendly interface to build, ship, and run containers on any environment.With the docker-cli, we can run and execute the Docker container via Dockerfile. But with Dockerfile, we can work only with a container, but in the project, we normally work with multiple containers. In that case, we need to use Docker compose.Docker Compose define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment. It get an app running in one command by just running docker-compose up.Docker compose uses the Dockerfile if one add the build command to your project’s docker-compose.yml. Your Docker workflow should be to build a suitable Dockerfile for each image you wish to create, then use compose to assemble the image
4年前
Create simple web app Nodejs with Docker
Duy NG
How to get a Node.js application into a Docker container?Steps to create a web application Nodejs with Docker#Create NodeJS web appCreate a DockerfileBuild image from DockerfileRun image as containerConnect to web app from a browserGetting started#Create root folder of project#$ mkdir simple-nodejs$ cd simple-nodejsInit package.json#$ yarn init -yAdd dependencies and scripts in this package.json file{ "name": "simple-nodejs", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "start": "node index.js", "dev": "nodemon index.js" }, "dependencies": { "express": "*", "nodemon": "*", "dotenv": "*", "mongoose": "*", "axios": "*" }}Create index.js file (in root project)#Add the following code to run server nodejs with express framework.const express = require('express');const app = express();app.get('/', (req, res) => { res.send('Hi there!');});const port = process.env.PORT || 3000;app.listen(port, () => { console.log(`Server is running on port ${port}`);});Create Dockerfi
4年前
Config ESLint, Prettier for React App in VSCode
Duy NG
As a developer, you will understand how important of quality of code in your project. ESlint and Prettier are great tools helps you for formatting and style of code.In this article, you will understand how to setup ESLint & Prettier in your React project and on text-editor VSCode.What are ESLint and Prettier?#ESlint#It is a static code analyzer, that means it tells you errors and mistakes that you may make while you are developing.These errors can be stuff like -Simple syntax errors eg. not closing a function declaration with }.Dead code detection eg. unused variables, code written after a return statement.Violating code guidelines, these are rules defined by yourself or a combination of predefined standards like the Airbnb styled guide or Google's style guide etc.Prettier#Prettier is a code formatter, it's only concerned with how your code looks, do you want ensure consistent indentation in the entire project?Do you want to ensure there're no semicolons in the project? Make your promi
4年前
Setup Webpack React TypeScript
Duy NG
How to setup a React project with Webpack and TypeScript?With create-react-app, it only takes a few clicks to create a complete React project, requires not in-depth knowledge of webpack or babel. But if you are still not satisfied with the features that create-react-app brings. For example, CSS does not show source-map when dev, or may be you simply configure more deeply. If in this case, It's the time to configure manually webpack.If you do not have any knowledge about webpack, you can refer my two previous articles:Setup basic webpackWebpack & TypeScriptInit project#Install dependencies packages$ yarn init -y$ yarn add -D react react-dom redux react-redux react-router-dom typescript$ yarn add -D webpack webpack-cli webpack-dev-server style-loader css-loader sass sass-loader typescript ts-loaderInstall plugin for webpack$ yarn add -D clean-webpack-plugin compression-webpack-plugin copy-webpack-plugin dotenv-webpack html-webpack-plugin mini-css-extract-plugin webpack-bundle-analyzercle
4年前
Setup Webpack TypeScript
Duy NG
How to setup a webpack project with TypeScript?We continue from the previous article basic setup webpack. In this article, we will discover how to setup a webpack project with TypeScript and using plugin in Webpack.Install webpack and loaders packages#Create new project and install packages dependencies$ mkdir webpack-typescript$ cd webpack-typescript$ npm init -y$ yarn add webpack webpack-cli webpack-dev-server style-loader css-loader sass sass-loader file-loader -DTo understand each dependencies means, checkout my previous article basic setup webpackInstall HTMLWebpackPlugin$ yarn add html-webpack-plugin -DThis plugin will help use import automatically the new bundle.js file after build into index.html build file. You will see more explanation below.Install TypeScriptTypeScript extends JavaScript by adding types. By understanding JavaScript, TypeScript saves you time catching errors, debug adn providing fixes before you run code. Any browser, any OS, anywhere JavaScript runs.We can u
4年前
Basic Setup Webpack
Duy NG
Webpack fundamentals for fast learning and step by step to setup a project with webpack.Webpack basics#Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging ...Check more information on Webpack websiteSetup a webpack project#Create project and init package.json file$ mkdir webpack-basic$ cd webpack-basic$ npm init -yIn the root project create public folder and index.html file<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="root"> <h1>Webpack basic</h1> </div> <script src="../dist/bundle.js"></script> </body></html>Setup Babel#Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.See the website babeljs.io for more information.Installa
4年前
Syntax Python vs Javascript
Duy NG
Programming in a new language can feel unfamiliar, intimidating, and tricky to navigate at first. There are new rules, syntax, and nuances to learn.Python vs. JavaScript Language Basics#JavaScript and Python are interpreted programming languages, meaning their runtime environments use an interpreter (or engine) that parses and executes code one statement at a time.The two languages are also “object-based” — everything is (or can be treated as) an object: strings, numbers, data structures, functions, etc.Primitive Types#First up, JavaScript and Python have similar built-in data types. For example, both use numeric data types (integers and floats), strings and Booleans.// JavaScript data typesconst pi = 3.14;const age = 31;const greeting = "good morning";const isAdmin = true;# Python data typespi = 3.14age = 13greeting = "good morning"is_admin = TrueType Checking and Conversion#Python and JavaScript are “dynamically typed” languages, which means you do not have to set the type of a varia
4年前
Better In Ruby - 02
Duy NG
Some tips you probably don't know in Ruby - 02In this article, I want to show you some nice Ruby features that you may know or not. Anyway, it’s a quick read and it’s always interesting to learn new stuff, right?!Create a hash from a list of values#You can create a hash from a list of values by using Hash[...]. It will create a hash like below:Hash['key1', 'value1', 'key2', 'value2']# => {"key1"=>"value1", "key2"=>"value2"}Lambda Literal ->#Lambda Literal is a anonymous function like lambda in python, => in JS or C#, allows you to create lambda easily.a = -> { 1 + 1 }a.call# => 2a = -> (v) { v + 1 }a.call(2)# => 3Double star (**)#The double star is a neat little trick in Ruby. See the following method:def my_method(a, *b, **c) return a, b, cenda is a regular parameter. *b will take all the parameters passed after the first one and put them in an array. c will take any parameter given in the format key: value at the end of the method call.See the following examples:One parametermy_metho
4年前
Better In Ruby - 01
Duy NG
Some tips you probably don't know in Ruby.Today, I will make a series that I learned about tips and tricks in ruby.Assigning the rest of an array to a variable#When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern a = [1, 2, 3] b, *rest = *a b # => 1 rest # => [2, 3] a # => [1, 2, 3]Word array#When we want to add a separator in the string%w{This is a string, I want to separate by a comma} * ", "# "This, is, a, string,, I, want, to, separate, by, a, comma"Concate array#[1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3] # truenew_array = Array.new([0], 5) # [0,0,0,0,0]Format decimal#number = 9.5"%.2f" % number # => "9.50"number.round(2)Remove a folder#This is a relatively common job of developer. There a many different ways to delete a folder and this is one of the shortest and fastest way to do:require 'fileutils'FileUtils.rm_r 'somedir'Massive assignment#Massive assignment allow us to declare many variables at the same timea,b,c,
5年前
Rails 5 or Rails 6 ?
Duy NG
What version of rails you use in your projects, today?At THP, when we start learning rails, we are required to install rails version 5.2.3. But I when I see that the new version of rails has been released is already 6.0. So we have posed a question for our technical manager of THP:Why we don't install directly the version rails 6.0?And he said: "One word: webpack. I always don't understand so much for the "webpack", and I need to search more on the internet. And with this article (this is not mine), we will know some advantages and new features of rails 6 .I hear that: Rails 5 is still just fineRails 5.0.Z is still on the severe patches list, and Rails 5.2.Z is still receiving regular security updates; so you're still OK on Rails 5 (especially 5.2 or higher)Now We will see 4 amazing features of rails 6.Parralled Testing#Test’s performance is finally going to be improved (a lot!). Now you can use cores to your advantage of running big tests much faster. Each testing worker runs in its o
5年前
How to switch to another Rails version
Duy NG
When you need to use multiple versions of Rails on your computer, how do you switch between them?Installation rails#Before I talk about how to switch a version of rails, I will go quickly how to install the different versions of rails. The ruby package manager that I'am using is rbenv and I will use it for this tuto.If you are using another ruby package manager like rvm, you should look at rbenv and its advantage. rbenv is more lighter and faster than the rvm and rbenv is very recommended by a a lot of developers.There is an article on dev.to help you understand more clearly: Why and How I Replaced RVM with RBENV.Ok, now go on our article.To install whatever version(s) of rails you want:gem install rails -v 6.0.3.2To know all rails versions released, you check out on all rails versions.You can also do it with your terminal with the command line gem list rails --remote --all | grep "^rails ".I you want to install rails on another version of ruby, you need to switch version of ruby and r
5年前
Build your personal website without spending any money
Duy NG
In this article, we'll walk through how to set up a Jekyll-powered blog using the Minimal Mistakes theme.It’s not always clear why we need a personal website, but here’s the truth, especially for developers: a website is an effective medium to let the world know who we are, what we are capable of, and what our values are.The purpose of the website you want to build can vary; it could be a blog, portfolio, landing page, or multi-purpose site. In my case, I need a website to:Showcase my projectsBlog about my experiences, my knowledge in programming, and my other interestsShare information about me that would be of interest to a recruiter, including my resume, email, and links to my GitHub, Medium, and LinkedIn pagesBeing able to easily generate and publish blog posts is another extremely beneficial feature, though not required.Initially, I tried to create my website using HTML, CSS, and serving it with GitHub Pages. However, I realized it would take a lot of time to complete, not to ment
5年前
Simple coding challenges with Ruby - 03
Duy NG
Doing coding challenges is an excellent way to imporve your programming language & problem-solvings skills.I'am learning and trying to improve my English. So I'm really sorry if my grammar mistakes annoy you. Thank you for your understanding.Kata challenges#My level on codewars now is 5kyu. You can check my Codewars. So, today when I take the new challenges with the option rank up, Codewars gave me only the 5kyu challenges.Let's take a look together!1. Rot13 (5kyu)#The first challenge today is still handle string. There are too many string algorithms. Maybe in the next day, I will choose the challenges by subject. For example, I will learn the OOP soon. So I think I will choose the katas in this subject.Now, we will go to solve the challenge.:bell: Task: Rot13ROT13 is a simple letter substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet. ROT13 is an example of the Caesar cipher.Create a function that takes a string and returns the string ciphere
5年前
Simple coding challenges with Ruby - 02
Duy NG
Doing coding challenges is an excellent way to imporve your programming language & problem-solvings skills.I'am learning and trying to improve my English. So I'm really sorry if my grammar mistakes annoy you. Thank you for your understanding.Kata challenges#In the last article, we have done the very simple challenges. Now we will challenge in the next level with the 6kyu challenges.1. Replace with alphabet position (6kyu)#All the next challenges have distributed random by codewars.:bell: Task: Replace with alphabet positionIn this kata you are required to, given a string, replace every letter with its position in the alphabet. If anything in the text isn't a letter, ignore it and don't return it."a" = 1, "b" = 2, etcFor examplealphabet_position("The sunset sets at twelve o' clock.")Should returnShould return "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11" (as a string):arrow_right: My solution:This challenge is always handle with the stringOne thing that we ne
5年前
Simple coding challenges with Ruby - 01
Duy NG
Doing coding challenges is an excellent way to imporve your programming language & problem-solvings skills.I'am learning and trying to improve my English. So I'm really sorry if my grammar mistakes annoy you. Thank you for your understanding.The Hacking Project (THP)#You may be asking: "What is The Hacking Project?"The Hacking Project (THP) is a type coding bootcamps within 12 weeks for the full-stack web development on Ruby & Ruby on Rails. The Hacking Project has been created in France since 2017 to help the people who want to learn a new coding skills, who want to create a startup or even for the people who want to make their career change into web development.In 12 weeks, you will learn how to create a web application with the front-end skills (HMLT, CSS, JavaScript), the back-end skills with Ruby, Ruby on Rails and many others skills in IT developement.This bootcamps is now free for every one. It's very impressive, isn't it?If you interessed in THP, you can check out the website T
5年前