traceypooh / blogtini

Markdown + JS 100% client-side blogs & websites
8 stars 3 forks source link

WIP: Suggestions in refactor #5

Open renoirb opened 1 year ago

renoirb commented 1 year ago

Warning I'm aware it's not working ATM. I'm going to shave out things from my fork that can be ported back and I probably made this PR too much in a hurry. I'll remove "draft" once what I'm sharing here doesn't break.


Hi, I'm using your work and am seeing things that I could share back. I'm keeping them here in this PR. Do what you want with them.

I'm implementing slowly my own fork in https://github.com/renoirb/blogtini based off your amazing work! I'll be using customElements, and see some perf tweaks and other things. Also, I have bad working memory, it helps me making small things, separate concerns. I'll probably make tests etc.

Do what you want, I'll try to give back from here. If you want it.

traceypooh commented 1 year ago

Thanks for liking and diving in! this is a lot to consider already, so am going to throw off a few initial thoughts...

You happened to have already seen the (optional) config.yml at the root of the top of the blog/site project, right? that's an excellent place for customizations (like docroot changes, etc.) and am hoping to move more and more there, as needed.

I had envisioned this as being ideally a two part system:

  1. JS to "crawl" your sitemap (or RSS feed, have work uncommitted on that), build up tags/categories maps, sort posts, etc...
  2. A completely pluggable "theme" in JS. so if one doesn't like/prefer the current based-entirely-on hugo-futurue-imperfect-slim theme (which I've already lightly hacked at my current hugo site since it went unsupported, grrr.....) https://poohbot.com -- then one could just plug in a new theme.js file "pointer" to some other setup and UI/UX.

SEO is a challenge. I feel i'm at war with google and super pissed they get to decide everything and get to player hate SPA sites that want to entirely build up the <head> dynamically with JS. Some of the meta and/title tags get through, but a lot comes down to how much of their JS-enabled crawler "budget" (w/ timeout limits to how much JS and loading they'll do) they'll let you do. Still, I am hopeful some day if this and similar projects take off, they'll listen more in the future. Meanwhile, their JS crawlers should get better, faster, more efficient and more common. TBD!

I view any .ts (absolutely) or .mjs (potentially) extensions as a dealbreaker -- at least, the project goal is to only support modern browser native capabilities. I'm on the fence about types in JS -- in general -- but I have 0 interest in anything that's not browser native. (just FYI).

