All Blog Posts

Ola Mundo

Olá Mundo! (Hello World!) Welcome to my page This is a sample markdown page that demonstrates various markdown features. Text Formatting You can write text in bold, italic, or both. You can also use ~~strikethrough~~ text. Lists Here's an unordered list: First item Second item Third item with a link Numbered list: 1. First step 2. Second step 3. Third step Code Example Here's an inline code example: `console.log('Hello World!')` And a code block: def greet(): print("Hello, World!") Quote > This is a blockquote. > It can span multiple lines. Table | Header 1 | Header 2 | | -------- | -------- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 |

by John Doe
text
markdown
sample

Use Git Hooks

in the last blog, I mentioned to use git hooks to format my code before commit. surprisingly, it's not hard to do it. the native way to use git hooks is to edit the `.git/hooks` directory, but it's not recommended since .git folder is ignored by git, it will cause troubles when other guys commit. so i use husky, this is a git hook tool specially for js users. After getting started, you can see the husky is working. by the way husky doc mentions there is another useful tool called lint-staged, it will run the lint command for different file formats concurrently, but for my current project, i don't need it since I got over 99% code in typescript. Extra Q: I run my lint command as a part of build command, so why I need to use git hooks? A: because if eslint yells at build stage in your remote server, things become worse, am I right?

by Eddie Zhang
git
husky
git hooks

Solve Your End-of-line (eol) Problem For Good

I don't want to explain it too much, I understand why you come to this blog setup for your editor if you use vscode, create a `.vscode/settings.json` { "files.eol": "\n" } or a much general solution, create a `.editorconfig` file [*] endofline = lf in this way, even if an editor haven't set eol sequence to LF, this will do it for you for frontend developers in your `.prettierrc` file { "endOfLine": "lf" } you know what to do next but it still happens well, even though you set up these stuffs during developing, eol issue still happens when you clone a repository from a windows user. After your `git commit`, git saves your code in CRLF on windows, while LF on linux/macos. to handle this, create a `.gitattributes` file * text=auto eol=lf *.{cmd,[cC][mM][dD]} text eol=crlf *.{bat,[bB][aA][tT]} text eol=crlf this config tells git to use LF on saving any file, except .cmd or .bat not done yet run following commands to reset eol. Before it, you should make sure your local repository is clean (commit/stash) git ls-files --eol inspect if there are files use crlf git rm --cached -r . clear git index git reset --hard after these, eol in current files will be set to LF

by Eddie Zhang
eol

A Record Of Adding Eslint To My Nextjs Website

adding eslint support to nextjs is definitely not as easy as the official claims! what happened? nextjs has supported eslint by default, then I thought "maybe a just need a .eslintrc file, how hard can it be?", then one afternoon of my life is ruined. I copied my .eslintrc file from my old project, and I promised I exactly followed nextjs migrate instruction > tldr, nextjs prompts you to extend "next" in your own .eslintrc.json then nothing happened when I run "pnpm run lint", nextjs has no idea about my .eslintrc.json file. this popped up ⚠ The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config After ~~copying~~ referring to many stackoverflow/github issues, I decided to screw that bullcrap next lint, I do it my self! these are necessary dependencies, notice they are all devDependencies "@typescript-eslint/eslint-plugin": "^8.18.2", "@typescript-eslint/parser": "^8.18.2",// to let eslint understand typescript "eslint": "^9.17.0", "eslint-config-next": "^15.1.3",// to avoid conflict with nextjs eslint config "eslint-config-prettier": "^9.1.0", //to avoid conflict with prettier config "prettier": "^3.4.2", then we will be okay...? after eslint 9, .eslintrc files (js or json or whatever) are not supported, which means I have to make a eslint.config.mjs instead to let eslint cli know my config file > is breaking changes ths mainstream in javascript? am I right, Nextjs official? Good news is, eslint official tells me how to migrate to the new version: pnpx @eslint/migrate-config .eslintrc.json these msgs will pop up Migrating .eslintrc.json Wrote new config to ./eslint.config.mjs You will need to install the following packages to use the new config: globals @eslint/js @eslint/eslintrc You can install them using the following command: npm install globals @eslint/js @eslint/eslintrc -D download... actually we good, pnpx @eslint/migrate-config .eslintrc.json && eslint --no-cache eslint shouts, in the end. setup prettier eslint shouts when our rules are broken, but prettier fix our code (kind of) to introduce some plugins I am using: "prettier-plugin-organize-imports": "^4.1.0",// this will conflict with eslint-import-sort, I recommend to use prettier "prettier-plugin-tailwindcss": "^0.6.9",// format tw classnames go to your .prettierrc, "plugins": [ "prettier-plugin-tailwindcss", "prettier-plugin-organize-imports" ], run `prettier write .` to format all the files in your project > why this command can run globally? modify my commands "lint": "pnpx @eslint/migrate-config .eslintrc.json && eslint --no-cache", "format": "pnpm run lint && prettier --write .", > I am not getting used to the latest eslint config syntax, you can make your own's don't forget to go to next.config.ts const nextConfig: NextConfig = { eslint: { ignoreDuringBuilds: true, }, //... }; since we run `format` every time before `build` so we don't need it anymore currently I am making it into a git hook, I will write a new blog after I made it

