Skip to content

Blog

Shrink Docker WSL2 vhdx Disk Size

Can also be used to clean up files for regular WSL distributions When running Docker Desktop with the WSL2 backend on Windows, due to the nature of dynamic VHD disks (docker_data.vhdx), the host machine’s disk space is not automatically released even if we delete a large number of useless images and containers in Docker. Often, the actual container usage is only around 20 GB, but the host’s .vhdx file can swell to 130 GB, or even fill up the C drive.

Read more →

slot without shadow dom

1 2 3 4 5 6 7 <svelte:options customElement={{ tag: "example", shadow: "none" }} /> <div {@attach (slot) => { slot.appendChild($host().firstElementChild!); }} ></div>

Read more →

Solid.js Quick Overview

Components internal <Show> <Switch> <Match> <For> <Index> createSelector() indexArray() mapArray() <Suspense> <SuspenseList> <Portal> <Dynamic> <ErrorBoundary> JSX Attributes on* / on:* use:* class / classList / style attr:* / prop:* / bool:* innerHTML / textContent ref /* @once */ Life Cycle onMount() onCleanup() Utility createContext() / useContext() mergeProps() / splitProps() lazy() children() createUniqueId() Render Client DEV render() SSR <NoHydration> isServer hydrate() hydrationScript() renderToStream() renderToString() renderToStringAsync() getRequestEvent Reactivity Data createSignal() / Derived signals createStore() / createMutable() modifyMutable() unwrap() produce() / reconcile() createResource() createMemo() createDeferred() from() / observable() Operations createEffect() / createRenderEffect() / createComputed() createReaction() Utility batch() on() untrack() catchError() useTransition() / startTransition() Owner createRoot() getOwner() runWithOwner()

Read more →

Some experience in crawling

Introduction I’ve been writing web scrapers since I was in middle school. Back then, the internet was flooded with people selling basic scraping courses. Looking back over the past decade, while the tech stack has evolved, the core logic of scraping has remained exactly the same. Today, I want to skip the textbook fluff and share some real-world insights, tech stack opinions, and the actual bottlenecks that will make or break your scraper.

Read more →

Some Insights on Tinkering with Servers

Server Selection Cloud providers: Foreign ones basically require a credit card, so you can pass on them directly. Domestically, Alibaba Cloud has the largest market share, but the differences between major cloud providers’ services are negligible for ordinary people. You can choose based on price, but be cautious when choosing small providers. CPU: At least two cores. Operation and maintenance are hard with just one core, as your services will fight for resources with your ssh and vscode server. Memory: At least 2GB; 4GB is the comfort zone. It’s fine if there are no Java services, but once you have Java, just forget about it. Servers with little memory can only run go and rust; jvm and node services are completely unusable. Anyone who has manually deployed services knows how sweet go is, and wouldn’t dare to use jvm. Network: If you are sure the traffic will be low or if you are not afraid of DDoS, you can choose pay-by-traffic; otherwise, choose fixed bandwidth. Region: Currently, Hong Kong is still the optimal solution. Not only is ICP registration not required, but accessing Docker Hub, GitHub, Huggingface, etc., doesn’t require a proxy, and you can even set up a proxy server. Operating System Selection Server sides are typically either Debian-based or RHEL-based.

Read more →

Svelte Basics

Introduction Use {} to embed JS expressions 1 2 3 4 5 6 7 8 9 10 <script> let src = '/tutorial/image.gif'; let name = 'Rick Astley'; </script> <p>Name: {name}</p> <img src={src}/> <!-- Syntactic sugar --> <img {src} /> Use <style> to add styles 1 2 3 4 5 6 7 8 <p>This is a paragraph.</p> <style> p { color: goldenrod; font-size: 2em; } </style> Import and use components 1 2 3 4 5 <script lang="ts"> import Nested from './Nested.svelte'; </script> <Nested /> Turn strings into HTML code 1 <p>{@html string}</p> Reactivity Creation and modification of “State” $… are called Runes

Read more →

