From 19d573f6638e06c798e8dd14575ad1268bbc7bf9 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 18:39:18 -0700 Subject: [PATCH 01/12] Switch to lodash-es. --- package-lock.json | 8 ++++---- package.json | 2 +- src/ColorDropDownField.jsx | 2 +- src/PracticePage.jsx | 2 +- src/ga.js | 2 +- src/lines.js | 2 +- src/store.js | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 371b641..6221909 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "downloadjs": "^1.4.7", "i18next": "^25.3.2", "i18next-browser-languagedetector": "8.2.0", - "lodash": "^4.17.5", + "lodash-es": "^4.17.21", "mobx": "^6.13.0", "mobx-react-observer": "^1.1.0", "react": "^19.1.0", @@ -3500,10 +3500,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { + "node_modules/lodash-es": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "license": "MIT" }, "node_modules/lodash.merge": { diff --git a/package.json b/package.json index 18c04eb..d801956 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "downloadjs": "^1.4.7", "i18next": "^25.3.2", "i18next-browser-languagedetector": "8.2.0", - "lodash": "^4.17.5", + "lodash-es": "^4.17.21", "mobx": "^6.13.0", "mobx-react-observer": "^1.1.0", "react": "^19.1.0", diff --git a/src/ColorDropDownField.jsx b/src/ColorDropDownField.jsx index b05ab57..9fe90c0 100644 --- a/src/ColorDropDownField.jsx +++ b/src/ColorDropDownField.jsx @@ -1,4 +1,4 @@ -import { range } from "lodash"; +import { range } from "lodash-es"; import Color from "color"; import DropDownField from "./DropDownField"; diff --git a/src/PracticePage.jsx b/src/PracticePage.jsx index 61fb2f7..594493e 100644 --- a/src/PracticePage.jsx +++ b/src/PracticePage.jsx @@ -1,4 +1,4 @@ -import { times } from "lodash"; +import { times } from "lodash-es"; import LineSet from "./LineSet"; import WatermarkSVG from "./WatermarkSVG"; diff --git a/src/ga.js b/src/ga.js index 453559a..3deb1f7 100644 --- a/src/ga.js +++ b/src/ga.js @@ -1,4 +1,4 @@ -import { debounce, partial } from "lodash"; +import { debounce, partial } from "lodash-es"; import { reaction } from "mobx"; export const gtagEvent = (action, params) => { diff --git a/src/lines.js b/src/lines.js index d8cab94..a2c5de2 100644 --- a/src/lines.js +++ b/src/lines.js @@ -1,4 +1,4 @@ -import { merge } from "lodash"; +import { merge } from "lodash-es"; export const basicLine = (width, offset) => { return { diff --git a/src/store.js b/src/store.js index c658967..229a063 100644 --- a/src/store.js +++ b/src/store.js @@ -1,4 +1,4 @@ -import { reduce, range } from "lodash"; +import { reduce, range } from "lodash-es"; import { action, computed, observable, makeObservable } from "mobx"; import { composeLine, defaultLineSpec } from "./lines"; From be66246c3d0beea5952cd077f84ae9e80554bd0c Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 18:39:52 -0700 Subject: [PATCH 02/12] Make sure editors know too. --- .editorconfig | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..36d5a7a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*] +max_line_length = 100 From 71451f97fad06939e0c2cb8d80e6e5a3fe32e391 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 18:42:20 -0700 Subject: [PATCH 03/12] Ditch the devcontainer since I love WSL. --- .devcontainer/devcontainer.json | 22 ---------------------- vite.config.js | 3 --- 2 files changed, 25 deletions(-) delete mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 2418c26..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,22 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node -{ - "name": "Node.js & TypeScript", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm", - - // Features to add to the dev container. More info: https://containers.dev/features. - "features": { "ghcr.io/devcontainers-extra/features/ripgrep:1": {} }, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [5173], - - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "npm install" - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} diff --git a/vite.config.js b/vite.config.js index c7979d7..257a96f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -28,9 +28,6 @@ export default defineConfig({ }, }), ], - server: { - host: true, - }, test: { environment: "jsdom", }, From c12bd72a8de79f5118db12554f834f2ca8a4ec71 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 18:42:50 -0700 Subject: [PATCH 04/12] Reshuffle to let lodash-es shake out. --- vite.config.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/vite.config.js b/vite.config.js index 257a96f..f7aedde 100644 --- a/vite.config.js +++ b/vite.config.js @@ -8,15 +8,7 @@ export default defineConfig({ rollupOptions: { output: { manualChunks: { - uicore: [ - "react", - "react-dom", - "mobx", - "mobx-react-observer", - "i18next", - "react-i18next", - "lodash", - ], + react: ["react", "react-dom", "react-i18next", "mobx", "mobx-react-observer"], }, }, }, From 2807cea1cfac0a24d99ebeb725c61d4556abd78c Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 19:28:51 -0700 Subject: [PATCH 05/12] Bundle analysis. --- package-lock.json | 11 +++++++++++ package.json | 1 + 2 files changed, 12 insertions(+) diff --git a/package-lock.json b/package-lock.json index 6221909..e783d39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "jsdom": "^26.1.0", "prettier": "^3.6.2", "vite": "^7.0.6", + "vite-bundle-analyzer": "^1.1.0", "vitest": "^3.2.4" } }, @@ -4496,6 +4497,16 @@ } } }, + "node_modules/vite-bundle-analyzer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-1.1.0.tgz", + "integrity": "sha512-f/9m+6S5yPOHf/QS00rLOkyQ0icZeF67roM3O5LZZMPTOZFU1bHJTptNHCKMJc2yxXzj0Hunwcetrc+vM2LEQQ==", + "dev": true, + "license": "MIT", + "bin": { + "analyze": "dist/bin.js" + } + }, "node_modules/vite-node": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", diff --git a/package.json b/package.json index d801956..8091abb 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "jsdom": "^26.1.0", "prettier": "^3.6.2", "vite": "^7.0.6", + "vite-bundle-analyzer": "^1.1.0", "vitest": "^3.2.4" }, "setupTestFrameworkScriptFile": "src/setupTests.js", From 90ce4caa3590ea31dc372212f3f8384857c5c98c Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 19:29:05 -0700 Subject: [PATCH 06/12] Keep it pretty --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ad92582 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} From a989a30fcd672f16411814d5814c725c3b9a385b Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sat, 2 Aug 2025 19:34:45 -0700 Subject: [PATCH 07/12] Turn on analysis during build (for now). --- vite.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vite.config.js b/vite.config.js index f7aedde..e604ea8 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,6 +1,8 @@ import { defineConfig } from "vite"; + import react from "@vitejs/plugin-react"; import observerPlugin from "mobx-react-observer/babel-plugin"; +import { analyzer } from "vite-bundle-analyzer"; export default defineConfig({ base: "/pen/", @@ -8,7 +10,7 @@ export default defineConfig({ rollupOptions: { output: { manualChunks: { - react: ["react", "react-dom", "react-i18next", "mobx", "mobx-react-observer"], + react: ["react", "react-dom", "react-i18next", "i18next", "mobx", "mobx-react-observer"], }, }, }, @@ -19,6 +21,7 @@ export default defineConfig({ plugins: [observerPlugin()], }, }), + analyzer(), ], test: { environment: "jsdom", From 0250b0a50ae2a731b960b9b10b09f4f10017ba13 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sun, 3 Aug 2025 09:49:56 -0700 Subject: [PATCH 08/12] Stop using lodash.partial, worth a few kb. --- src/ga.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ga.js b/src/ga.js index 3deb1f7..322253d 100644 --- a/src/ga.js +++ b/src/ga.js @@ -1,4 +1,4 @@ -import { debounce, partial } from "lodash-es"; +import debounce from "lodash-es/debounce"; import { reaction } from "mobx"; export const gtagEvent = (action, params) => { @@ -16,13 +16,13 @@ export const trackEvent = (action, label) => { gtagEvent(action, { eventLabel: label }); }; -export const presetChange = partial(trackEvent, "select_preset"); +export const presetChange = (label) => trackEvent("select_preset", label); -export const ratiosChange = partial(trackEvent, "change_ratios"); +export const ratiosChange = (label) => trackEvent("change_ratios", label); -export const xHeightChange = partial(trackEvent, "change_x_height"); +export const xHeightChange = (label) => trackEvent("change_x_height", label); -export const outputAttempt = partial(trackEvent, "output_attempt"); +export const outputAttempt = (label) => trackEvent("output_attempt", label); export const gaLangChange = (lng) => { gtagEvent("language_change", { language: lng }); From c91cf65f0edbb6b45874da323bcc5b3611c141f2 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sun, 3 Aug 2025 10:03:46 -0700 Subject: [PATCH 09/12] Remove lodash.range and lodash.reduce for a few kb. Array native functions! --- src/ColorDropDownField.jsx | 3 +-- src/store.js | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ColorDropDownField.jsx b/src/ColorDropDownField.jsx index 9fe90c0..4e22dcb 100644 --- a/src/ColorDropDownField.jsx +++ b/src/ColorDropDownField.jsx @@ -1,4 +1,3 @@ -import { range } from "lodash-es"; import Color from "color"; import DropDownField from "./DropDownField"; @@ -7,7 +6,7 @@ const colors = [ { key: "transparent" }, { key: "black" }, { key: "gray" }, - ...range(1, 10).map((v) => ({ + ...Array.from({ length: 9 }, (_, i) => i + 1).map((v) => ({ key: Color.rgb(255, 255, 255) .darken(v / 10.0) .string(), diff --git a/src/store.js b/src/store.js index 229a063..fef86a9 100644 --- a/src/store.js +++ b/src/store.js @@ -1,5 +1,5 @@ -import { reduce, range } from "lodash-es"; -import { action, computed, observable, makeObservable } from "mobx"; +import range from "lodash-es/range"; +import { action, computed, makeObservable, observable } from "mobx"; import { composeLine, defaultLineSpec } from "./lines"; @@ -195,7 +195,7 @@ class PenStore { } get lineSetHeight() { - return reduce(this.heights, (sum, h) => sum + h, 0); + return this.heights.reduce((sum, h) => sum + h, 0); } get guideLineSet() { From 968c7017966276e21266b5c057f8a55f56db36c6 Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sun, 3 Aug 2025 10:33:36 -0700 Subject: [PATCH 10/12] Replace lodash.merge with some spread. --- src/lines.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/lines.js b/src/lines.js index a2c5de2..eb4325c 100644 --- a/src/lines.js +++ b/src/lines.js @@ -1,5 +1,3 @@ -import { merge } from "lodash-es"; - export const basicLine = (width, offset) => { return { x1: 0, @@ -25,12 +23,12 @@ export const lineDash = (name) => { }; export const composeLine = (spec) => { - return merge( - basicLine(spec.width, spec.offset), - color(spec.color), - thickness(spec.thickness), - lineDash(spec.dash), - ); + return { + ...basicLine(spec.width, spec.offset), + ...color(spec.color), + ...thickness(spec.thickness), + ...lineDash(spec.dash), + }; }; export const defaultLineSpec = (overrides = {}) => { From 32fd365cb034a44a376b09b8b72d2a856da060cc Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sun, 3 Aug 2025 10:50:50 -0700 Subject: [PATCH 11/12] `npx vite-bundle-analyzer` instead. --- package-lock.json | 11 ----------- package.json | 1 - vite.config.js | 2 -- 3 files changed, 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index e783d39..6221909 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "jsdom": "^26.1.0", "prettier": "^3.6.2", "vite": "^7.0.6", - "vite-bundle-analyzer": "^1.1.0", "vitest": "^3.2.4" } }, @@ -4497,16 +4496,6 @@ } } }, - "node_modules/vite-bundle-analyzer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-1.1.0.tgz", - "integrity": "sha512-f/9m+6S5yPOHf/QS00rLOkyQ0icZeF67roM3O5LZZMPTOZFU1bHJTptNHCKMJc2yxXzj0Hunwcetrc+vM2LEQQ==", - "dev": true, - "license": "MIT", - "bin": { - "analyze": "dist/bin.js" - } - }, "node_modules/vite-node": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", diff --git a/package.json b/package.json index 8091abb..d801956 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "jsdom": "^26.1.0", "prettier": "^3.6.2", "vite": "^7.0.6", - "vite-bundle-analyzer": "^1.1.0", "vitest": "^3.2.4" }, "setupTestFrameworkScriptFile": "src/setupTests.js", diff --git a/vite.config.js b/vite.config.js index e604ea8..a3a624a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,7 +2,6 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import observerPlugin from "mobx-react-observer/babel-plugin"; -import { analyzer } from "vite-bundle-analyzer"; export default defineConfig({ base: "/pen/", @@ -21,7 +20,6 @@ export default defineConfig({ plugins: [observerPlugin()], }, }), - analyzer(), ], test: { environment: "jsdom", From 1dd1b5e5d6f256d5e0411b5c04a88c2dd566691d Mon Sep 17 00:00:00 2001 From: Kyle VanderBeek Date: Sun, 3 Aug 2025 10:51:34 -0700 Subject: [PATCH 12/12] Less lodash.times. --- src/PracticePage.jsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/PracticePage.jsx b/src/PracticePage.jsx index 594493e..6260d7d 100644 --- a/src/PracticePage.jsx +++ b/src/PracticePage.jsx @@ -1,5 +1,3 @@ -import { times } from "lodash-es"; - import LineSet from "./LineSet"; import WatermarkSVG from "./WatermarkSVG"; @@ -36,7 +34,7 @@ const PracticePage = ({ store }) => { style={{ backgroundColor: "white" }} > - {times(count, (i) => ( + {[...Array(count)].map((_, i) => ( { ))} - {times(count, (i) => ( + {[...Array(count)].map((_, i) => (