Sidenote: I originally aimed to have a jekyll mod to enable us to use their basic setup. I have a fork & working branch, but it's kind of been months of crickets over there for the final config/testing questions... In the end, I haven't been sure any build step is appropriate (the hope is none is needed -- though you may have noticed their is an optional build step to run before commit/push (of say a new post to a blog) that rebuilds/updates the sitemap.xml (and/or RSS feed files) w/ a simple shell script and git hook. Mostly, I wanted a static markdown site that had no build steps and JS only as the guiding goal. As the founding & longest coder at https://archive.org -- I have keen interest in "roach proof" (when the world nukes away and only the roaches and alien visitors are left) blog pages. So they'll find the raw files w/ a browser and be like "ooh! i know what this is!" and it "just works" 1000s of years from now :D

RE: custom elements... So my work front-end UI/UX centered team at work uses and prefers lit -- have you happened to have seen that? I'm a bit on the fence about it for this project since the pages are generally quite static in reality (this whole thing was born of ideas based of static site generators and their pluses and minuses). I'm curious where you're thinking custom elements / web components / lit might be worth the effort?

OK! that's some good initial thoughts! Please don't take any of them in a discouraging light -- none of them are meant to be so, and I want to reiterate that I'm thrilled you are interested and active in this -- this was my hope for this project -- to get a team of folks involved and using it :)

traceypooh commented 1 year ago

Oh, and re: .mjs files... the entire project is type="module" by default (I'll never use CJS again, since ESM is so soooooo good ( the best import system setup on the planet, across all languages, hands down :D)).

So you can just rename any .mjs file to .js to avoid any (potential) browser confusion.

renoirb commented 1 year ago

(writing this from a phone, beside a sleeping baby. Apologies for typos)

Hi Tracey,

I got interested because I also think about long term ("roach proof"), leverage the (web) platform™, browser native ("Don't break the web","Cool URIs don't change", etc.), and maintainability. From what you've written, I feel like I am actually on the same page as you.

I am more efficient programmer when I separate complexity in smaller units with tests and isolation. My working memory is very bad (all the time) and that's a necessity for me to produce anything functional.

I'm willing to contribute with pieces that can be contributed into how you're planning it. I may make different choices on my own site, but the ideas I have in mind align almost totally. (I say almost, because typings is to me a neat model to design code before implementation, and, of course, you might have other ideas I can't guess that are missing. I like being precise and I'm now getting pedantic)

(rest inline)

Thanks for liking and diving in! this is a lot to consider already,

Yup.

I'm an "exploratory programmer". My fork (renoirb/blogtini) is an orphan fork, just getting the minimal and experiment. As I'm trying say, I'd like to separate concerns and continue on your ideas since they align with mine.

so am going to throw off a few initial thoughts...

Thanks for all this write up.

Your talk blew my mind and shown me running an idea I've had for years, but couldn't work on.

I'm glad you've done this. As I'm trying to tell, I'd love to help.

You happened to have already seen the (optional) config.yml at the root of the top of the blog/site project, right? that's an excellent place for customizations (like docroot changes, etc.) and am hoping to move more and more there, as needed.

Yup, saw all that.

it's clever to use browser's treatment of an .html file with empty body directly with markdown so browser treats as content-type: text/html. Like Nicholas Zakas said when introducing Progressive Enhancement, an automatic escalator, at worse case, is still an escalator.

It's cool, but has dome drawbacks. SEO being one, it'd be best that inter-page be HTML a elements (which is valid Markdown). Some other markup maybe. Like the W3C does with Bikeshed and Publican. Also other drawbacks for internationalization.

I had envisioned this as being ideally a two part system:

  1. JS to "crawl" your sitemap (or RSS feed, have work uncommitted on that), build up tags/categories maps, sort posts, etc...

Yup. Got that.

Also using sitemap.xml as input. Clever stuff.

Maybe I'd try to use IndexedDB and see how we could leverage it for search, and also, maintain its state. I'm unsure if IndexedDB is appropriate for text fuzzy search. But I'm curious if we have heavy content, how it would do. We could import the whole WebPlatform docs markdown content and see how speed goes. See this article I've written about that, it's about 5000 markdown files. Have you tried with that many?

As for the search index, tags, categories indices, we could probe using Last-Modified response header, and sometimes call, and maintain index freshness without hammering needlessly.

GET /foo HTTP/1.1
If-Modified-Since: ...
Accept: text/html

304 Not Modified

So we know we don't need to update.

Something like that. Keep the response parsing the same, it's simple if it's Markdown, no DOM to create and walk. Then "re calculate" the indices when changes.

  1. A completely pluggable "theme" in JS. so if one doesn't like/prefer the current based-entirely-on hugo-futurue-imperfect-slim theme (which I've already lightly hacked at my current hugo site since it went unsupported, grrr.....)

Yup. Got that too.

I would love to allow people to use as-is, and also be extensible. That's why the crawling (indexing, etc) and rendering feels like should be separated. That's what I'm experimenting with at the moment.

And web components, dependency less (just use bare metal native DOM). Because I'd love it to be the smallest as possible.

https://poohbot.com -- then one could just plug in a new theme.js file "pointer" to some other setup and UI/UX.

That entry point /theme.js is great. Also the perfect place to tell whether the file is loaded from localhost, or file:///... and work.

Staticman is cool too, thanks for sharing. I was thinking if it would be applicable to make comments be stored in JSON similar to ActivityStream comments, in some schema so rendering them be the same as rendering the site's own activities. I'm aware that a person's POST /inbox (if there was) be the ideal than static comment. Basically a local filesystem cache of comments as if the commenter did have its own. I'm curious about Annotations on pages as ways to accept comments. But I can go in too many directions.

Yeah. I should table that for now. I'm going into a tangent. Basically find a way to use what I'm mentioning, done right, so we store comments via PRs created by a bot that staticman does. If we use similar storage format as a filesystem cache ActivityStream, we'd get "two birds, one stone" (poor birds, gotta find cruelty free image for this expression someday). And it's web native (!)

SEO is a challenge. I feel i'm at war with google and super pissed they get to decide everything and get to player hate SPA sites that want to entirely build up the <head> dynamically with JS. Some of the meta and/title tags get through, but a lot comes down to how much of their JS-enabled crawler "budget" (w/ timeout limits to how much JS and loading they'll do) they'll let you do. Still, I am hopeful some day if this and similar projects take off, they'll listen more in the future. Meanwhile, their JS crawlers should get better, faster, more efficient and more common. TBD!

