diff --git a/public/images/blogs/react_bun_boilerplate/1.webp b/public/images/blogs/react_bun_boilerplate/1.webp new file mode 100644 index 0000000..6cfd157 Binary files /dev/null and b/public/images/blogs/react_bun_boilerplate/1.webp differ diff --git a/public/images/blogs/react_bun_boilerplate/2.webp b/public/images/blogs/react_bun_boilerplate/2.webp new file mode 100644 index 0000000..ce41548 Binary files /dev/null and b/public/images/blogs/react_bun_boilerplate/2.webp differ diff --git a/src/components/blogs/header.tsx b/src/components/blogs/header.tsx index f382c76..d83d7e6 100644 --- a/src/components/blogs/header.tsx +++ b/src/components/blogs/header.tsx @@ -6,7 +6,7 @@ export function BlogsPageHeaderGrp() {
Tus's Blogs
-
+
Some notes, some ideas, some opinions

@@ -20,6 +20,20 @@ export function SingleBlogPageHeaderGrp(props: {id: string}) {
{blogInfoDict[props.id].title}
+
+ {formatDate(blogInfoDict[props.id].date)} +
); } + +function formatDate(date: Date) { + const options: Intl.DateTimeFormatOptions = { + day: "numeric", + month: "long", + year: "numeric", + weekday: "long", + } + + return date.toLocaleDateString("en-UK", options); +} diff --git a/src/components/copyright.tsx b/src/components/copyright.tsx index 7d0a606..0c4da7e 100644 --- a/src/components/copyright.tsx +++ b/src/components/copyright.tsx @@ -18,7 +18,7 @@ function Copyright(props: { copyright_class?: string }) { React, {" "} TypeScript and {" "} Sass.

- Copyright © {year} All Rights Reserved. + Copyright © 2023-{year} All Rights Reserved. ); } diff --git a/src/components/layouts/blog.tsx b/src/components/layouts/blog.tsx index 5239f4a..3367e1c 100644 --- a/src/components/layouts/blog.tsx +++ b/src/components/layouts/blog.tsx @@ -21,7 +21,7 @@ function BlogLayout() {
- +
); } diff --git a/src/css/markdown.css b/src/css/markdown.css index b0ee8ae..ca4066d 100644 --- a/src/css/markdown.css +++ b/src/css/markdown.css @@ -6,7 +6,10 @@ margin: revert; padding: revert; list-style-type: revert; - line-height: 1.5rem; + line-height: 1.625rem; +} +.single-blog-wrapper h1 { + padding-top: 3rem; } .single-blog-wrapper code, .single-blog-wrapper pre { border-radius: 5px; @@ -38,6 +41,7 @@ font-style: italic; padding: 1.33em; text-align: left; + font-weight: bold; } .single-blog-wrapper table { padding: 1rem 0; diff --git a/src/css/markdown.css.map b/src/css/markdown.css.map index dd9e787..34018a0 100644 --- a/src/css/markdown.css.map +++ b/src/css/markdown.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["scss/general/_var.scss","scss/markdown.scss"],"names":[],"mappings":"AAAQ;AACA;AACA;AAKR;ACAI;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA,kBAde;EAef,OAdU;;AAiBd;EACI;EACA;EACA;EACA;EACA,aDfS;ECgBT;;AAEA;EACI;;AAIR;EACI;EACA;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;;;AAIR;EAEI,aD9DQ","file":"markdown.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["scss/general/_var.scss","scss/markdown.scss"],"names":[],"mappings":"AAAQ;AACA;AACA;AAKR;ACAI;EACI;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA,kBAlBe;EAmBf,OAlBU;;AAqBd;EACI;EACA;EACA;EACA;EACA,aDnBS;ECoBT;;AAEA;EACI;;AAIR;EACI;EACA;EACA;;AAEA;EACI;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;;;AAIR;EAEI,aDnEQ","file":"markdown.css"} \ No newline at end of file diff --git a/src/css/scss/components/_button.scss b/src/css/scss/components/_button.scss index 9d15fb5..6e8c21a 100644 --- a/src/css/scss/components/_button.scss +++ b/src/css/scss/components/_button.scss @@ -61,7 +61,7 @@ } .btn-contact-overlay { - @include util.overlay(rgba($color: dimgray, $alpha: 1)); + @include util.overlay(rgba($color: var.$text-menu, $alpha: 0.7)); } .btn-skill-grp { diff --git a/src/css/scss/general/_container.scss b/src/css/scss/general/_container.scss index e67fe55..612021a 100644 --- a/src/css/scss/general/_container.scss +++ b/src/css/scss/general/_container.scss @@ -23,7 +23,7 @@ position: relative; width: 80%; line-height: initial; - color: lightgray; + color: var.$text-menu; } .menu-proj-wrapper { diff --git a/src/css/scss/general/_util.scss b/src/css/scss/general/_util.scss index adbd71f..7254b42 100644 --- a/src/css/scss/general/_util.scss +++ b/src/css/scss/general/_util.scss @@ -60,7 +60,7 @@ $directions: ( @mixin overlay($color) { background: $color; - position: absolute; + position: fixed; width: 100dvw; height: 100dvh; top: 0; diff --git a/src/css/scss/general/_var.scss b/src/css/scss/general/_var.scss index ef4dbc8..b3965ac 100644 --- a/src/css/scss/general/_var.scss +++ b/src/css/scss/general/_var.scss @@ -21,9 +21,11 @@ $default-body-font-size: clamp(1rem, 0.96rem + 0.18vw, 1.125rem); $radius: 5px; $text-dark: aliceblue; +$text-menu: #E2E8F0; $background-dark: #34383d; $gray: #8c8c8c; $light-gray: #cbcbcb; $default-atag-color: #0d6efd; $navbar-bg-color: #383838; $navbar-stick-color: #191717; +$overlay-color: #1E293B; diff --git a/src/css/scss/markdown.scss b/src/css/scss/markdown.scss index 66b1f2e..f6469ef 100644 --- a/src/css/scss/markdown.scss +++ b/src/css/scss/markdown.scss @@ -9,7 +9,11 @@ $codeinline-background: #f6f8fa; margin: revert; padding: revert; list-style-type: revert; - line-height: 1.5rem; + line-height: 1.625rem; + } + + h1 { + padding-top: 3rem; } code, pre { @@ -47,6 +51,7 @@ $codeinline-background: #f6f8fa; font-style: italic; padding: 1.33em; text-align: left; + font-weight: bold; } table { diff --git a/src/css/scss/style.scss b/src/css/scss/style.scss index bf724e0..368d841 100644 --- a/src/css/scss/style.scss +++ b/src/css/scss/style.scss @@ -42,7 +42,7 @@ span { } .background-overlay { - @include util.overlay(rgba($color: dimgray, $alpha: 0.9)); + @include util.overlay(rgba($color: var.$overlay-color, $alpha: 0.75)); } .header-grp { @@ -88,7 +88,7 @@ span { @extend %copyright-txt; position: relative; display: none; - color: lightgray; + color: var.$text-menu; a { color: bisque; diff --git a/src/css/style.css b/src/css/style.css index fc4c9f2..2e65e98 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -472,8 +472,8 @@ hr { } .btn-contact-overlay { - background: dimgray; - position: absolute; + background: rgba(226, 232, 240, 0.7); + position: fixed; width: 100dvw; height: 100dvh; top: 0; @@ -938,7 +938,7 @@ hr { position: relative; width: 80%; line-height: initial; - color: lightgray; + color: #E2E8F0; } .menu-proj-wrapper { @@ -1043,8 +1043,8 @@ span { } .background-overlay { - background: rgba(105, 105, 105, 0.9); - position: absolute; + background: rgba(30, 41, 59, 0.75); + position: fixed; width: 100dvw; height: 100dvh; top: 0; @@ -1089,7 +1089,7 @@ span { .menu-copyright { position: relative; display: none; - color: lightgray; + color: #E2E8F0; } .menu-copyright a { color: bisque; diff --git a/src/css/style.css.map b/src/css/style.css.map index 2f9a48a..002d5d1 100644 --- a/src/css/style.css.map +++ b/src/css/style.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["scss/general/_var.scss","scss/general/_util.scss","scss/components/_image.scss","scss/components/_text.scss","scss/components/_line.scss","scss/components/_button.scss","scss/general/_animation.scss","scss/components/_navbar.scss","scss/components/_card.scss","scss/components/_form.scss","scss/general/_grid.scss","scss/general/_landscape.scss","scss/general/_container.scss","scss/style.scss"],"names":[],"mappings":"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","file":"style.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["scss/general/_var.scss","scss/general/_util.scss","scss/components/_image.scss","scss/components/_text.scss","scss/components/_line.scss","scss/components/_button.scss","scss/general/_animation.scss","scss/components/_navbar.scss","scss/components/_card.scss","scss/components/_form.scss","scss/general/_grid.scss","scss/general/_landscape.scss","scss/general/_container.scss","scss/style.scss"],"names":[],"mappings":"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","file":"style.css"} \ No newline at end of file diff --git a/src/lib/factory/cardBase.tsx b/src/lib/factory/cardBase.tsx index d18e8a9..f26e04b 100644 --- a/src/lib/factory/cardBase.tsx +++ b/src/lib/factory/cardBase.tsx @@ -22,6 +22,7 @@ export interface IBlogCardProps extends ICardProps { brief_description: string, url: string, file: string, + date: Date, } diff --git a/src/lib/general_info.ts b/src/lib/general_info.ts index 9fec9cd..9d3bc40 100644 --- a/src/lib/general_info.ts +++ b/src/lib/general_info.ts @@ -417,18 +417,20 @@ export const blogInfoDict: {[id: string]: IBlogCardProps} = { id: "great_ytb_channels_1", title: "Great Youtube Channels (Part 1)", brief_description: `I watch youtube a lot, and I make a list of youtube channels - I have watched that you may find interesting. Here is part 1 of my list...`, +I have watched that you may find interesting. Here is part 1 of my list...`, url: "/great_ytb_channels_1", - file: "great_ytb_channels_1.md" + file: "great_ytb_channels_1.md", + date: new Date("Apr 26 2023 22:35:23 GMT+0800"), }, "great_ytb_channels_2": { content_section: "Blogs", id: "great_ytb_channels_2", title: "Great Youtube Channels (Part 2)", brief_description: `I watch youtube a lot, and I make a list of youtube channels - I have watched that you may find interesting. Here is part 2 of my list...`, +I have watched that you may find interesting. Here is part 2 of my list...`, url: "/great_ytb_channels_2", - file: "great_ytb_channels_2.md" + file: "great_ytb_channels_2.md", + date: new Date("Apr 27 2023 13:30:59 GMT+0800"), }, "markdown_starter": { content_section: "Blogs", @@ -436,38 +438,40 @@ export const blogInfoDict: {[id: string]: IBlogCardProps} = { title: "Get started with Markdown", brief_description: "My markdown theme which is generated by React Markdown.", url:"/markdown_starter", - file:"markdown_starter.md" + file:"markdown_starter.md", + date: new Date("Thu Mar 23 2023 23:10:33 GMT+0700"), }, "uncommon_javascript_notes": { content_section: "Blogs", id: "uncommon_javascript_notes", title: "Uncommon JavaScript Notes - The language", brief_description: `JavaScript is super complicated, like a pain in your ass. - Even when you are quite familiar with programming languages logics and concepts, - you still find it difficult to cover major aspects in JS.`, +Even when you are quite familiar with programming languages logics and concepts, +you still find it difficult to cover major aspects in JS.`, url: "/uncommon_javascript_notes", - file: "uncommon_javascript_notes.md" + file: "uncommon_javascript_notes.md", + date: new Date("Fri Jun 16 2023 23:02:26 GMT+0700"), }, "uncommon_javascript_notes_1": { content_section: "Blogs", id: "uncommon_javascript_notes_1", title: "Uncommon JavaScript Notes - Browser: Document, Events, Interfaces", brief_description: `One thing that make JavaScript weird to learn is - how it interacts with the browser DOM, how to control the events, the forms, - and how the resource is loaded.`, +how it interacts with the browser DOM, how to control the events, the forms, +and how the resource is loaded.`, url: "/uncommon_javascript_notes_1", - file: "uncommon_javascript_notes_1.md" + file: "uncommon_javascript_notes_1.md", + date: new Date("Sun Sep 03 2023 11:13:44 GMT+0700"), }, "learn_from_react_bun_boilerplate": { content_section: "Blogs", id: "learn_from_react_bun_boilerplate", - title: "Trying to re-create React boilerplate in Bun and what I learned from it", - brief_description: `Many people are hyped with Bun for its performance and new features compared with - NodeJS. One of them is .jsx and .tsx file support with its internal transpiler, which help creating a React - app by Bun becomes more convenient. But the problem here is to have a boilerplate to optimize the feature - for creating React app.`, + title: "What I learned after re-creating a React boilerplate", + brief_description: `We can learn by re-creating something. This post is +about which things I discovered just by a React boilerplate.`, url: "/learn_from_react_bun_boilerplate", - file: "react_bun_boilerplate.md" + file: "react_bun_boilerplate.md", + date: new Date("Sun Oct 22 2023 19:43:00 GMT+0700"), }, }; diff --git a/src/markdown/markdown_starter.md b/src/markdown/markdown_starter.md index bfaea09..5556a6a 100644 --- a/src/markdown/markdown_starter.md +++ b/src/markdown/markdown_starter.md @@ -131,12 +131,12 @@ Reference-style: Here's my logo (hover to see the title text): Inline-style: -![alt text](../logo/favicon-32x32.png "Tuslipid 1") +![alt text](/logo/favicon-32x32.png "Tuslipid 1") Reference-style: ![alt text][logo] -[logo]: ../logo/favicon-32x32.png "Tuslipid 2" +[logo]: /logo/favicon-32x32.png "Tuslipid 2"
@@ -326,4 +326,4 @@ $\forall x \in X, \quad \exists y \leq \epsilon$
-$L = \frac{1}{2} \rho v^2 S C_L$ \ No newline at end of file +$L = \frac{1}{2} \rho v^2 S C_L$ diff --git a/src/markdown/react_bun_boilerplate.md b/src/markdown/react_bun_boilerplate.md new file mode 100644 index 0000000..3e3efed --- /dev/null +++ b/src/markdown/react_bun_boilerplate.md @@ -0,0 +1,402 @@ +# Introduction + +> We can learn by re-creating something. + +Recently, I love diving deeper into React and already has some works using this library. Yeah, my +website is written in React 💩, and another interesting project is written in +[NextJS](https://nextjs.org), a React's framework, which is +[Algorithms Visualizer](https://algovisual.xuankhoatu.com/). + +They both helped me discovering many meaningful aspects of frontend development, from SPA styling as +a beginner to detailed state management, hooks, components, modules, etc. + +Still, I felt like I was missing something very original. It is a kind of thing that we ought to be +aware of whenever learning a framework/library, and I only figured it out when +[Bun](https://bun.sh) was released. + +> Well, how is the React codebase initialized? + +Many people are hyped about Bun, including me. Bun supports *jsx* and *tsx* formats with its +internal transpiler, so it definitely should be great with React. For this reason, I came up with +the idea of starting some small React projects with Bun. + +However, it was not as easy as it seemed. I did not want to use Webpack and Babel if there had +already been transpiler support, but the existing templates still kept using them. If we create +a React app via Bun template as the following: + +```bash +bun create react-app appname +``` + +We simply use Bun to run `npx create-react-app` and install all +the preset dependencies. That's not what I want. 🙁 + +Thus, the first thing I have to do here is create my own custom boilerplate. +Then one day, I found the appropriate templates in the `create-templates` repository of +the Bun community (you can check them out via this +[link](https://github.com/bun-community/create-templates)). + +> So, why not try re-creating and customizing it? + +After making my own customized boilerplate, I was surprised by discovering many new aspects of +a React project. Below, I will share what I have learned so far. + +# Table of Contents + +- [How are static contents served in a web](#how-are-the-static-contents-served-in-a-web) +- [How the server-side rendering delivers React components](#how-the-server-side-rendering-delivers-react-components) +- [At the client-side](#at-the-client-side) +- [Inside the FileSystemRouter, refers to NextJS's routing](#inside-the-filesystemrouter-refers-to-nextjss-routing) +- [Custom the console.log](#custom-the-consolelog) + +# How are the static contents served in a web + +The basics comes first, or, as it should be said, everything is built on top of the basics. +Sometimes, we are just too focused on fancy stuff that we forget why there are the +things called fundamentals. This time, it hits me hard. + +I found the following code in the +[`react-ssr`](https://github.com/bun-community/create-templates/blob/main/react-ssr/dev.tsx) +template: + +```ts +function serveFromDir(config: { + directory: string; + path: string; +}): Response | null { + let basePath = path.join(config.directory, config.path); + const suffixes = ['', '.html', 'index.html']; + + for (const suffix of suffixes) { + try { + const pathWithSuffix = path.join(basePath, suffix); + const stat = statSync(pathWithSuffix); + if (stat && stat.isFile()) { + return new Response(Bun.file(pathWithSuffix)); + } + } catch (err) {} + } + + return null; +} + +export default { + async fetch(request) { + ... + let reqPath = new URL(request.url).pathname; + ... + // check public + const publicResponse = serveFromDir({ + directory: PUBLIC_DIR, + path: reqPath, + }); + if (publicResponse) return publicResponse; + ... + } +} satisfies ServeOptions; +``` + +Like a habit, my head came up with the `WTF`, that thing was frightening me. Although +it looks familiar, somehow I could not understand it at first. + +> So... I must put myself through what frightening me huh... + +It took a long time for me just to regain calm and read the code line by line, and finally, +I could break the code into the following pseudocode: + +``` +Define function serveFromDir(directory, filepath): + basepath -> join directory and file path together + suffixes -> ['', '.html', 'index.html'] as list + + For each suffix in the suffixes list: + Try do: + pathWithSuffix -> join basePath and suffix together + stat -> get pathWithSuffix's statistic + + If stat exists and stat is a file: + Return a Response with the blob object of the file located in pathWithSuffix + End if + Catch any error + End try + End for + + Return null +End define + +In Bun serve option + In async fetch(): + reqPath -> URL's pathname of request.url + + publicResponse -> serveFromDir(PUBLIC_DIR, reqPath) + If publicResponse exists (not null): + Return publicResponse as Response + end if + end fetch() +end Bun serve otion +``` + +Typically, the `serveFromDir()` method resolves the directory and filepath, then +checks the statistic in the resolved path. If it knows the statistic exists and +there is a file as the resolved path, it will return a `Response` object containing the +file. + +In the Bun serve option, we use the `serveFromDir()` to map the request pathname to +the specific public folder. Thus, if we request to get public content, for +example, at `http://localhost:3000/image.jpg`, the flow will go like this: + +1. The `reqPath` is assigned to `/image.jpg` +2. Assume we set the `PUBLIC_DIR` to `__dirname + /public` +3. In the `serveFromDir()`, we will have the `basePath` which is equivalent to + `__dirname + /public/image.jpg`. +4. In the suffix `''`, we set the `pathWithSuffix` to the same with `basePath`, + so the code will check the `image.jpg` in the `public` folder. +5. Assuming there is an `image.jpg` file in the `public` folder, it will return a `Response` + object containing the blob object of that file. +6. Finally, this `Response` object is sent to the client browser. + +Recall when we wrote our `index.html` for the first time, It turns out that everything follows the +same concept: +1. We request to the server for the content. +2. The server resolves the request path, then checks the file system. +3. The server returns status `200` if it finds out the content, or status `404` if the content + is not found. + +We can try to start a http server via the popular +[http-server](https://www.npmjs.com/package/http-server) +command in any static content folder, we will get the whole file system displayed on the browser. + +The difference here is just in the Bun serve option, we have specified a specific +directory for the app to look into, not only a root directory. + +> That's why I found the code so familiar huh... + + +# How the server-side rendering delivers React components + +Originally, React was designed to render components as client-side rendering. Nevertheless, as the +web requirements in performance, SEO supports, scaling, etc... were increasing, React must have +released the supports on the server-side. + +Since then, many frameworks have been built on top of the React server APIs, for instance, NextJS, +Remix, and Gatsby. Again, another question comes along with this concept: + +> Which APIs do those frameworks use for server-side rendering? + +We can easily look it up in React server APIs' +[documents](https://react.dev/reference/react-dom/server): + +- For Node.js Streams + +```ts +renderToPipeableStream() +renderToStaticNodeStream() +``` + +- For Web Streams + +```ts +renderToReadableStream() +``` + +- For non-streaming environments +```ts +renderToString() +renderToStaticMarkup() +``` + +With them, we can generate React components to virtual DOM directly on the server and then send it +to the client. + +In a JavaScript server runtime such as Node or my customized boilerplate, Bun, we can call those +APIs to perform the React server-side rendering conveniently. With Node, we may use +`renderToPipeableStream` or `renderToStaticNodeStream` to create a streaming connection that +delivers React components. In Bun, we can use `renderToReadableStream` for the same functionality. + +```ts +import App from "./App.tsx"; + +const stream = await renderToReadableStream(); +``` + +# At the client-side + +We got the deliveries from the server as above. Now we need to have something to catch the components +at the client. React's `createRoot()` is not a good choice because it will destroy and re-create +the DOM nodes whenever there is a new component delivered from the server. + +That is why `hydrateRoot()` appears. + +> Call `hydrateRoot` to "attach" React to existing HTML that was already rendered by React in a +> server environment. +> +> ---> [Learn more about React's hydrateRoot](https://react.dev/reference/react-dom/client/hydrateRoot) + +For the server-side routing, we may hydrate the entire document: + +```ts +import { hydrateRoot } from "react-dom/client"; +import App from "./App.tsx"; + +hydrateRoot(document, ); +``` + +# Inside the FileSystemRouter, refers to NextJS's routing + +Bun provides an API for resolving routes against file-system paths with NextJS-style file-system +routing called `FileSystemRouter`. + +I have done some debugging to find out how the routing resolver works, and the result has blown my +mind. + +Assume we are running a React app at `localhost:3000` and have a file system for routing as follows: + +``` +pages/ +|--- app.tsx + +index.tsx +``` + +In the file `index.tsx`, we call `FileSystemRouter` with the direction assigned to the `pages` +folder. + +```ts +const pageRouter = new Bun.FileSystemRouter({ + dir: './pages', + style: 'nextjs', +}); +console.log("🚀 ~ pageRouter:", pageRouter) +``` + +By logging the `pageRouter`, we get the following output at the console: + +```bash +🚀 ~ pageRouter: FileSystemRouter { + match: [Function: match], + origin: null, + reload: [Function: reload], + routes: { + "/app": "/home/user/your-work-directory/pages/app.tsx", + }, + style: "nextjs", +} +``` + +We can see the `FileSystemRouter` object has mapped the path to the file system in the +`routes` attribute. + +Then, when we call `FileSystemRouter.match` method (i.e, request to `localhost:3000/app`): + +```ts +const match = pageRouter.match(request); +console.log(match); +``` + +```bash +MatchedRoute { + filePath: "/home/user/your-work-directory/pages/app.tsx", + kind: "exact", + name: "/app", + params: {}, + pathname: "/app", + query: {}, + scriptSrc: "app.tsx", + src: "app.tsx", +} +``` + +The `FileSystemRouter` object has resolved the HTTP request and returned a `MatchedRoute` object, +which maps the request path to the file path corresponding to the `routes` attribute of the +`FileSystemRouter` object. Since then, by receiving the request, the app will have the information +to access the corresponding path. + +Therefore, if we build our React app source code (transpile *jsx/tsx* files to *js* files) in a build +directory called `build/`, we can use `FileSystemRouter` to map the request path to the *js* file +path, then send the file to the client so that the client can perform any feature of a React app. + +```ts +import * as path from "path"; + +const PROJECT_ROOT = import.meta.dir; +const BUILD_DIR = path.resolve(PROJECT_ROOT, "build"); + +const buildMatch = buildRouter.match(req); +``` + +# Custom the console.log + +This thing is not related to React, but it is an interesting thing that I found out when re-creating +the boilerplate. + +When you run `npm start` in a `create-react-app` project, you will get the below console log: + +![Create react app hello console log](/images/blogs/react_bun_boilerplate/1.webp 'create-react-app hello console log') + +> How to have that colorful console log? + +If we want to custom the color, we just simply need to use +[control character](https://en.wikipedia.org/wiki/ANSI_escape_code#Description) to color our output: + +```ts +console.log('\x1b[33m Welcome to the app! \x1b[0m'); +``` + +If we want to add prefix to console log, we need to override the `console.log` with JavaScript's +`bind`: + +```ts +const prefix = "My prefix: "; +console.log = console.log.bind(console, prefix); +``` + +Here is the starting console log in my customized boilerplate: + +```ts +/** + * Add prefix to console log + */ +const prefix = '\x1b[96m[' + new Date().toLocaleString() + ']\x1b[0m -'; +console.log = console.log.bind( console, prefix ); + +/** + * A welcome log. It will display whenever the project starts + */ +export function hiConsole(port: string | number) { + console.log("\x1b[92mCompiled successfully!\x1b[0m"); + console.log(` + +Now you can view the project in your browser: + + Local : \x1b[96mhttp://localhost:${port}\x1b[0m + IP Address : \x1b[96mhttp://127.0.0.1:${port}\x1b[0m + +🚀🚀🚀 Have fun ~ + + `); +} + +hiConsole(3000); +``` + +![My custom console log](/images/blogs/react_bun_boilerplate/2.webp 'My custom console log') + +# Conclusion + +Just by re-creating a simple boilerplate, I can enrich my understanding of React and working with +JavaScript environments generally. It also provided insights into the fundamental concept of frontend +development, which I must have missed at some points. All in all, it emphasized the importance +of going beyond the surface and gaining a deeper comprehension of the tools and processes involved. + +If you want to have a look into my customized React boilerplate with Bun, then you can go to my +Github repository [here](https://github.com/khoaxuantu/Custom-bun-react-app). + +Although it only limits React server-side rendering, it is enough to build a small project, +such as my [Meme collection](https://meme.xuankhoatu.com/). 😆 + +# References + +- [React documentations](https://react.dev) +- [Bun documentations](https://bun.sh/docs) +- [Using console colors with Node.js](https://blog.logrocket.com/using-console-colors-node-js/) + diff --git a/src/markdown/uncommon_javascript_notes.md b/src/markdown/uncommon_javascript_notes.md index f0705ef..4b5e37c 100644 --- a/src/markdown/uncommon_javascript_notes.md +++ b/src/markdown/uncommon_javascript_notes.md @@ -48,7 +48,6 @@ have very fundamental topics, instead, it contains concepts that I can easily mi for looking up JavaScript basics, you can refer to [javascript.info tutorials](https://javascript.info/) directly or [MDN (Mozilla) JavaScript manual](https://developer.mozilla.org/en-US/docs/Web/JavaScript). -

