Last active
March 4, 2025 07:37
-
-
Save 0xdevalias/916e4ababd3cb5e3470b07a024cf3125 to your computer and use it in GitHub Desktop.
Revisions
-
0xdevalias revised this gist
Mar 4, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1068,7 +1068,7 @@ const x2 = a1.b1.div` ### My Other Related Deepdive Gist's and Projects - https://gist.github.com/0xdevalias - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias' gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) -
0xdevalias revised this gist
Mar 4, 2025 . 1 changed file with 8 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -65,6 +65,10 @@ And other similar deep dives / reverse engineering / module identification attem - > `[plugin]` plugin to support unminifying `goober` CSS-in-JS library patterns + related JSX decompilation - ?etc? Including this new gist that I created to collate this sort of deep dive research on various modules I have identified: - [JavaScript Web App Reverse Engineering - Module Identification (0xdevalias' gist)](https://gist.github.com/0xdevalias/28c18edfc17606f09cf413f97e404a60#javascript-web-app-reverse-engineering---module-identification) ## Comment 1 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issue-1992063389)) @@ -1064,12 +1068,15 @@ const x2 = a1.b1.div` ### My Other Related Deepdive Gist's and Projects - - https://gist.github.com/0xdevalias - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias' gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias' gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (`__next_f`, etc) (0xdevalias' gist))](https://gist.github.com/0xdevalias/ac465fb2f7e6fded183c2a4273d21e61#react-server-components-nextjs-v13-and-webpack-notes-on-streaming-wire-format-__next_f-etc) - [Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias gist)](https://gist.github.com/0xdevalias/31c6574891db3e36f15069b859065267#fingerprinting-minified-javascript-libraries--ast-fingerprinting--source-code-similarity--etc) - [JavaScript Web App Reverse Engineering - Module Identification (0xdevalias' gist)](https://gist.github.com/0xdevalias/28c18edfc17606f09cf413f97e404a60#javascript-web-app-reverse-engineering---module-identification) - [Reverse Engineered Webpack Tailwind-Styled-Component (0xdevalias' gist)](https://gist.github.com/0xdevalias/916e4ababd3cb5e3470b07a024cf3125#reverse-engineered-webpack-tailwind-styled-component) - [Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [Debugging Electron Apps (and related memory issues) (0xdevalias' gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [devalias' Beeper CSS Hacks (0xdevalias' gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) -
0xdevalias revised this gist
Mar 4, 2025 . 1 changed file with 37 additions and 32 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,6 +2,26 @@ Deep Dive into reverse engineering how some webpacked code relates to the `styled-components` / `Tailwind-Styled-Component` libs. ## Table of Contents <!-- TOC start (generated with https://bitdowntoc.derlin.ch/) --> - [Overview](#overview) - [Comment 1](#comment-1) - [Comment 2](#comment-2) - [Comment 3](#comment-3) - [Comment 4](#comment-4) - [Comment 5](#comment-5) - [Comment 6](#comment-6) - [Comment 7](#comment-7) - [Smart-Rename for 'function replaces self' memoisation pattern](#smart-rename-for-function-replaces-self-memoisation-pattern) - [Comment 8](#comment-8) - [Smart rename for `styled-components`'ish patterns](#smart-rename-for-styled-componentsish-patterns) - [See Also](#see-also) - [My Other Related Deepdive Gist's and Projects](#my-other-related-deepdive-gists-and-projects) <!-- TOC end --> ## Overview This was originally posted on the following issue, and the heading structure here will relate to the individual comments that were made there: - https://github.com/pionxzh/wakaru/issues/40 @@ -45,37 +65,6 @@ And other similar deep dives / reverse engineering / module identification attem - > `[plugin]` plugin to support unminifying `goober` CSS-in-JS library patterns + related JSX decompilation - ?etc? ## Comment 1 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issue-1992063389)) @@ -1069,4 +1058,20 @@ const x2 = a1.b1.div` ` // ..snip.. ``` ## See Also ### My Other Related Deepdive Gist's and Projects - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias' gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias' gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (`__next_f`, etc) (0xdevalias' gist))](https://gist.github.com/0xdevalias/ac465fb2f7e6fded183c2a4273d21e61#react-server-components-nextjs-v13-and-webpack-notes-on-streaming-wire-format-__next_f-etc) - [Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias' gist)](https://gist.github.com/0xdevalias/31c6574891db3e36f15069b859065267#fingerprinting-minified-javascript-libraries--ast-fingerprinting--source-code-similarity--etc) - [Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [Debugging Electron Apps (and related memory issues) (0xdevalias' gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [devalias' Beeper CSS Hacks (0xdevalias' gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) - [Reverse Engineering Golang (0xdevalias' gist)](https://gist.github.com/0xdevalias/4e430914124c3fd2c51cb7ac2801acba#reverse-engineering-golang) - [Reverse Engineering on macOS (0xdevalias' gist)](https://gist.github.com/0xdevalias/256a8018473839695e8684e37da92c25#reverse-engineering-on-macos) -
0xdevalias revised this gist
Mar 4, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -42,7 +42,7 @@ And other similar deep dives / reverse engineering / module identification attem - https://github.com/j4k0xb/webcrack/issues/151 - > `[plugin]` plugin to support WordPress Gutenberg specific blocks features (including how it injects `window.React`, `window.wp.element`, etc) within JSX decompilation - https://github.com/j4k0xb/webcrack/issues/152 - > `[plugin]` plugin to support unminifying `goober` CSS-in-JS library patterns + related JSX decompilation - ?etc? ## Table of Contents -
0xdevalias revised this gist
Mar 4, 2025 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -36,6 +36,14 @@ And other similar deep dives / reverse engineering / module identification attem - https://github.com/pionxzh/wakaru/issues/89 - > `[module-detection]` `radix-ui/primitives` - ?etc? - https://github.com/j4k0xb/webcrack/issues?q=%22%5Bplugin%5D%22 - https://github.com/j4k0xb/webcrack/issues/143 - > `[plugin]` Add support for `data-sentry-component` / `data-sentry-element` / `data-sentry-source-file` (from `@sentry/babel-plugin-component-annotate`) - https://github.com/j4k0xb/webcrack/issues/151 - > `[plugin]` plugin to support WordPress Gutenberg specific blocks features (including how it injects `window.React`, `window.wp.element`, etc) within JSX decompilation - https://github.com/j4k0xb/webcrack/issues/152 - > `[plugin]` plugin to support unminifying goober CSS-in-JS library patterns + related JSX decompilation - ?etc? ## Table of Contents -
0xdevalias revised this gist
May 3, 2024 . 1 changed file with 8 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -57,13 +57,14 @@ And other similar deep dives / reverse engineering / module identification attem ### My Other Related Deepdive Gist's and Projects - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias' gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias' gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (`__next_f`, etc) (0xdevalias' gist))](https://gist.github.com/0xdevalias/ac465fb2f7e6fded183c2a4273d21e61#react-server-components-nextjs-v13-and-webpack-notes-on-streaming-wire-format-__next_f-etc) - [Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias' gist)](https://gist.github.com/0xdevalias/31c6574891db3e36f15069b859065267#fingerprinting-minified-javascript-libraries--ast-fingerprinting--source-code-similarity--etc) - [Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [Debugging Electron Apps (and related memory issues) (0xdevalias' gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [devalias' Beeper CSS Hacks (0xdevalias' gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) - [Reverse Engineering Golang (0xdevalias' gist)](https://gist.github.com/0xdevalias/4e430914124c3fd2c51cb7ac2801acba#reverse-engineering-golang) - [Reverse Engineering on macOS (0xdevalias' gist)](https://gist.github.com/0xdevalias/256a8018473839695e8684e37da92c25#reverse-engineering-on-macos) -
0xdevalias revised this gist
May 3, 2024 . 1 changed file with 31 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,37 @@ Deep Dive into reverse engineering how some webpacked code relates to the `style This was originally posted on the following issue, and the heading structure here will relate to the individual comments that were made there: - https://github.com/pionxzh/wakaru/issues/40 - > [module-detection / smart-rename] `styled-components` / `Tailwind-Styled-Component` libs For the more general case of 'module detection' (and related concepts), see these issues: - https://github.com/pionxzh/wakaru/issues/41 - > Module detection - https://github.com/pionxzh/wakaru/issues/73 - > add a 'module graph' - https://github.com/pionxzh/wakaru/issues/74 - > explore 'AST fingerprinting' for module/function identification (eg. to assist smart / stable renames, etc) And other similar deep dives / reverse engineering / module identification attempts: - https://github.com/pionxzh/wakaru/issues?q=%22%5Bmodule-detection%5D%22 - https://github.com/pionxzh/wakaru/issues/50 - > Support detect and replace `swc`'s `runtime-helpers` - https://github.com/pionxzh/wakaru/issues/55 - > Support detect and replace `microsoft/tslib`'s `runtime-helpers` - https://github.com/pionxzh/wakaru/issues/79 - > `[module-detection]` `zustand` - React state management - https://github.com/pionxzh/wakaru/issues/80 - > `[module-detection]` `js-xss` - https://github.com/pionxzh/wakaru/issues/86 - > `[module-detection]` `statsig-io/js-client` - https://github.com/pionxzh/wakaru/issues/87 - > `[module-detection]` `DataDog/browser-sdk` - https://github.com/pionxzh/wakaru/issues/88 - > `[module-detection]` `TanStack/query` - https://github.com/pionxzh/wakaru/issues/89 - > `[module-detection]` `radix-ui/primitives` - ?etc? ## Table of Contents -
0xdevalias revised this gist
Apr 30, 2024 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -27,9 +27,10 @@ This was originally posted on the following issue, and the heading structure her ### My Other Related Deepdive Gist's and Projects - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias gist)](https://gist.github.com/0xdevalias/31c6574891db3e36f15069b859065267#fingerprinting-minified-javascript-libraries--ast-fingerprinting--source-code-similarity--etc) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [Debugging Electron Apps (and related memory issues) (0xdevalias gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) -
0xdevalias revised this gist
Dec 10, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -34,6 +34,7 @@ This was originally posted on the following issue, and the heading structure her - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) - [Reverse Engineering Golang (0xdevalias' gist)](https://gist.github.com/0xdevalias/4e430914124c3fd2c51cb7ac2801acba#reverse-engineering-golang) - [Reverse Engineering on macOS (0xdevalias' gist)](https://gist.github.com/0xdevalias/256a8018473839695e8684e37da92c25#reverse-engineering-on-macos) ## Comment 1 -
0xdevalias revised this gist
Nov 27, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -33,6 +33,7 @@ This was originally posted on the following issue, and the heading structure her - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) - [Reverse Engineering Golang (0xdevalias' gist)](https://gist.github.com/0xdevalias/4e430914124c3fd2c51cb7ac2801acba#reverse-engineering-golang) ## Comment 1 -
0xdevalias revised this gist
Nov 27, 2023 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,15 +9,18 @@ This was originally posted on the following issue, and the heading structure her ## Table of Contents <!-- TOC start (generated with https://github.com/derlin/bitdowntoc) --> - [See Also](#see-also) - [My Other Related Deepdive Gist's and Projects](#my-other-related-deepdive-gists-and-projects) - [Comment 1](#comment-1) - [Comment 2](#comment-2) - [Comment 3](#comment-3) - [Comment 4](#comment-4) - [Comment 5](#comment-5) - [Comment 6](#comment-6) - [Comment 7](#comment-7) - [Comment 8](#comment-8) <!-- TOC end --> ## See Also -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,6 +16,7 @@ This was originally posted on the following issue, and the heading structure her - [Comment 3](#comment-3) - [Comment 4](#comment-4) - [Comment 5](#comment-5) - [Comment 6](#comment-6) - [Comment 7](#comment-7) ## See Also -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,8 +30,6 @@ This was originally posted on the following issue, and the heading structure her - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) ## Comment 1 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issue-1992063389)) -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ This was originally posted on the following issue, and the heading structure her - https://github.com/pionxzh/wakaru/issues/40 - > smart-rename/similar for `styled-components` / `Tailwind-Styled-Component` libs ## Table of Contents - [See Also](#see-also) - [My Other Related Deepdive Gist's and Projects](#my-other-related-deepdive-gists-and-projects) -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 11 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,17 @@ This was originally posted on the following issue, and the heading structure her - https://github.com/pionxzh/wakaru/issues/40 - > smart-rename/similar for `styled-components` / `Tailwind-Styled-Component` libs # Table of Contents - [See Also](#see-also) - [My Other Related Deepdive Gist's and Projects](#my-other-related-deepdive-gists-and-projects) - [Comment 1](#comment-1) - [Comment 2](#comment-2) - [Comment 3](#comment-3) - [Comment 4](#comment-4) - [Comment 5](#comment-5) - [Comment 7](#comment-7) ## See Also ### My Other Related Deepdive Gist's and Projects -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,6 @@ This was originally posted on the following issue, and the heading structure her - [Debugging Electron Apps (and related memory issues) (0xdevalias gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 15 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,21 @@ This was originally posted on the following issue, and the heading structure her - https://github.com/pionxzh/wakaru/issues/40 - > smart-rename/similar for `styled-components` / `Tailwind-Styled-Component` libs ## See Also ### My Other Related Deepdive Gist's and Projects - https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts. - [Debugging Electron Apps (and related memory issues) (0xdevalias gist)](https://gist.github.com/0xdevalias/428e56a146e3c09ec129ee58584583ba#debugging-electron-apps-and-related-memory-issues) - [Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code) - [Reverse Engineering Webpack Apps (0xdevalias gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps) - [Reverse Engineered Webpack Tailwind-Styled-Component (0xdevalias gist)](https://gist.github.com/0xdevalias/916e4ababd3cb5e3470b07a024cf3125#reverse-engineered-webpack-tailwind-styled-component) - [Reverse engineering ChatGPT's frontend web app + deep dive explorations of the code (0xdevalias gist)](https://gist.github.com/0xdevalias/4ac297ee3f794c17d0997b4673a2f160#reverse-engineering-chatgpts-frontend-web-app--deep-dive-explorations-of-the-code) - [Bypassing Cloudflare, Akamai, etc (0xdevalias gist)](https://gist.github.com/0xdevalias/b34feb567bd50b37161293694066dd53#bypassing-cloudflare-akamai-etc) - [devalias' Beeper CSS Hacks (0xdevalias gist)](https://gist.github.com/0xdevalias/3d2f5a861335cc1277b21a29d1285cfe#beeper-custom-theme-styles) ### My Other Related Deepdive Gist's and Projects ## Comment 1 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issue-1992063389)) -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -725,7 +725,7 @@ I wonder if something in the webpack minimisation process is applying a memo to Here's the first one, and i'll add the other one in a new comment after this. ### Smart-Rename for 'function replaces self' memoisation pattern We could potentially detect memoisation patterns like the following, and rename the function something more useful: @@ -799,7 +799,7 @@ This could use the standard 'rename function' code that `wakaru` already uses to ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809962543)) ### Smart rename for `styled-components`'ish patterns @pionxzh As per my last comment, here is the other smart-rename'ish pattern that might be useful here: -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 286 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -715,4 +715,289 @@ y = d.Z.span( ..it kind of feels like the memoisation could be happening at a higher layer than `tailwind-merge`, and possibly even higher than `Tailwind-Styled-Component`.. I wonder if something in the webpack minimisation process is applying a memo to the text passed to the template tags; or perhaps this might even be something that is being done manually in the webpacked app itself. ## Comment 7 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809841149)) @pionxzh Obviously all of the above deep dive research is a LOT, and I wouldn't expect you to read it all in depth right now, but based on what I discovered above, I think it might be possible to make some simple'ish inferences (though without being as robust as perfectly matching the module first (https://github.com/pionxzh/wakaru/issues/41)). Here's the first one, and i'll add the other one in a new comment after this. ## Smart-Rename for 'function replaces self' memoisation pattern We could potentially detect memoisation patterns like the following, and rename the function something more useful: ```js function p() { var e = (0, r._)([ "\n absolute w-4 h-4 rounded-full text-[10px] text-white flex justify-center items-center right-0 top-[20px] -mr-2 border border-white\n ", "\n ", "\n", ]); return ( (p = function () { return e; }), e ); } ``` Here's some basic code that ChatGPT generated for this: ```js const jscodeshift = require('jscodeshift').withParser('babylon'); const sourceCode = `TODO` // TODO: include the source code to be processed here const ast = jscodeshift(sourceCode); ast.find(jscodeshift.FunctionDeclaration) .forEach(path => { // Check if this function reassigns itself const hasSelfReassignment = jscodeshift(path) .find(jscodeshift.AssignmentExpression) .some(assignmentPath => { const left = assignmentPath.value.left; return left.type === 'Identifier' && left.name === path.value.id.name; }); if (hasSelfReassignment) { const oldName = path.value.id.name const newName = `${path.value.id.name}Memo` // Rename the function path.value.id.name = newName; console.log(`Function ${oldName} is using a memoization pattern, renamed to ${newName}.`); } else { console.log(`Function ${path.value.id.name} is NOT using a memoization pattern.`); } }); // Further transformation code and printing the modified source code ``` You can see it in a REPL here: - https://replit.com/@0xdevalias/Rewriting-JavaScript-Variables-via-AST-Examples#jscodeshift-detect-self-memoize-function.js The current output is something like this: ``` $ node jscodeshift-detect-self-memoize-function.js Function p is using a memoization pattern, renamed to pMemo. Function q is NOT using a memoization pattern. ``` This could use the standard 'rename function' code that `wakaru` already uses to assign it a better name. ## Comment 8 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809962543)) ## Smart rename for `styled-components`'ish patterns @pionxzh As per my last comment, here is the other smart-rename'ish pattern that might be useful here: While it wouldn't be fully robust unless we could guarantee the imported library (see #41), it seems that both `styled-components` and `Tailwind-Styled-Component` use a similar pattern of mapping over a set of standard DOM element names ([Ref](https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/domElements.ts)) to create their basic components. In my example webpack code, this resulted in code that looked like the following: ```js var b = d.Z.div(m(), function (e) { return e.$isMessageRedesign ? "rounded-full h-7 w-7" : "rounded-sm h-[30px] w-[30px]"; }), y = d.Z.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ), ``` My assumption is that this code will always end up being accessed by `x.y.[domElement]`, where `x` and `y` could be any arbitrary identifier; and `domElement` is a name from the following list (or similar, depending on which lib it is): - https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/domElements.ts Based on those assumptions, we should be able to use some AST code like the following to detect usages of `styled-components`'ish patterns: ```js const jscodeshift = require('jscodeshift').withParser('babylon'); const sourceCode = ` function m() { var e = (0, r._)(["foo", "bar"]); return ( (m = function () { return e; }), e ); } function p() { var e = (0, r._)(["foo", "bar", "baz"]); return ( (p = function () { return e; }), e ); } var b = x.y.div(m(), function (e) { return e.$isMessageRedesign ? "rounded-full h-7 w-7" : "rounded-sm h-[30px] w-[30px]"; }), y = x.y.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ); const x0 = div("foo", (e) => "bar") const x1 = a1.div("foo", (e) => "bar") const x2 = a1.b1.div("foo", (e) => "bar") const x3 = a1.b1.c1.div("foo", (e) => "bar") const y0 = notAnElement("foo", (e) => "bar") const y1 = a1.notAnElement("foo", (e) => "bar") const y2 = a1.b1.notAnElement("foo", (e) => "bar") const y3 = a1.b1.c1.notAnElement("foo", (e) => "bar") `; const domElements = [ 'a', 'abbr', // ..snip.. 'div', // ..snip.. 'span', // ..snip.. ]; const ast = jscodeshift(sourceCode); ast.find(jscodeshift.CallExpression) .forEach(path => { // Check if the callee is a MemberExpression if (path.value.callee.type === 'MemberExpression') { const memberExp = path.value.callee; // Check if the object of the MemberExpression is also a MemberExpression if (memberExp.object.type === 'MemberExpression') { const innerMemberExp = memberExp.object; // Ensure that the object of the inner MemberExpression is not another MemberExpression if (innerMemberExp.object.type !== 'MemberExpression' && domElements.includes(memberExp.property.name)) { console.log(`Found styled-components'ish pattern ${innerMemberExp.object.name}.${innerMemberExp.property.name}.${memberExp.property.name}()`); // Transform CallExpression to TaggedTemplateExpression const args = path.value.arguments; // The first item in quasis is the static text before the first expression, the first item in expressions is the first dynamic expression, the second item in quasis is the static text after the first expression and before the second expression, and so on. const expressions = []; const quasis = []; args.forEach((arg, index) => { let value; const isFirst = index === 0; const isLast = index === args.length - 1; const prefix = isFirst ? '\n ' : '\n ' const suffix = isLast ? '\n' : '\n ' if (arg.type === 'StringLiteral') { // Directly include string literals in the template value = { raw: `${prefix}${arg.value}${suffix}`, cooked: `${prefix}${arg.value}${suffix}` }; quasis.push(jscodeshift.templateElement(value, false)); } else { if (isFirst) { value = { raw: prefix, cooked: prefix }; quasis.push(jscodeshift.templateElement(value, isLast)); } value = { raw: suffix, cooked: suffix }; quasis.push(jscodeshift.templateElement(value, isLast)); // For non-string expressions, place them in ${} expressions.push(arg); } }); const taggedTemplateExp = jscodeshift.taggedTemplateExpression( memberExp, jscodeshift.templateLiteral(quasis, expressions) ); // Replace the original CallExpression with the new TaggedTemplateExpression jscodeshift(path).replaceWith(taggedTemplateExp); } } } }); const newSourceCode = ast.toSource(); console.log("---"); console.log("Rewritten code:"); console.log(newSourceCode); ``` You can see it in a REPL here: - https://replit.com/@0xdevalias/Rewriting-JavaScript-Variables-via-AST-Examples#jscodeshift-detect-styled-components.js The current output is something like this: ``` $ node jscodeshift-detect-styled-components.js Found styled-components'ish pattern x.y.div() Found styled-components'ish pattern x.y.span() Found styled-components'ish pattern a1.b1.div() --- Rewritten code: // ..snip.. var b = x.y.div` ${m()} ${function (e) { return e.$isMessageRedesign ? "rounded-full h-7 w-7" : "rounded-sm h-[30px] w-[30px]"; }} `; var y = x.y.span` ${p()} ${function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }} ${function (e) { return "danger" === e.$type && "bg-red-500 text-white"; }} `; // ..snip.. const x2 = a1.b1.div` foo ${(e) => "bar"} ` // ..snip.. ``` -
0xdevalias revised this gist
Nov 14, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ # Reverse Engineered Webpack Tailwind-Styled-Component Deep Dive into reverse engineering how some webpacked code relates to the `styled-components` / `Tailwind-Styled-Component` libs. This was originally posted on the following issue, and the heading structure here will relate to the individual comments that were made there: -
0xdevalias created this gist
Nov 14, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,718 @@ # Reverse Engineered Webpack Tailwind-Styled-Component Deep Dive into reverse engineering how some webpacked code relates to the styled-components / Tailwind-Styled-Component libs. This was originally posted on the following issue, and the heading structure here will relate to the individual comments that were made there: - https://github.com/pionxzh/wakaru/issues/40 - > smart-rename/similar for `styled-components` / `Tailwind-Styled-Component` libs ## Comment 1 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issue-1992063389)) While looking through some decompiled code in a rather complex webpack bundled app, I've identified what seems to be the `styled-components` library (or something very similar to it): - https://github.com/styled-components/styled-components It would be cool to be able to handle `styled-components` when reversing code. ## Comment 2 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809608312)) The webpacked code that includes this (in this app) is in the following chunk: - https://github.com/0xdevalias/chatgpt-source-watch/blob/main/unpacked/_next/static/chunks/pages/_app.js And within this code, it specifically seems to be in `34303: function (U, B, G) {` (which unpacks in this tool to `module-34303.js`) - https://github.com/search?q=isTwElement%3F&type=code Within the original code for that module, I identified a section of code that looks like this: ```js tU = [ "a", abbr", "address", "area", "article", // ..snip.. ``` Which at first I manually correlated with the following from `styled-components`: - https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/utils/domElements.ts#L3-L8 ```js const elements = [ 'a', 'abbr', 'address', 'area', 'article', ``` But then later found this code: ```js tB = Symbol("isTwElement?"), ``` Which I then searched for on GitHub code search: - https://github.com/search?q=isTwElement%3F&type=code That seemed to lead me to these 2 repos: - https://github.com/search?q=repo%3AMathiasGilson%2FTailwind-Styled-Component%20isTwElement%3F&type=code - https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/tailwind.tsx#L5 - https://github.com/search?q=repo%3Aaplr%2Ftailwind-components%20isTwElement%3F&type=code - https://github.com/aplr/tailwind-components/blob/main/packages/tailwind-components/src/utils/isTailwindComponent.ts#L3 At first glance, both of these repos also appear to have the same `domElements` as above: - https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/domElements.ts#L1-L6 - https://github.com/aplr/tailwind-components/blob/main/packages/tailwind-components/src/utils/domElements.ts#L1-L6 But after accounting for differences in spacing, quotes, etc; and diffing them, it looks like the `Tailwind-Styled-Components` / `tailwind-components` libs have extra entries for `head` / `title` that `styled-components` doesn't have, and `styled-components` has a `use` entry that the other two don't have. Based on this, we can compare against the code in our webpack bundled code, and see that it also has `head` / `title`, and is missing `use`; implying that it is one of the Tailwind Styled Components libs. ## Comment 3 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809609240)) Right at the top of our webpacked code we see this `Z` wrapper that returns `tq`: ```js 34303: function (U, B, G) { "use strict"; G.d(B, { Z: function () { return tq; }, }); // ..snip.. ``` We find `tq` right at the bottom of this module: ```js // ..snip.. return ( (J[tB] = !0), "string" != typeof U ? (J.displayName = U.displayName || U.name || "tw.Component") : (J.displayName = "tw." + U), (J.withStyle = (U) => V(Z.concat(U))), J ); }; return V(); }, t$ = tU.reduce((U, B) => ({ ...U, [B]: tz(B) }), {}), tq = Object.assign(tz, t$); }, ``` We can see some code here that sets `displayName` to `tw.Component` as a fallback. Searching those 2 tailwind repo's for `tw.Component` leads us to the following files: - https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/tailwind.tsx#L244 - https://github.com/aplr/tailwind-components/blob/main/packages/tailwind-components/src/utils/getComponentName.ts#L7 Contrasting the function code that contains the `tw.Component` string with our webpacked code, it looks like it the webpacked code is using `Tailwind-Styled-Component`. Looking at the end of the code in that file, we can see how it correlates with `t$` / `tq` above: - https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/tailwind.tsx#L257-L267 ```ts const intrinsicElementsMap: IntrinsicElementsTemplateFunctionsMap = domElements.reduce( <K extends IntrinsicElementsKeys>(acc: IntrinsicElementsTemplateFunctionsMap, DomElement: K) => ({ ...acc, [DomElement]: templateFunctionFactory(DomElement) }), {} as IntrinsicElementsTemplateFunctionsMap ) const tw: TailwindInterface = Object.assign(templateFunctionFactory, intrinsicElementsMap) export default tw ``` A typical webpack module when unminimised has the following basic structure: ```js function(module, exports, require) { // Module code goes here } ``` We can see how that maps to our webpacked code: ```js 34303: function (U, B, G) { ``` This means that: - `U`: module - `B`: exports - `G`: require The `Tailwind-Styled-Component` code above ends in `export default tw`, and in our webpacked code we can see that it essentially exports the `TailWindInterface` as `Z`: ```js G.d(B, { Z: function () { return tq; }, }); ``` ## Comment 4 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809625370)) Based on this knowledge, we can now find references to `Tailwind-Styled-Component` across the webpacked code by looking for an import of the module containing it (in this case: `34303`); and then looking for the name it was exported with (in this case: `Z`) Looking at a different chunk file that imports `34303`: - https://github.com/0xdevalias/chatgpt-source-watch/blob/main/unpacked/_next/static/chunks/496.js We can find a module that uses `34303` like the following: ```js 46110: function (e, t, n) { // ..snip.. var r = n(4337), // ..snip.. d = n(34303), // ..snip.. var b = d.Z.div(m(), function (e) { return e.$isMessageRedesign ? "rounded-full h-7 w-7" : "rounded-sm h-[30px] w-[30px]"; }), y = d.Z.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ), // ..snip.. ``` We can see that the `34303` module is imported as `d`, and then the `Tailwind-Styled-Component` `TailWindInterface` is accessed as: - `d.Z.div` - `d.Z.span` - etc Looking back at how `TailWindInterface` is defined ([Ref](https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/tailwind.tsx#L257-L267)), we can see that it first reduces `domElements` ([Ref](https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/domElements.ts)) to `intrinsicElementsMap`; then `Object.assign`'s that to `templateFunctionFactory`: ```ts const intrinsicElementsMap: IntrinsicElementsTemplateFunctionsMap = domElements.reduce( <K extends IntrinsicElementsKeys>(acc: IntrinsicElementsTemplateFunctionsMap, DomElement: K) => ({ ...acc, [DomElement]: templateFunctionFactory(DomElement) }), {} as IntrinsicElementsTemplateFunctionsMap ) const tw: TailwindInterface = Object.assign(templateFunctionFactory, intrinsicElementsMap) export default tw ``` We can also see the type definition for `TailwindInterface`: ```ts export type IntrinsicElementsTemplateFunctionsMap = { [RTag in keyof JSX.IntrinsicElements]: TemplateFunction<JSX.IntrinsicElements[RTag]> } export interface TailwindInterface extends IntrinsicElementsTemplateFunctionsMap { <C extends TailwindComponent<any, any>>(component: C): TemplateFunction< TailwindComponentInnerProps<C>, TailwindComponentInnerOtherProps<C> > <C extends React.ComponentType<any>>(component: C): TemplateFunction< // Prevent functional components without props infering props as `unknown` C extends (P?: never) => any ? {} : React.ComponentPropsWithoutRef<C> > <C extends keyof JSX.IntrinsicElements>(component: C): TemplateFunction<JSX.IntrinsicElements[C]> } ``` We can read about `JSX.IntrinsicElements` in TypeScript here: - https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements - > In order to understand type checking with JSX, you must first understand the difference between intrinsic elements and value-based elements. Given a JSX expression `<expr />`, `expr` may either refer to something intrinsic to the environment (e.g. a `div` or `span` in a DOM environment) or to a custom component that you’ve created. - > TypeScript uses the [same convention that React does](http://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components) for distinguishing between these. An intrinsic element always begins with a lowercase letter, and a value-based element always begins with an uppercase letter. - > Intrinsic elements are looked up on the special interface `JSX.IntrinsicElements`. By default, if this interface is not specified, then anything goes and intrinsic elements will not be type checked. However, if this interface is present, then the name of the intrinsic element is looked up as a property on the `JSX.IntrinsicElements` interface. Explaining those types with ChatGPT: > Thanks for sharing the actual `TailwindInterface`. This interface extends `IntrinsicElementsTemplateFunctionsMap` and provides overloads for a generic function. Let's break down its structure: > > ### `IntrinsicElementsTemplateFunctionsMap` > > This type maps each key of `JSX.IntrinsicElements` (which represents every possible HTML tag as a string, like `'a'`, `'div'`, `'span'`, etc.) to a `TemplateFunction` specific to that tag's type. The `TemplateFunction` is a generic type that likely encapsulates the logic for creating styled components for each intrinsic element. > > ### `TailwindInterface` > > This interface extends `IntrinsicElementsTemplateFunctionsMap`, meaning it includes all mappings from that type. Additionally, it provides three generic function signatures: > > 1. **For Tailwind Components**: > - This overload is for when the `component` is a Tailwind-specific component. The `TemplateFunction` returned is specific to the props of the Tailwind component. > - `TailwindComponentInnerProps<C>` and `TailwindComponentInnerOtherProps<C>` are likely types that extract or define the props relevant to a Tailwind component. > > 2. **For General React Components**: > - This overload handles cases where the `component` is a general React component. The `TemplateFunction` generated is based on the component's props. > - The comment indicates special handling to prevent functional components without props from having their props inferred as `unknown`. Instead, it defaults to an empty object (`{}`) if the component does not accept any props. > > 3. **For Intrinsic Elements**: > - This is similar to the mappings in `IntrinsicElementsTemplateFunctionsMap`, but it's defined as a function overload. It allows calling the `TailwindInterface` function with an intrinsic element (like `'div'`, `'a'`, etc.) as the argument, returning a `TemplateFunction` for that specific element. > > These overloads provide flexibility in how the `TailwindInterface` can be used. It supports creating styled components for both specific Tailwind components and general React components, as well as for any standard HTML element represented in `JSX.IntrinsicElements`. This design makes the `TailwindInterface` highly adaptable and usable across different types of components in a React application using Tailwind CSS for styling. Based on that interface, we can now better understand what the `d.Z.div` / `d.Z.span` code from above is doing: ```js // ..snip.. function m() { var e = (0, r._)([ "relative p-1 ", " text-white flex items-center justify-center", ]); return ( (m = function () { return e; }), e ); } function p() { var e = (0, r._)([ "\n absolute w-4 h-4 rounded-full text-[10px] text-white flex justify-center items-center right-0 top-[20px] -mr-2 border border-white\n ", "\n ", "\n", ]); return ( (p = function () { return e; }), e ); } // ..snip.. var b = d.Z.div(m(), function (e) { return e.$isMessageRedesign ? "rounded-full h-7 w-7" : "rounded-sm h-[30px] w-[30px]"; }), y = d.Z.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ), ``` Explained by ChatGPT: > In the provided code, `d.Z` corresponds to the exported `TailwindInterface` from your earlier message. The code is creating styled components using this interface, with specific styles and conditional styling based on props. Let's break down each part: > > ### Functions `m` and `p` > > - Both `m` and `p` are memoization functions. They use `(0, r._)(...)` to compute a class string (presumably using a library like `clsx` for conditional and combined class names) and then redefine themselves to always return this computed class string in subsequent calls. This is a form of memoization to ensure the class string is only computed once. > > ### Creating Styled Components `b` and `y` > > - `b` and `y` are styled components created using `d.Z.div` and `d.Z.span` respectively. `d.Z` refers to `TailwindInterface`, and `div` and `span` are specifying the type of HTML element to style. > > #### Component `b` > > - `b` is a styled `div` element. > - It starts with a base style generated by the `m()` function. > - It also includes a function that adds conditional styling based on the `$isMessageRedesign` prop. If `$isMessageRedesign` is true, it adds `"rounded-full h-7 w-7"`; otherwise, it adds `"rounded-sm h-[30px] w-[30px]"`. > > #### Component `y` > > - `y` is a styled `span` element. > - It starts with a base style generated by the `p()` function. > - It has two additional functions for conditional styling based on the `$type` prop: > - If `$type` is `"warning"`, it adds `"bg-orange-500 text-white"`. > - If `$type` is `"danger"`, it adds `"bg-red-500 text-white"`. > > ### Summary > > - The code is utilizing the `TailwindInterface` to create two styled components, `b` (a `div`) and `y` (a `span`), with base styles and additional conditional styles based on props. > - The styling is dynamic, responding to props like `$isMessageRedesign` and `$type`, allowing these components to adapt their styles based on the context in which they are used. > - The memoization in `m` and `p` ensures that the base styles are only computed once, improving performance. ## Comment 5 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809704264)) Looking back at the main repo/usage docs for `Tailwind-Styled-Component`: - https://github.com/MathiasGilson/Tailwind-Styled-Component - https://github.com/MathiasGilson/Tailwind-Styled-Component#usage We can see that there are multiple ways of writing a styled component, including: ```js // Basic const Container = tw.div` flex items-center // ..snip.. ` // Conditional class names const Button = tw.button` flex ${(p) => (p.$primary ? "bg-indigo-600" : "bg-indigo-300")} ` // etc ``` Along with some other potentially relevant notes: > Tailwind Styled Components supports [Transient Props](https://styled-components.com/docs/api#transient-props) > > Prefix the props name with a dollar sign ($) to prevent forwarding them to the DOM element These usage examples are making use of JavaScript's Template Literals 'Tagged templates': - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates - > Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. - > The tag function can then perform whatever operations on these arguments you wish, and return the manipulated string. (Alternatively, it can return something completely different, as described in one of the following examples.) - > Tag functions don't even need to return a string! This will essentially end up routing through the `TailwindInterface` to the `templateFunctionFactory` ([Ref](https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/src/tailwind.tsx#L197C7-L267)) ```ts const templateFunctionFactory: TailwindInterface = (<C extends React.ElementType>(Element: C): any => { return (template: TemplateStringsArray, ...templateElements: ((props: any) => string | undefined | null)[]) => { // ..snip.. ``` We can see that this function is a template literal 'tagged template' function that receives the static strings in the `template` param, and then all of the dynamic strings in the `templateElements` param. I couldn't find much specifically about `TemplateStringsArray`, but here is 1 issue related to it, showing that it's a TypeScript thing: - https://github.com/microsoft/TypeScript/issues/33304 --- Using the above examples from the README in the Babel REPL gives transformed code like this: ```js var _templateObject, _templateObject2; function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze( Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } }) ); } // Basic var Container = tw.div( _templateObject || (_templateObject = _taggedTemplateLiteral([ "\n flex\n items-center\n // ..snip..\n", ])) ); // Conditional class names var Button = tw.button( _templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n flex\n ", "\n"])), function (p) { return p.$primary ? "bg-indigo-600" : "bg-indigo-300"; } ); // etc ``` We can see how this code looks a lot like the earlier code from our webpacked app, though the babel code implicitly concatenates the template literal strings as part of it's transform, whereas our webpacked code receives them as an array (as per the JS standard), and then passes them to a helper function that seems to concatenate them (potentially something like `classnames` / `clsx` / similar; see notes above+later on for more on this): ```js // ..snip.. function p() { var e = (0, r._)([ "\n absolute w-4 h-4 rounded-full text-[10px] text-white flex justify-center items-center right-0 top-[20px] -mr-2 border border-white\n ", "\n ", "\n", ]); return ( (p = function () { return e; }), e ); } // ..snip.. y = d.Z.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ), ``` If we were to manually re-write this back to how it would have looked in it's template literal form (ignoring the memoisation it does), it would have been something like this: ```js y = d.Z.span` absolute w-4 h-4 rounded-full text-[10px] text-white flex justify-center items-center right-0 top-[20px] -mr-2 border border-white ${(e) => (e.$type === "warning" && "bg-orange-500 text-white")} ${(e) => (e.$type === "danger" && "bg-red-500 text-white")} ` ``` --- Looking at where `template` and `templateElements` are processed within `templateFunctionFactory`; they're nested deeper within the `TwComponentConstructor` -> `TwComponent` -> in the JSX that returns `FinalElement`, specifically in the `className` prop: ```jsx // ..snip.. return ( <FinalElement // ..snip.. // set class names className={cleanTemplate( mergeArrays( template, templateElements.map((t) => t({ ...props, $as })) ), props.className )} // ..snip.. /> ) // ..snip.. ``` We can see that `mergeArrays` is called with `template` and `templateElements.map((t) => t({ ...props, $as }))`; which essentially merges the 2 arrays (while handling falsy values): ```js export const mergeArrays = (template: TemplateStringsArray, templateElements: (string | undefined | null)[]) => { return template.reduce( (acc, c, i) => acc.concat(c || [], templateElements[i] || []), // x || [] to remove false values e.g '', null, undefined. as Array.concat() ignores empty arrays i.e [] [] as string[] ) } ``` We can then see that the result of that is passed to `cleanTemplate`; which does some further cleanup of the result returned from `mergeArrays` (`template`) and `inheritedClasses`, then passes them to `twMerge` (from `tailwind-merge`): ```ts export const cleanTemplate = (template: Array<Interpolation<any>>, inheritedClasses: string = "") => { const newClasses: string[] = template .join(" ") .trim() .replace(/\n/g, " ") // replace newline with space .replace(/\s{2,}/g, " ") // replace line return by space .split(" ") .filter((c) => c !== ",") // remove comma introduced by template to string const inheritedClassesArray: string[] = inheritedClasses ? inheritedClasses.split(" ") : [] return twMerge( ...newClasses .concat(inheritedClassesArray) // add new classes to inherited classes .filter((c: string) => c !== " ") // remove empty classes ) } ``` Neither `mergeArrays` nor `cleanTemplate` appear to do any memoisation on the template string data, so presumably that pattern is happening somewhere later on still.. perhaps within `twMerge`? ## Comment 6 ([Ref](https://github.com/pionxzh/wakaru/issues/40#issuecomment-1809744611)) Looking at the `Tailwind-Styled-Component` `package.json`, we can see that `Tailwind-Styled-Component` relies on `tailwind-merge`: - https://github.com/MathiasGilson/Tailwind-Styled-Component/blob/master/package.json#L64-L66 - https://github.com/dcastil/tailwind-merge - > Utility function to efficiently merge [Tailwind CSS](https://tailwindcss.com/) classes in JS without style conflicts. Looking at the `tailwind-merge` API reference: - https://github.com/dcastil/tailwind-merge/blob/v2.0.0/docs/api-reference.md We can see that the 2 main functions appear to be: ```ts function twMerge( ...classLists: Array<string | undefined | null | false | 0 | typeof classLists> ): string ``` > Default function to use if you're using the default Tailwind config or are close enough to the default config. > > If twMerge doesn't work for you, you can create your own custom merge function with [extendTailwindMerge](https://github.com/dcastil/tailwind-merge/blob/v2.0.0/docs/api-reference.md#extendtailwindmerge). ```ts function twJoin( ...classLists: Array<string | undefined | null | false | 0 | typeof classLists> ): string ``` > Function to join className strings conditionally without resolving conflicts. > > It is used internally within twMerge and a direct subset of [clsx](https://www.npmjs.com/package/clsx). If you use clsx or [classnames](https://www.npmjs.com/package/classnames) to apply Tailwind classes conditionally and don't need support for object arguments, you can use twJoin instead, it is a little faster and will save you a few hundred bytes in bundle size. From these function signatures, and the description text of `twJoin`, we can see that this lib is quite similar (at least in API) to `classnames` / `clsx` / etc: - https://github.com/JedWatson/classnames - > A simple javascript utility for conditionally joining classNames together - https://github.com/lukeed/clsx - > A tiny (228B) utility for constructing `className` strings conditionally. We can find the definition of `twMerge` in the code here: - https://github.com/dcastil/tailwind-merge/blob/main/src/lib/tw-merge.ts#L3 - `export const twMerge = createTailwindMerge(getDefaultConfig)` - https://github.com/dcastil/tailwind-merge/blob/main/src/lib/create-tailwind-merge.ts - `createTailwindMerge` - https://github.com/dcastil/tailwind-merge/blob/main/src/lib/default-config.ts - `getDefaultConfig` Looking at `createTailwindMerge`, we can see that it returns a function, that wraps calling the `functionToCall` function. The first time that is accessed, it will map to `initTailwindMerge`, then the next time it's called it will map to `tailwindMerge`: ```ts export function createTailwindMerge( createConfigFirst: CreateConfigFirst, ...createConfigRest: CreateConfigSubsequent[] ): TailwindMerge { let configUtils: ConfigUtils let cacheGet: ConfigUtils['cache']['get'] let cacheSet: ConfigUtils['cache']['set'] let functionToCall = initTailwindMerge function initTailwindMerge(classList: string) { const config = createConfigRest.reduce( (previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst() as GenericConfig, ) configUtils = createConfigUtils(config) cacheGet = configUtils.cache.get cacheSet = configUtils.cache.set functionToCall = tailwindMerge return tailwindMerge(classList) } function tailwindMerge(classList: string) { const cachedResult = cacheGet(classList) if (cachedResult) { return cachedResult } const result = mergeClassList(classList, configUtils) cacheSet(classList, result) return result } return function callTailwindMerge() { return functionToCall(twJoin.apply(null, arguments as any)) } } ``` This looks quite similar to the memoisation pattern in sections of our webpacked code, for example: ```js function p() { var e = (0, r._)([ "\n absolute w-4 h-4 rounded-full text-[10px] text-white flex justify-center items-center right-0 top-[20px] -mr-2 border border-white\n ", "\n ", "\n", ]); return ( (p = function () { return e; }), e ); } ``` Though while it shares a similar sort of memoisation pattern; it doesn't seem to actually be the same code. Here are some references for `tailwind-merge`'s memoisation/caching: - https://github.com/dcastil/tailwind-merge/blob/main/docs/features.md#performance - > Results get cached by default, so you don't need to worry about wasteful re-renders. The library uses a computationally lightweight [LRU cache](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) which stores up to 500 different results by default. The cache is applied after all arguments are [joined](https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md#twjoin) together to a single string. This means that if you call twMerge repeatedly with different arguments that result in the same string when joined, the cache will be hit. --- Thinking more about the structure of the webpacked code from `Tailwind-Styled-Component`.. and how it calls the memoised code above.. ```js y = d.Z.span( p(), function (e) { return "warning" === e.$type && "bg-orange-500 text-white"; }, function (e) { return "danger" === e.$type && "bg-red-500 text-white"; } ), ``` ..it kind of feels like the memoisation could be happening at a higher layer than `tailwind-merge`, and possibly even higher than `Tailwind-Styled-Component`.. I wonder if something in the webpack minimisation process is applying a memo to the text passed to the template tags; or perhaps this might even be something that is being done manually in the webpacked app itself.