Yes.

That's why, we might have to do like what they do in W3C's specs for essential things like links we care about to be done by hand, not markdown.

I view any .ts (absolutely)

I love how TypeScript helps me design. But, that code is for writing and maintaining. What's deployed and running, least dependencies. Native. I agree.

or .mjs (potentially) extensions as a dealbreaker

No problem, I used .mjs thinking it was the future proof way to tell its ESM served over http.

-- at least, the project goal is to only support modern browser native capabilities. I'm on the fence about types in JS -- in general -- but I have 0 interest in anything that's not browser native. (just FYI).

On the same page.

Sidenote: I originally aimed to have a jekyll mod to enable us to use their basic setup. I have a fork & working branch, but it's kind of been months of crickets over there for the final config/testing questions... In the end, I haven't been sure any build step is appropriate (the hope is none is needed -- though you may have noticed their is an optional build step to run before commit/push (of say a new post to a blog) that rebuilds/updates the sitemap.xml (and/or RSS feed files) w/ a simple shell script and git hook. Mostly, I wanted a static markdown site that had no build steps and JS only as the guiding goal.

I agree. The smallest amount of boilerplate and leverage what the browser does by design. Starting the response body with "---" and markdown as an .html file, the browser treats as if we did have <html>...

Unfortunately, as a native French canadian, being constantly faced to the fact that our content isn't in English and how the other language doesn't play well (screen reader being one "victim"), we lose the opportunity to tell sans JavaScript the html[lang] of ce que nous écrivons

As the founding & longest coder at https://archive.org -- I have keen interest in "roach proof" (when the world nukes away and only the roaches and alien visitors are left) blog pages.

I love your perspective. I'm interested to learn more about what you've learned.

So they'll find the raw files w/ a browser and be like "ooh! i know what this is!" and it "just works" 1000s of years from now :D

Yes. I'm also such type of nerd. Had cool convos with former colleagues when I was SysAdmin on WebPlatform.org as a W3C team members. I learned so much about how it all started, how things are maintained there. It's constantly in my mind. Long term, and to understand what and how to properly leverage technology

RE: custom elements... So my work front-end UI/UX centered team at work uses and prefers lit -- have you happened to have seen that?

Yes. I also participated in the Web Component CG Community Protocols. The "context API". I contributed to reviewing Lit.dev's Context protocol lit/lit#1955 (daisy-chaining always annoyed me, that Protocol solves it nicely)

In my fork (d.g. this broken looking page, try the search, look for "html", notice the date of article. It's updated via a context-request event. Code to request, and code to update

I have good understanding of Vue, and Lit.dev internals. My hobby is to actually compare how frameworks runtime does the same effect. I love Vue 3's way of describing render trees, how we can use raw JavaScript to describe how to generate HTML so that most use case (and mostly everyone uses template syntax) but for real hairy patterns, native 1-1 parity render tree.

Lit doesn't have that lime Vue does. But I like how it's a middle ground.

I also have the ambition to achieve to load least code should a view need only the minimum. Which is a contrast to what most people do by bundling everything in one payload. ESM import allow to dynamically load when needed. Maybe a view only load /theme.js, the site's index is still warm, no check to make, load the "app layout". Done. 2 JavaScript files loaded parsed. Ideally the least amount of DOM mutations.

See a prototype of the app layout live here: https://renoirb.github.io/blogtini/using-app-layout.html

I also worked in ways to package for reuse of that "chrome" (repetitive UI markup) with Vue https://youtu.be/C39eZYD-7Ow so you import, tell the navigation tree, listen to events. So the same package is reused between projects.

I like https://lit.dev, but it's also possible to be framework naked. Or Svelte, generating code that doesn't require loading a framework runtime.

If you look at the bookmarks in my fork, the ContextAPI, you'll see how we can update parts of the view without any "reactivity" or "stream", or ... runtime. Just native DOM events.

I serve some of it from my domain name, an attempt to mimick Deno's way of publishing package for web browser runtime. And I was thinking to port lit-labs/context package.

I'll stop here for now. I've added more for you to parse.

I said I would stop and I didn't. I wouldn't mind having a vocal video conf call.

My plan is to continue experimenting, if you wouldn't have done this, I would probablly have made the same choices. I'm trying to go in a similar place as what you've described. Also, I'm a new stay at home dad. Web nerd. I can hack when my 7 months old son naps. The Web is constantly in my mind since 2001 (professionally). So, your project got my attention. I wanna contribute.

Cheers.

renoirb commented 1 year ago

Oh, and re: .mjs files... the entire project is type="module" by default (I'll never use CJS again, since ESM is so soooooo good ( the best import system setup on the planet, across all languages, hands down :D)).

So you can just rename any .mjs file to .js to avoid any (potential) browser confusion.

Exactly. Same feeling.

Now, the question is how to write small packages with testing, publishing for the same code, different targets. Different releases, published as versioned URLs, yet code of a module using it refer to module with version less, but specified as an importMap.

I've been contributing and using RushJS.io for that. I've been asking about that today on RushJS' community chat on Zulip. They responded that they have an issue for that use-case microsoft/rushstack#3934. But all that is probably too bleeding edge though.

traceypooh commented 1 year ago

re: your first long reply (esp.)

I. Love. This.

Minor suggested alteration.

Let's setup a standing meeting to checkin & collaborate! 🙌🏻

Hehe. Well, we can see, but I think that could be a great way to coordinate & plan.

renoirb commented 1 year ago

(Please consider this notes for when we meet. Apologies for the apparent chaos, that's my brain.)

Instead of using Lit, we could make a thin wrapper (html tagged function) like what Enhance does.

Notice the example in the docs

export default function MyHeader({ html }) {
  return html`
    <header>
      <h1>Header</h1>
      <nav>
        <a href=/>home</a>
        <a href=/about>about</a>
      </nav>
    </header>
  `
}

Is possible because of this

I have other ideas, but the more we add the more it grows. E.g. what Plume on a Solid pod is, or that Enhance framework, or singleSpa.

Priorities could be to

So that people could extend with any customElement framework they want, store in anything they want.

Other ideas could be we have a distribution of blogtini server soide to run on CloudFlare, or NGINX (NJS). Keeping the idea that the code run client-side or here would give the same (isomorphism FTW!). If one day a person stops using NGINX, it'll still work. Except that people who browse the web JavaScript disabled might get the stylized version.

The use of context-event for things allows to separate and defer later things. For example, not that it needs to be core, but I could decide to make more descriptive list of tags, with text in a language I maintain for the same tag definition. The logic is currently embedded in my 2020 pre-covid work in Vue, but the taxonomy logic, provide the appropriate data, and display the list differently

I gotta go. Told you, full of ideas.