Messiahhh Frontend Blog and Documentation
website·Indexed 30 days ago
https://messiahhh.github.io/blog/A comprehensive collection of technical notes and documentation covering frontend development. Topics include JavaScript (BOM, DOM, Proxy, Promise), TypeScript (tsconfig.json, declaration files), React (useState, Hooks), Vue, Node.js (Event Loop, NPM, pnpm), Rust (Cargo, WebAssembly, Tauri), WebGL, Three.js, and database management with MongoDB and MySQL.
What's inside Messiahhh Blog
- Tauri is a multi-platform application solution implemented in Rust. Unlike Electron, which bundles Chromium and Node.js, Tauri achieves significantly smaller application sizes by utilizing the operating system's native renderer (WebView).
Understand how pnpm solves phantom dependencies and npm doppelgängers
pnpm improves upon npm and yarn by changing how
node_modulesare structured to solve two primary issues:Phantom Dependencies: npm and yarn use a flattened
node_modulesstructure, allowing code to import sub-dependencies that aren't explicitly listed inpackage.json. pnpm solves this by using symbolic links (soft links). The top-levelnode_modulesonly contains the packages explicitly declared inpackage.json, which point to a hidden.pnpmdirectory where the actual dependency tree resides.npm Doppelgängers: In flattened structures, if multiple packages require different versions of the same dependency, duplicate copies are often created in nested
node_modulesfolders, increasing disk usage. pnpm solves this by using a content-addressable store (typically in~/.pnpm-store). It creates hard links from the project'snode_modules/.pnpmto the global store, ensuring each version of a package is stored only once on the disk regardless of how many projects use it.
Understand the modern browser multi-process architecture
Modern browsers use a multi-process architecture to ensure stability and performance. The primary processes include:
- Browser Process (Main Process): The core coordinator.
- Renderer Process (Multiple): Responsible for converting HTML, CSS, and JS into pixels. It contains the Main Thread (Blink engine for parsing/layout/paint and V8 engine for JS execution) and the Compositor Thread (splits the layout tree into layers for independent rasterization).
- GPU Process: Handles drawing via the Skia graphics library, which interfaces with OpenGL.
- Network Process: Manages network communication.
- Plugin Process (Multiple): Handles browser plugins.
Choose between WebAssembly and Node-API for Rust integration
Depending on the target environment and performance requirements, Rust can be integrated into the frontend ecosystem using two main approaches:
- WebAssembly (WASM): Compatible with both Web browsers and Node.js. It is ideal for cross-platform compatibility and overcoming performance bottlenecks in the browser.
- Node-API: Exclusive to Node.js. It offers higher performance than WASM but requires a separate
.nodebinary compilation for every target platform.
Set up PostCSS for CSS compilation
PostCSS provides CSS compilation capabilities. It can be used via thepostcss-clifor command-line compilation or integrated into Webpack usingpostcss-loader. Configuration can be passed via command-line arguments or defined in apostcss.config.jsfile. By default, PostCSS does not transform code; plugins must be installed and configured to provide specific transformation features.Understand the Browser Same-Origin Policy
The Same-Origin Policy (SOP) prevents scripts from reading or writing resources across different origins unless authorized. Two origins are considered 'same-origin' only if their protocol, domain, and port are identical. While AJAX/Fetch requests are restricted by SOP, certain tags like<script src="">and<form>are not.Understand the relationship between JSX and the Virtual DOM
JSX is a syntactic sugar that is compiled intoReact.createElementcalls. The result ofReact.createElementis a plain JavaScript object known as aJSX.ElementorReact.ReactElement, which is commonly referred to as the Virtual DOM. These objects describe the type of element and its properties (props) but do not contain pointers to other elements.// JSX Syntax const element = <h1 class="hello">hello, world!</h1> // Compiled to: const element = React.createElement('h1', { class: 'hello' }, 'hello, world') // Resulting Virtual DOM object: const element = { $$typeof: Symbol(react.element), key: null, props: {class: "hello", children: "hello, world!"}, ref: null, type: "h1", }Understand TypeScript Declaration Files (.d.ts)
TypeScript separates variable context (found in
.jsfiles) from type context (found in.d.tsfiles). Declaration files allow developers to provide type information for JavaScript code or external libraries.TypeScript loads declaration files via:
tsconfig.json'sincludearray (all.tsand.d.tsfiles).tsconfig.json'stypesandliboptions, which default tonode_modules/@typesandnode_modules/typescript/librespectively.
Libraries typically distribute types in two ways:
- As a separate package in
node_modules/@types. - Bundled with the library, with the path specified in
package.jsonunder thetypesfield (requires explicit import to get type hints).
Understand the JavaScript Event Loop and Task Queues
The event loop manages the execution of code by coordinating between the main thread and task queues. Tasks are categorized into two types:
- Macro-tasks: Include the initial script execution,
setTimeout,setInterval, I/O operations (e.g., AJAX, file reading), UI events (e.g., clicks), andsetImmediate(Node.js specific). - Micro-tasks: Most commonly
Promise.then().
Execution Rule: The event loop executes one macro-task, then exhausts the entire micro-task queue, then moves to the next macro-task.
- Macro-tasks: Include the initial script execution,
Understand JavaScript primitive wrapper types
When calling methods on primitive values (e.g., calling.toString()on a string literal), JavaScript temporarily wraps the primitive in an object of the corresponding wrapper type, executes the method, and then discards the object.// Conceptual process of '1'.toString() var s = new String('1'); s.toString(); s = null;Intercept object property access and modification with Proxy
TheProxyobject allows you to create a wrapper around a target object to intercept and redefine fundamental operations, such as property lookup (get) and assignment (set).let handler = { get: function (target, propKey, receiver) { console.log(`Reading property: ${propKey}`); return target[propKey]; }, set: function (target, propKey, newValue, receiver) { console.log(`Setting property: ${propKey} to ${newValue}`); target[propKey] = newValue; return true; // Return true to indicate success } }; let proxy = new Proxy({ name: 'akara' }, handler); proxy.name; // Triggers 'get' handler proxy.age = 20; // Triggers 'set' handlerUnderstand the WebGL Rendering Pipeline
The WebGL rendering process follows these primary stages:
- Preparation: Compiling shaders, linking programs, creating VBOs, configuring VAOs, and setting Uniforms/Textures.
- Execution: Calling
gl.drawArrays()to send draw commands to the GPU. - Vertex Processing: The Vertex Shader runs for each vertex to transform coordinates into Homogeneous Clip Space using three matrices:
- Model Matrix: Model Space $\rightarrow$ World Space.
- View Matrix: World Space $\rightarrow$ Camera/View Space.
- Projection Matrix: Camera Space $\rightarrow$ Clip Space (Perspective or Orthographic).
- Rasterization: GPU performs perspective division to get Normalized Device Coordinates (NDC) [-1, 1], clips vertices outside the view frustum, maps to the Viewport, and interpolates varying values for pixels.
- Fragment Processing: The Fragment (Pixel) Shader runs for each pixel to determine the final color, which is written to the Framebuffer.
- Finalization: Depth testing and other per-pixel operations.