by Eddie Zhang
eslint
nextjs
prettier

The Correct Way To Download Ios Runtime

the general workflow is to download ios runtime in xcode, but xcode shouted download is failed > this is not only for me, lots of developers reported this issue, I think it's Apple's fault. then we have to download it manually. go to <https://developer.apple.com/download/all/?q=Xcode> to download ios runtime you like. > tips for Chinese developers, you need a 🪜 for normal access After your dmg file is downloaded, then go to your shell, tell which xcode to load you ios, mine is at default path sudo xcode-select -s /Applications/Xcode.app xcodebuild -runFirstLaunch xcrun simctl runtime add "~/Downloads/<somewhat.dmg>" the forgoing is what Apple doc told you, but what it hasn't told you is: Accessing '/Users/<Username>/Downloads/<somewhat.dmg>' requires Security & Privacy approval. since terminal cannot add files to disk by default, you should go to your mac settings, Security & Privacy > Full disk access > Give terminal full permission run those bash commands again, D: 134B74D0-63F2-43ED-9E2B-21B5739CA8A5 iOS (18.2 - 22C150) (Ready) if this pops up means you are okay Then you can play iphone 16 in your mac!

by Eddie Zhang
xcode
ios runtime

Pitfalls On Orbstack Proxy

how to set proxy to orbstack? Well, on my new computer I installed orbstack to ease my work, but when I was pulling a mirror, a familiar message shows up: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) don't need to say more, this is the classic proxy issue, let's add some proxies, it differs from docker/daemon.json, you should go here vim ~/.orbstack/config/docker.json add registries just as the same as docker { "registry-mirrors": [ "https://<some-proxy>.com" ] } open a new shell and pull nginx Well,it doesn't help, things go tricky orbstack documents says we can also set network proxies, let's have it a try orb config set network_proxy socks5://127.0.0.1:7890 this command sets proxy of terminal, I added it just in case export http_proxy=socks5://127.0.0.1:7890 see if it is set orb config show it should work, right? NO! then the final resort is to add dns ip addresses to your computer after add a bunch of dns records it works in the end.

by Eddie Zhang
orbstack
proxy

Quick Notes

just some quick notes in my coding, if there is enough content, I will create a new blog for it. fix the eol issue make a `.gitattributes` * text=auto eol=lf default LF *.{cmd,[cC][mM][dD]} text eol=crlf CRLF for cmd *.{bat,[bB][aA][tT]} text eol=crlf CRLF for bat replace all the files with LF in old files git rm --cached -r . git reset --hard fix the revalidate issue [❌] export const revalidate = 15*60; //error [✅] export const revalidate = 900; //success set git proxy git config --global http.proxy '<http|socks5>://<hostname>:<port>' cannot set https proxy because git doesn't have this option see the config is set or not git config --global --get http.proxy

by Eddie Zhang
quick notes

What Exactly Is "use Client" In Nextjs?