TailwindCSS implementation of Human Interface Guidelines

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 @import "tailwindcss"; /* Colors: https://developer.apple.com/design/human-interface-guidelines/color#Specifications */ :root { --red: rgb(255 56 60); --orange: rgb(255 141 40); --yellow: rgb(255 204 0); --green: rgb(52 199 89); --mint: rgb(0 200 179); --teal: rgb(0 195 208); --cyan: rgb(0 192 232); --blue: rgb(0 136 255); --indigo: rgb(97 85 245); --purple: rgb(203 48 224); --pink: rgb(255 45 85); --brown: rgb(172 127 94); @variant dark { --red: rgb(255 66 69); --orange: rgb(255 146 48); --yellow: rgb(255 214 0); --green: rgb(48 209 88); --mint: rgb(0 218 195); --teal: rgb(0 210 224); --cyan: rgb(60 211 254); --blue: rgb(0 145 255); --indigo: rgb(109 124 255); --purple: rgb(219 52 242); --pink: rgb(255 55 95); --brown: rgb(183 138 102); } --gray: rgb(142 142 147); --gray2: rgb(174 174 178); --gray3: rgb(199 199 204); --gray4: rgb(209 209 214); --gray5: rgb(229 229 234); --gray6: rgb(242 242 247); @variant dark { --gray: rgb(142 142 147); --gray2: rgb(99 99 102); --gray3: rgb(72 72 74); --gray4: rgb(58 58 60); --gray5: rgb(44 44 46); --gray6: rgb(28 28 30); } @variant contrast-more { --red: rgb(233 21 45); --orange: rgb(197 83 0); --yellow: rgb(161 106 0); --green: rgb(0 137 50); --mint: rgb(0 133 117); --teal: rgb(0 129 152); --cyan: rgb(0 126 174); --blue: rgb(30 110 244); --indigo: rgb(86 74 222); --purple: rgb(176 47 194); --pink: rgb(231 18 77); --brown: rgb(149 109 81); @variant dark { --red: rgb(255 97 101); --orange: rgb(255 160 86); --yellow: rgb(254 223 67); --green: rgb(74 217 104); --mint: rgb(84 223 203); --teal: rgb(59 221 236); --cyan: rgb(109 217 255); --blue: rgb(92 184 255); --indigo: rgb(167 170 255); --purple: rgb(234 141 255); --pink: rgb(255 138 196); --brown: rgb(219 166 121); } --gray: rgb(108 108 112); --gray2: rgb(142 142 147); --gray3: rgb(174 174 178); --gray4: rgb(188 188 192); --gray5: rgb(216 216 220); --gray6: rgb(235 235 240); @variant dark { --gray: rgb(174 174 178); --gray2: rgb(124 124 128); --gray3: rgb(84 84 86); --gray4: rgb(68 68 70); --gray5: rgb(54 54 56); --gray6: rgb(36 36 38); } } } @theme inline { --color-red: var(--red); --color-orange: var(--orange); --color-yellow: var(--yellow); --color-green: var(--green); --color-mint: var(--mint); --color-teal: var(--teal); --color-cyan: var(--cyan); --color-blue: var(--blue); --color-indigo: var(--indigo); --color-purple: var(--purple); --color-pink: var(--pink); --color-brown: var(--brown); --color-gray: var(--gray); --color-gray2: var(--gray2); --color-gray3: var(--gray3); --color-gray4: var(--gray4); --color-gray5: var(--gray5); --color-gray6: var(--gray6); } /* Typography: https://developer.apple.com/design/human-interface-guidelines/typography#Specifications */ :root { font-size: var(--text-body); --large-title-size: 34pt; --title1-size: 28pt; --title2-size: 22pt; --title3-size: 20pt; --headline-size: 17pt; --body-size: 17pt; --callout-size: 16pt; --sub-headline-size: 15pt; --footnote-size: 13pt; --caption1-size: 12pt; --caption2-size: 11pt; --large-title-leading: 41pt; --title1-leading: 34pt; --title2-leading: 28pt; --title3-leading: 25pt; --headline-leading: 22pt; --body-leading: 22pt; --callout-leading: 21pt; --sub-headline-leading: 20pt; --footnote-leading: 18pt; --caption1-leading: 16pt; --caption2-leading: 13pt; --large-title-strong: var(--font-weight-bold); --title1-strong: var(--font-weight-bold); --title2-strong: var(--font-weight-bold); --title3-strong: var(--font-weight-semibold); --headline-strong: var(--font-weight-semibold); --body-strong: var(--font-weight-semibold); --callout-strong: var(--font-weight-semibold); --sub-headline-strong: var(--font-weight-semibold); --footnote-strong: var(--font-weight-semibold); --caption1-strong: var(--font-weight-semibold); --caption2-strong: var(--font-weight-semibold); --large-title-tracking: 0.4pt; --title1-tracking: 0.38pt; --title2-tracking: -0.26pt; --title3-tracking: -0.45pt; --headline-tracking: -0.43pt; --body-tracking: -0.43pt; --callout-tracking: -0.31pt; --sub-headline-tracking: -0.23pt; --footnote-tracking: -0.08pt; --caption1-tracking: 0pt; --caption2-tracking: 0.06pt; @variant sm { --large-title-size: 26pt; --title1-size: 22pt; --title2-size: 17pt; --title3-size: 15pt; --headline-size: 13pt; --body-size: 13pt; --callout-size: 12pt; --sub-headline-size: 11pt; --footnote-size: 10pt; --caption1-size: 10pt; --caption2-size: 10pt; --large-title-leading: 32pt; --title1-leading: 26pt; --title2-leading: 22pt; --title3-leading: 20pt; --headline-leading: 16pt; --body-leading: 16pt; --callout-leading: 15pt; --sub-headline-leading: 14pt; --footnote-leading: 13pt; --caption1-leading: 13pt; --caption2-leading: 13pt; --large-title-strong: var(--font-weight-bold); --title1-strong: var(--font-weight-bold); --title2-strong: var(--font-weight-bold); --title3-strong: var(--font-weight-semibold); --headline-strong: var(--font-weight-black); --body-strong: var(--font-weight-semibold); --callout-strong: var(--font-weight-semibold); --sub-headline-strong: var(--font-weight-semibold); --footnote-strong: var(--font-weight-semibold); --caption1-strong: var(--font-weight-medium); --caption2-strong: var(--font-weight-semibold); --large-title-tracking: 0.22pt; --title1-tracking: -0.26pt; --title2-tracking: -0.43pt; --title3-tracking: -0.23pt; --headline-tracking: -0.08pt; --body-tracking: -0.08pt; --callout-tracking: 0pt; --sub-headline-tracking: 0.06pt; --footnote-tracking: 0.12pt; --caption1-tracking: 0.12pt; --caption2-tracking: 0.12pt; } } @theme inline { --text-large-title: var(--large-title-size); --text-title1: var(--title1-size); --text-title2: var(--title2-size); --text-title3: var(--title3-size); --text-headline: var(--headline-size); --text-body: var(--body-size); --text-callout: var(--callout-size); --text-sub-headline: var(--sub-headline-size); --text-footnote: var(--footnote-size); --text-caption1: var(--caption1-size); --text-caption2: var(--caption2-size); --leading-large-title: var(--large-title-leading); --leading-title1: var(--title1-leading); --leading-title2: var(--title2-leading); --leading-title3: var(--title3-leading); --leading-headline: var(--headline-leading); --leading-body: var(--body-leading); --leading-callout: var(--callout-leading); --leading-sub-headline: var(--sub-headline-leading); --leading-footnote: var(--footnote-leading); --leading-caption1: var(--caption1-leading); --leading-caption2: var(--caption2-leading); --font-weight-large-title-strong: var(--large-title-strong); --font-weight-title1-strong: var(--title1-strong); --font-weight-title2-strong: var(--title2-strong); --font-weight-title3-strong: var(--title3-strong); --font-weight-headline-strong: var(--headline-strong); --font-weight-body-strong: var(--body-strong); --font-weight-callout-strong: var(--callout-strong); --font-weight-sub-headline-strong: var(--sub-headline-strong); --font-weight-footnote-strong: var(--footnote-strong); --font-weight-caption1-strong: var(--caption1-strong); --font-weight-caption2-strong: var(--caption2-strong); --tracking-large-title: var(--large-title-tracking); --tracking-title1: var(--title1-tracking); --tracking-title2: var(--title2-tracking); --tracking-title3: var(--title3-tracking); --tracking-headline: var(--headline-tracking); --tracking-body: var(--body-tracking); --tracking-callout: var(--callout-tracking); --tracking-sub-headline: var(--sub-headline-tracking); --tracking-footnote: var(--footnote-tracking); --tracking-caption1: var(--caption1-tracking); --tracking-caption2: var(--caption2-tracking); } @custom-variant strong (& strong); @utility large-title { @apply text-large-title leading-large-title tracking-large-title; @apply strong:font-large-title-strong; } @utility title1 { @apply text-title1 leading-title1 tracking-title1; @apply strong:font-title1-strong; } @utility title2 { @apply text-title2 leading-title2 tracking-title2; @apply strong:font-title2-strong; } @utility title3 { @apply text-title3 leading-title3 tracking-title3; @apply strong:font-title3-strong; } @utility headline { @apply text-headline leading-headline tracking-headline; @apply strong:font-headline-strong; } @utility body { @apply text-body leading-body tracking-body; @apply strong:font-body-strong; } @utility callout { @apply text-callout leading-callout tracking-callout; @apply strong:font-callout-strong; } @utility sub-headline { @apply text-sub-headline leading-sub-headline tracking-sub-headline; @apply strong:font-sub-headline-strong; } @utility footnote { @apply text-footnote leading-footnote tracking-footnote; @apply strong:font-footnote-strong; } @utility caption1 { @apply text-caption1 leading-caption1 tracking-caption1; @apply strong:font-caption1-strong; } @utility caption2 { @apply text-caption2 leading-caption2 tracking-caption2; @apply strong:font-caption2-strong; }

