From f6cbe9537b918a91fa1a6ddc10dab6338a3613c1 Mon Sep 17 00:00:00 2001 From: chloe caruso Date: Mon, 11 Aug 2025 22:38:06 -0700 Subject: [PATCH] move blog pages --- src/blog/pages/webdev/deranged-typescript.md | 87 +++++ src/blog/pages/webdev/marko-intro.markodown | 339 +++++++++++++++++++ 2 files changed, 426 insertions(+) create mode 100644 src/blog/pages/webdev/deranged-typescript.md create mode 100644 src/blog/pages/webdev/marko-intro.markodown diff --git a/src/blog/pages/webdev/deranged-typescript.md b/src/blog/pages/webdev/deranged-typescript.md new file mode 100644 index 0000000..a6f4a45 --- /dev/null +++ b/src/blog/pages/webdev/deranged-typescript.md @@ -0,0 +1,87 @@ +- imports at the bottom + - order your file by importance. + - 'G' to jump to imports, etc + - prefer namespace imports + - easier to type and refactor. easier to read. +- large files are okay + - all files are their own library + - split files up by making components modular, not by "oh it's too big" + - engine/render.ts is a standalone library, in order to split JSX, Suspense, + and Marko out, the main file was made modular. +- lowercase +- name objects ultra-concisely + - filenames are often one word describing what they contain + - avoid useless descriptors like "utils", "helpers", and "data" + - examples + - async.ts contains all the async library functions. + - watch.ts contains the file watcher and watch-reload mode. + - render.*, Io +- be ultra-concise in comments +- no "discarded" variables, embrace `void x` + - makes code more readable + - note how i want to write a lint for this + - note the one proposal i want about void +- push the ts inference engine (as const, ReturnType, etc) + - reduces how much you repeat yourself making it easier to refactor things + - use the code as the source of truth +- push the ts inference engine (generics) + - do not implement crazy things with the TS engine, instead use generic input + types, and then use regular control to narrow and transform the return type. + source of truth is your code. +- UNWRAP, ASSERT utility globals are amazing + - ban postfix '!' + - stripped for production frontend builds +- destructure often + - use the one example from work lol +- package.json "imports" are amazing + - remapping + - implementation switching + - testing +- embrace the web and node.js APIs + - sitegen relies on so many node features that bun and deno fail to run it. + - overlay modules are great +- avoid dependencies + - once you build your own mini standard library you win + - talk about regrets with mdx + +## imports at the bottom + +Here is an abridged version of my website's `backend.ts`. When reading it from +top to bottom it is immediately obvious that it is a Hono web server. + +```ts +// This is the main file for paperclover.net's server. +const app = new Hono(); +const logHttp = console.scoped("http", { color: "magenta" }); + +// Middleware +app.use(...); +... + +// Backends +app.route("", require("./q+a/backend.ts").app); +... + +export default app; + +... + +import { type Context, Hono, type Next } from "#hono"; +import { logger } from "hono/logger"; +import { trimTrailingSlash } from "hono/trailing-slash"; +import * as assets from "#sitegen/assets"; +import * as admin from "./admin.ts"; +import * as console from "@paperclover/console"; +``` + +Since `import`/`export` statements are hoisted like `var` and `function`, the +position of these statements within the file does not matter. The imported +modules have to be loaded first before this file can start. With this, I've +found it nicer to sort the file by _importance_ rather than by arbitrary rules +dictated by how C-style `#include`s worked. + +Start with a documentation comment, then the most important +functions/variables/types, sort the file by importance. Imports are not really +important since you very quickly get to know where common namespaces come from. +And since they're at the bottom, you can just press `G` in Vim or `CMD+Down` on +the Mac to scroll to the end of the file. diff --git a/src/blog/pages/webdev/marko-intro.markodown b/src/blog/pages/webdev/marko-intro.markodown new file mode 100644 index 0000000..0436022 --- /dev/null +++ b/src/blog/pages/webdev/marko-intro.markodown @@ -0,0 +1,339 @@ +export const blog: BlogMeta = { + title: "Marko is the coziest HTML templating language", + desc: "...todo...", + created: "2025-06-13", + draft: true, +}; +export const meta = formatBlogMeta(blob); +export * as layout from "@/blog/layout.tsx"; + +I've been recently playing around [Marko], and after adding limited support +for it in my website generator, [sitegen], I instantly fell in love with how +minimalistic it is in comparison to JSX, Astro components, and Svelte. + +[Marko]: https://next.markojs.com +[sitegen]: https://paperclover.dev/clo/sitegen + +## Introduction to Marko + +If JSX was taking HTML and shoving its syntax into JavaScript, Marko is shoving +JavaScript into HTML. Attributes are JavaScript expressions. + +```marko +
+ // `input` is like props, but given in the top-level scope + +
+ ${input.user.name} +
+ + // Capital letter variables for imported components + + + // Components also can be auto-imported by lowercase. + // This will look upwards for a `tags/` folder containing + // "custom-footer.marko", similar to how Node.js finds + // package names in all upwards `node_modules` folders. + +
+ +// ESM `import` / `export` just work as expected. +// I prefer my imports at the end, to highlight the markup. +import MarkdownContent from "./MarkdownContent.marko"; +import { formatTimeNicely } from "../date-helpers.ts"; +``` + +Tags with the `value` attribute have a shorthand, which is used by the built-in +`` for conditional rendering. + +```marko +// Sugar for + + +// and it composes amazingly to the 'if' built-in + + + +``` + +Tags can also return values into the scope for use in the template using `/`, such as `` for unique ID generation. This is available to components that ``. + +``` + + + +