the 'use client' directive is a confusing content in Nextjs, because it actually differs from the conventional acknowledgement to client side rendering How? let's make an example, you will get what I mean. export const LOG = () => { if (typeof window !== undefined) { console.log('I am on client side'); } if (process.env.NODE_ENV) { console.log('I am on server side'); } }; let's use it to page component import { LOG } from '@/lib/LOG'; const Page = () => { LOG(); }; export default Page; the function logs both in my terminal and in my browser, it is quite reasonable because nextjs uses SSR let' add 'use client' notation to the page 'use client'; import { LOG } from '@/lib/LOG'; const Page = () => { LOG(); }; export default Page; the function still logs in both of my terminal and my browser, but it logs twice in the browser (due to react strict mode) See? 'use client' still uses SSR, hence actually the full name of 'use client' is actually 'use client feature', not 'use client rendering', that's a huge difference. So why nextjs invent it? See the doc. nextjs has two separate strategies to make it happen: 1. Full page load: nextjs renders a full page of static HTML on server side, then use js script to append browser features on client side. 2. Subsequent navigation: First, what is "subsequent navigation"? I believe nextjs document didn't explain it well. But it sounds like "client navigation" to me, probably it means the Link component in next/link. Anyway, in this case, nextjs directly sends js bundle to browser, this is the real "client side rendering". by marking 'use client' at the top of the tsx file, obviously nextjs uses the first strategy, because these components still use SSR, just like the example above. Then, it makes great sense to explains why nextjs mentions the unsupported pattern in using client components because initially all the components are rendered on server side, when hydration happens on client side, it means the render is done, then nextjs cannot go back to server side to handle server features. have to use the 'use server' directive to handle server features. Key points 1. client components are more than the components use 'use client' 2. the components use 'use client' are hydrated on client side 3. the components use 'use client' are rendered on server side (at first stage) 4. 'use server' can only be used in the components use 'use client' Extra somebody thinks maybe it causes hydration error because of the "use client" directive, but actually it is not. const Page = () => { return ( <p> <h3>This is index</h3> </p> ); }; This code causes hydration error, because the this is invalid html structure (p tags can only contain inline elements, h3 is block element)

by Eddie Zhang
Nextjs
use client

Write A React Switch Case Component

In React, we often find ourselves writing conditional rendering like: `{condition && <Component/>}`. Examples from this Website use-and-operator use-ternary-operator From my perspective, this pattern significantly impacts code maintainability and readability, yet such pattern has already became part of react syntax. > I have some thoughts about typescript as well, but we discuss that another time :) Is There a Better Way? During my time learning vuejs in university, I discovered its elegant solution to this problem via built-in directives. Not familiar? See the docs. Of course, Vue.js can implement directives easily because it is based on template. Adding directives to React would be more difficult because we are going to use babel plugins. So I will use slots, or react children, and I really make it in the end! Here's my implementation: react-switch-case > For the sake of shadcn/ui - I have no idea how many methods that the React instance has in last several years 😅 Rather than using If-else blocks, I prefer switch cases for better readability. And the jsx syntax returns values, hence we no longer need to write break statements. Here's a working example, just like the switch-case everyone knows 😎 react-switch-case-example Go to this link to experience demo

by Eddie Zhang
eureka moment

Useful Links For Developers

Some useful links for developers, to avoid terrible frontend codes. UI Does anyone not know about shadcn/ui? To be honest this guy saves everyone's life :). However, shadcn is too atomic, it's not easy to use it as a full-fledged UI. Shadcn The following ui libraries are based on shadcn, but are more like normal ui libraries for developers. Origin UI Magic UI Aceternity UI <-this website uses it, a lot other recommended ui libraries, i,e, not based on shadcn Next UI<- not related to nextjs Headless UI Icons Iconify Tabler <-I prefer this one Hero Icons Lucide Icons <-integrated with shadcn/ui React Icons <- once popular, but now I don't use it anymore Other annoying stuffs ico converter favicon generator looking for brand logos make logo React hooks I just recommend this one, because I don't like to write the same codes over and over again. react-use I guess these are the all the things for frontend developers. As for backend developers... ngrok

by Eddie Zhang
links

Dotnet Cli Cheatsheet

I prefer typing commands over clicking (blame VSCode for that). General Workflow List all templates provided by Microsoft dotnet new list <template name> --tag=<tag> For template names with spaces, please use double quotes Or search for a template on NuGet dotnet new search <template name> --tag=<tag> Create a new application using the template's short name dotnet new <template short name> > Unlike other CLI tools, the dotnet CLI creates files and folders directly in your current directory, so make sure to create a directory first before running this command. Run the application (navigate to the project folder first) dotnet run Build the application dotnet build .NET SDK Commands List all SDK versions installed on your machine, The command structure differs from the usual pattern dotnet --list-sdks Check current SDK version dotnet --version > You can download SDKs from the official .NET download page > > Alternatively, use the .NET SDK extension in VSCode as shown below: > dotnet-install-tool SDKs are installed globally, and the CLI automatically uses the latest version. How to Switch SDK Versions Navigate to your project root and run: dotnet new globaljson > This command works for both new and existing projects

by Eddie Zhang
snippets
dotnet