Read more →

The Curse of Knowing: A Self-Rescue Guide for the Kind-Hearted

I’ve come to realize that “knowing” is the sharpest weapon against kind-hearted people. Every second, countless terrible things are happening in the world: war, famine, disease, accidents… It is precisely because 99.99% of them remain unknown to you that you can live a normal life. Once you learn of a single tragedy, your conscience compels you to do something. But the world’s suffering is infinite. Not acting equals unkindness. Not knowing equals unkindness. Trying to know it all equals burning yourself out completely. Thus, a sharp contradiction is born.

Read more →

TypeScript Configuration

tsconfig.json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 { "include": ["src", "*.config.ts"], "exclude": ["dist", "node_modules"], "compilerOptions": { // Type Checking "strict": true, "allowUnreachableCode": false, "allowUnusedLabels": false, "exactOptionalPropertyTypes": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, "noPropertyAccessFromIndexSignature": true, "noUncheckedIndexedAccess": true, "noUnusedLocals": true, "noUnusedParameters": true, // Modules "types": ["vite/client"], "module": "esnext", "moduleResolution": "bundler", "allowImportingTsExtensions": true, "noUncheckedSideEffectImports": true, // Emit "noEmit": true, // JavaScript Support "allowJs": false, // Interop Constraints "erasableSyntaxOnly": true, "isolatedModules": true, "verbatimModuleSyntax": true, // Language and Environment "lib": ["ESNext", "DOM", "DOM.Iterable", "DOM.AsyncIterable"], "target": "esnext", // Completeness "skipLibCheck": true, }, } In addition, the official TS documentation does not recommend paths, but recommends Node Subpath Imports instead.

Read more →

Use C++ Modules and import std

macOS + Clang Warning Clang version must be at least 19. Install tools 1 2 xcode-select --install brew install llvm cmake ninja Note

Read more →