--- @@ -109,7 +108,6 @@ directly or [MDN (Mozilla) JavaScript manual](https://developer.mozilla.org/en-U + [Dynamic imports](#dynamic-imports)
-

--- @@ -323,7 +321,6 @@ const func = () => {} ```
-

## Code quality ### Polyfills and transpilers @@ -334,7 +331,6 @@ The scripts that update/add new functions. **Transpilers**\ Translate code to a different version. -

## Objects: the basics ### Objects @@ -356,7 +352,6 @@ Translate code to a different version. + `Symbol.keyFor(sym)`
-

## More about data types ### Iterables @@ -564,7 +559,6 @@ JSON.parse(str, function(key, value) { ```
-

## Advanced working with functions @@ -974,7 +968,6 @@ user.sayNow("Hello"); ```
-

## Object properties configuration @@ -1010,7 +1003,6 @@ Object.defineProperties(obj, { ```
-

## Prototypes, inheritance @@ -1120,7 +1112,6 @@ obj.join = Array.prototype.join; console.log(obj.join(',')); // Hello,World! ```
-

## Classes @@ -1153,7 +1144,6 @@ class MyClass { ```
-

## Error handling @@ -1296,7 +1286,6 @@ try { ```
-

## Promises, async/await @@ -1907,7 +1896,6 @@ f().catch(alert); // TypeError: failed to fetch ```
-

## Generators, advanced iteration @@ -2223,7 +2211,6 @@ let range = { ```
-

## Modules @@ -2312,18 +2299,15 @@ let module = await import(modulePath); ```
-

--- ## References - [Javascript.info](https://javascript.info/) - Part 1: The JavaScript language - [MDN Web Docs - Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript) - JavaScript -

--- ## Upcoming *Uncommon JavaScript Notes - Browser: Document, Events, Interfaces* - based on javascript.info's [part 2](https://javascript.info/#tab-2). -

diff --git a/src/markdown/uncommon_javascript_notes_1.md b/src/markdown/uncommon_javascript_notes_1.md index 2764810..a6fe627 100644 --- a/src/markdown/uncommon_javascript_notes_1.md +++ b/src/markdown/uncommon_javascript_notes_1.md @@ -1,4 +1,4 @@ -## Introduction +# Introduction > > One thing that make JavaScript weird to learn is > how it interacts with the browser DOM: how to control the events, the forms, @@ -16,11 +16,7 @@ using JavaScript. It is based on [javascript.info's part 2](https://javascript.i to have a fundamental knowledge of JavaScript. If you are a newbie in JS, let's check out the [javascript.info's part 1](https://javascript.info/#tab-1) first before jumping into this section. -

- ---- - -## Table of Contents +# Table of Contents
Details @@ -32,27 +28,23 @@ to have a fundamental knowledge of JavaScript. If you are a newbie in JS, let's + [Node properties: type, tag and contents](#node-properties-type-tag-and-contents) + [Attributes and properties](#attributes-and-properties) + [Modifying the document](#modifying-the-document) - + [Styles and classes](#styles-and-classes) - + [Element sizes and scrolling](#element-sizes-and-scrolling) - + [Window sizes and scrolling](#window-sizes-and-scrolling) - + [Coordinates](#coordinates) + + [Styles and classes](#styles-and-classes) + + [Element sizes and scrolling](#element-sizes-and-scrolling) + + [Window sizes and scrolling](#window-sizes-and-scrolling) + + [Coordinates](#coordinates) - [Introduction to Events](#introduction-to-events) - + [Introduction to browser events](#introduction-to-browser-events) - + [Bubbling and capturing](#bubbling-and-capturing) + + [Introduction to browser events](#introduction-to-browser-events) + + [Bubbling and capturing](#bubbling-and-capturing) + [Event delegation](#event-delegation)
-

- ---- - -## Document +# Document > Manipulate a web-page using JavaScript
-### Browser environment, specs +## Browser environment, specs
Details @@ -137,7 +129,7 @@ read the current URL and can redirect the browser to a new one.
-### DOM tree +## DOM tree
Details @@ -154,7 +146,7 @@ document.body.style.background = 'red'; setTimeout(() => document.body.style.background = '', 3000); ``` -#### An example of the DOM +### An example of the DOM ```html @@ -179,7 +171,7 @@ The DOM represents HTML as a tree structure of tags. Here's how it looks: |--- | |--- text "Something about Tusss..." ``` -#### Autocorrection +### Autocorrection If the browser encounters malformed HTML, it automatically corrects it when making the DOM. For instance, the top tag is always ``. Even if it doesn't exist in the document, it will exists in @@ -206,7 +198,7 @@ As an example, if the HTML file is the single word `"Hello"`, the browser will w > | | |--- > | | | |--- text "1" > ``` -#### Other node types +### Other node types There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usually work 4 of them: - `document` - the "entry point" into DOM - element nodes - HTML tags, the tree building blocks @@ -217,7 +209,7 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu
-### Walking the DOM +## Walking the DOM
Details @@ -228,11 +220,11 @@ corresponding DOM object. All operations on the DOM start with the `document` ob
-![DOM nodes](../images/blogs/uncommon_javascript_notes_1/1.webp "DOM nodes") +![DOM nodes](/images/blogs/uncommon_javascript_notes_1/1.webp "DOM nodes")
-#### On top: documentElement and body +### On top: documentElement and body ```html = document.documentElement = document.body @@ -240,7 +232,7 @@ corresponding DOM object. All operations on the DOM start with the `document` ob ``` > `document.body` can be `null` -#### Children: childNodes, firstChild, lastChild +### Children: childNodes, firstChild, lastChild There are 2 terms that we'll use from now on: - **Child nodes (or children)** - elements that are direct children. For instance, `` and `` are children of `` element. @@ -252,7 +244,7 @@ firstChild - gives fast access to the first children lastChild - gives fast access to the last children ``` -#### DOM collections +### DOM collections As we can see, `childNodes` looks like an array. But actually it's not an array, but rather a *collection* - a special array - like iterable object. There are 2 important consequences: @@ -271,7 +263,7 @@ There are 2 important consequences: > - DOM collections are live (current state of DOM). > - Don't use `for..in` to loop over collections. -#### Siblings and the parent +### Siblings and the parent *Siblings* are nodes that are children of the same parent. For instance, `` and `` are siblings: - `` is said to be the "next" or "right" sibling of `` @@ -284,7 +276,7 @@ alert(document.head.nextSibling); // HTMLBodyElement alert(document.body.previousSibling); // HTMLHeadElement ``` -#### Element-only navigation +### Element-only navigation Navigation properties listed above refer to all nodes. But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represents tags and form the structure of the page. @@ -292,7 +284,7 @@ So let's see more navigation links that only take *element nodes* into account:
-![element nodes](../images/blogs/uncommon_javascript_notes_1/2.webp "element nodes") +![element nodes](/images/blogs/uncommon_javascript_notes_1/2.webp "element nodes")
@@ -302,7 +294,7 @@ The links are similar to those given above, just with `Element` word inside: - `previousElementSibling`, `nextElementSibling` - neighbor elements. - `parentElement` - parent element. -#### More links: tables +### More links: tables The `` element supports (in addition to the given above) these properties: - `table.rows` - the collection of `` elements of the table. - `table.caption/tHead/tFoot` - references to elements ``, `` @@ -326,7 +318,7 @@ DOM).
-### Searching: getElement*, querySelector* +## Searching: getElement*, querySelector*
Details @@ -347,11 +339,11 @@ rarely used.
-### Node properties: type, tag and contents +## Node properties: type, tag and contents
Details -#### DOM node classes +### DOM node classes Different DOM nodes may have different properties. For instance, an element node corresponding to tag `` has a link-related properties, and the one corresponding to `` has input-related properties and so on. @@ -362,7 +354,7 @@ and other DOM nodes inherit from it.
-![DOM node classes](../images/blogs/uncommon_javascript_notes_1/3.webp "DOM node classes") +![DOM node classes](/images/blogs/uncommon_javascript_notes_1/3.webp "DOM node classes")
@@ -372,7 +364,7 @@ and other DOM nodes inherit from it. > alert(document.body.constructor.name) // HTMLBodyElement > ``` -#### The "nodeType" property +### The "nodeType" property The `nodeType` property provides one more, "old-fashioned" way to get the "type" of a DOM node. It has a numeric value: @@ -384,7 +376,7 @@ It has a numeric value: In modern scripts, we can use `instanceof` and other class-based tests to see the node type, but sometimes `nodeType` may be simpler. -#### Tag: nodeName and tagName +### Tag: nodeName and tagName Given a DOM node, we can read its tag name from `nodeName` or `tagName` properties: ```js alert(document.body.nodeName); // BODY @@ -396,11 +388,11 @@ Differences between `tagName` and `nodeName`: + For elements it means the same as `tagName`. + For other node types (text, comment, etc...) it has a string with the node type. -#### innerHTML: the contents +### innerHTML: the contents The [innerHTML](https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin) property allows to get the HTML inside the element as a string. -#### Beware: "innerHTML +=" does a full overwrite +### Beware: "innerHTML +=" does a full overwrite We can append HTML like this ```js elem.innerHTML += "
Hello !
"; @@ -418,7 +410,7 @@ elem.innerHTML = elem.innerHTML + "..." > As the content is "zeroed-out" and rewritten from the scratch, all images and other resources will be reloaded. -#### outerHTML: full HTML of the element +### outerHTML: full HTML of the element The `outerHTML` property contains the full HTML of the element. That's like `innerHTML` plus the element itself. @@ -453,7 +445,7 @@ itself. > - Another piece of HTML `

A new element

` was inserted in its place. > - `div` still has its old value. The new HTML wasn't saved to any variable. -#### nodeValue/data: text node content +### nodeValue/data: text node content The `innerHTML` property is only valid for element nodes. @@ -474,7 +466,7 @@ These two are almost the same for practical use, there are only minor specificat ``` -#### textContent: pure text +### textContent: pure text The `textContent` provides access to the *text* inside the element: only text, minus all `` ```html
@@ -489,7 +481,7 @@ The `textContent` provides access to the *text* inside the element: only text, m ``` > Writing to `textContent` is much more useful, because it allows to write text the "safe way" -#### The "hidden" property +### The "hidden" property The "hidden" attribute and the DOM property specifies whether the element is visible or not ```html
Both divs below are hidden
@@ -503,7 +495,7 @@ The "hidden" attribute and the DOM property specifies whether the element is vis ``` -#### More properties +### More properties - `value` - the value for ``, `
`, `