feat: move to unimport-icons

@lucide icons works very slow in barrel import, so i move to
unimport and use lucide icons
This commit is contained in:
2026-02-08 20:20:46 +05:00
parent 4a6e459407
commit 0f905bbc20
15 changed files with 279 additions and 64 deletions
+227 -22
View File
@@ -8,7 +8,6 @@
"name": "twitch-panels",
"version": "0.0.1",
"dependencies": {
"@lucide/svelte": "^0.563.1",
"@types/cropperjs": "^1.1.5",
"@types/uuid": "^10.0.0",
"cropperjs": "^2.1.0",
@@ -18,6 +17,7 @@
"uuid": "^13.0.0"
},
"devDependencies": {
"@iconify-json/lucide": "^1.2.89",
"@playwright/test": "^1.58.1",
"@sveltejs/adapter-auto": "^7.0.0",
"@sveltejs/adapter-static": "^3.0.10",
@@ -29,14 +29,15 @@
"@types/node": "^25.1.0",
"@vitest/coverage-istanbul": "^4.0.18",
"@vitest/ui": "^4.0.18",
"jest-canvas-mock": "^2.5.2",
"jsdom": "^28.0.0",
"konva": "^10.2.0",
"svelte": "^5.48.2",
"svelte-check": "^4.3.5",
"typescript": "^5.9.3",
"unplugin-icons": "^23.0.1",
"vite": "^7.3.1",
"vitest": "^4.0.18",
"vitest-canvas-mock": "^1.1.3",
"web-animations-js": "^2.3.2"
}
},
@@ -54,6 +55,20 @@
"dev": true,
"license": "MIT"
},
"node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"package-manager-detector": "^1.3.0",
"tinyexec": "^1.0.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@asamuzakjp/css-color": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz",
@@ -1081,6 +1096,35 @@
}
}
},
"node_modules/@iconify-json/lucide": {
"version": "1.2.89",
"resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.89.tgz",
"integrity": "sha512-9rZaJZn8VBls1KZnGaFTnqqZrUkd++XB3vy9WYIMgmHHgLxQMEZXg3V+oJSEeit0kCNr/OfDBmrDwuGl/LZulA==",
"dev": true,
"license": "ISC",
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
"dev": true,
"license": "MIT"
},
"node_modules/@iconify/utils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz",
"integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@antfu/install-pkg": "^1.1.0",
"@iconify/types": "^2.0.0",
"mlly": "^1.8.0"
}
},
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -1136,15 +1180,6 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@lucide/svelte": {
"version": "0.563.1",
"resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.563.1.tgz",
"integrity": "sha512-Kt+MbnE5D9RsuI/csmf7M+HWxALe57x3A0DhQ8pPnnUpneh7zuldrYjlT+veWtk+tVnp5doQtaAAxLujzIlhBw==",
"license": "ISC",
"peerDependencies": {
"svelte": "^5"
}
},
"node_modules/@playwright/test": {
"version": "1.58.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.1.tgz",
@@ -2148,6 +2183,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/confbox": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
"integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
"dev": true,
"license": "MIT"
},
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -2411,6 +2453,13 @@
"node": ">=12.0.0"
}
},
"node_modules/exsolve": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
"dev": true,
"license": "MIT"
},
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
@@ -2632,17 +2681,6 @@
"node": ">=8"
}
},
"node_modules/jest-canvas-mock": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz",
"integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==",
"dev": true,
"license": "MIT",
"dependencies": {
"cssfontparser": "^1.2.1",
"moo-color": "^1.0.2"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2767,6 +2805,24 @@
"immediate": "~3.0.5"
}
},
"node_modules/local-pkg": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
"integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"mlly": "^1.7.4",
"pkg-types": "^2.3.0",
"quansync": "^0.2.11"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
@@ -2847,6 +2903,38 @@
"node": ">=4"
}
},
"node_modules/mlly": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
"integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"acorn": "^8.15.0",
"pathe": "^2.0.3",
"pkg-types": "^1.3.1",
"ufo": "^1.6.1"
}
},
"node_modules/mlly/node_modules/confbox": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
"dev": true,
"license": "MIT"
},
"node_modules/mlly/node_modules/pkg-types": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"confbox": "^0.1.8",
"mlly": "^1.7.4",
"pathe": "^2.0.1"
}
},
"node_modules/moo-color": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz",
@@ -2921,6 +3009,13 @@
],
"license": "MIT"
},
"node_modules/package-manager-detector": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
"integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
"dev": true,
"license": "MIT"
},
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -2967,6 +3062,18 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pkg-types": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
"integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
"dev": true,
"license": "MIT",
"dependencies": {
"confbox": "^0.2.2",
"exsolve": "^1.0.7",
"pathe": "^2.0.3"
}
},
"node_modules/playwright": {
"version": "1.58.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.1.tgz",
@@ -3074,6 +3181,23 @@
"node": ">=6"
}
},
"node_modules/quansync": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
"integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/antfu"
},
{
"type": "individual",
"url": "https://github.com/sponsors/sxzz"
}
],
"license": "MIT"
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -3499,6 +3623,13 @@
"node": ">=14.17"
}
},
"node_modules/ufo": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
"integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==",
"dev": true,
"license": "MIT"
},
"node_modules/undici": {
"version": "7.20.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz",
@@ -3516,6 +3647,59 @@
"dev": true,
"license": "MIT"
},
"node_modules/unplugin": {
"version": "2.3.11",
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz",
"integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.5",
"acorn": "^8.15.0",
"picomatch": "^4.0.3",
"webpack-virtual-modules": "^0.6.2"
},
"engines": {
"node": ">=18.12.0"
}
},
"node_modules/unplugin-icons": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-23.0.1.tgz",
"integrity": "sha512-rv0XEJepajKzDLvRUWASM8K+8+/CCfZn2jtogXqg6RIp7kpatRc/aFrVJn8ANQA09e++lPEEv9yX8cC9enc+QQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@antfu/install-pkg": "^1.1.0",
"@iconify/utils": "^3.1.0",
"local-pkg": "^1.1.2",
"obug": "^2.1.1",
"unplugin": "^2.3.11"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@svgr/core": ">=7.0.0",
"@svgx/core": "^1.0.1",
"@vue/compiler-sfc": "^3.0.2",
"svelte": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"peerDependenciesMeta": {
"@svgr/core": {
"optional": true
},
"@svgx/core": {
"optional": true
},
"@vue/compiler-sfc": {
"optional": true
},
"svelte": {
"optional": true
}
}
},
"node_modules/update-browserslist-db": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
@@ -3739,6 +3923,20 @@
}
}
},
"node_modules/vitest-canvas-mock": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/vitest-canvas-mock/-/vitest-canvas-mock-1.1.3.tgz",
"integrity": "sha512-zlKJR776Qgd+bcACPh0Pq5MG3xWq+CdkACKY/wX4Jyija0BSz8LH3aCCgwFKYFwtm565+050YFEGG9Ki0gE/Hw==",
"dev": true,
"license": "MIT",
"dependencies": {
"cssfontparser": "^1.2.1",
"moo-color": "^1.0.3"
},
"peerDependencies": {
"vitest": "^3.0.0 || ^4.0.0"
}
},
"node_modules/w3c-xmlserializer": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
@@ -3769,6 +3967,13 @@
"node": ">=20"
}
},
"node_modules/webpack-virtual-modules": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"dev": true,
"license": "MIT"
},
"node_modules/whatwg-mimetype": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
+3 -2
View File
@@ -19,6 +19,7 @@
"test:e2e": "playwright test"
},
"devDependencies": {
"@iconify-json/lucide": "^1.2.89",
"@playwright/test": "^1.58.1",
"@sveltejs/adapter-auto": "^7.0.0",
"@sveltejs/adapter-static": "^3.0.10",
@@ -30,18 +31,18 @@
"@types/node": "^25.1.0",
"@vitest/coverage-istanbul": "^4.0.18",
"@vitest/ui": "^4.0.18",
"jest-canvas-mock": "^2.5.2",
"jsdom": "^28.0.0",
"konva": "^10.2.0",
"svelte": "^5.48.2",
"svelte-check": "^4.3.5",
"typescript": "^5.9.3",
"unplugin-icons": "^23.0.1",
"vite": "^7.3.1",
"vitest": "^4.0.18",
"vitest-canvas-mock": "^1.1.3",
"web-animations-js": "^2.3.2"
},
"dependencies": {
"@lucide/svelte": "^0.563.1",
"@types/cropperjs": "^1.1.5",
"@types/uuid": "^10.0.0",
"cropperjs": "^2.1.0",
+7 -1
View File
@@ -4,7 +4,13 @@
import SettingsRow from "$components/layout/SettingsRow.svelte";
import Button from "$components/ui/Button.svelte";
import RangeSlider from "$components/ui/RangeSlider.svelte";
import { Pencil, RotateCcw as Reset, Upload } from "@lucide/svelte";
// import { Pencil, RotateCcw as Reset, Upload } from "@lucide/svelte";
// import Pencil from "@lucide/svelte/icons/pencil";
// import Reset from "@lucide/svelte/icons/rotate-ccw";
// import Upload from "@lucide/svelte/icons/upload";
import Pencil from "~icons/lucide/pencil";
import Reset from "~icons/lucide/rotate-ccw";
import Upload from "~icons/lucide/upload";
import CropInline from "./CropInline.svelte";
let brightness = $state(100);
+2 -1
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { themeState } from "$states/theme.svelte";
import { Moon, Sun } from "@lucide/svelte";
import Moon from "~icons/lucide/moon";
import Sun from "~icons/lucide/sun";
function toggleTheme() {
themeState.toggle();
+2 -1
View File
@@ -2,7 +2,8 @@
import Button from "$components/ui/Button.svelte";
import type { SlideDirectionType } from "$lib/constants";
import { PANEL_SETTINGS } from "$lib/constants";
import { ChevronLeft, ChevronRight } from "@lucide/svelte";
import ChevronLeft from "~icons/lucide/chevron-left";
import ChevronRight from "~icons/lucide/chevron-right";
interface Props {
current: number;
+2 -1
View File
@@ -7,8 +7,9 @@
import { konvaAllStagesState } from "$states/konvaAllStages.svelte";
import { konvaStageState } from "$states/konvaStage.svelte";
import { textsState } from "$states/texts.svelte";
import { Download, StickyNote } from "@lucide/svelte";
import { fly } from "svelte/transition";
import Download from "~icons/lucide/download";
import StickyNote from "~icons/lucide/sticky-note";
import Preview from "./Preview.svelte";
import PreviewAll from "./PreviewAll.svelte";
import PreviewControls from "./PreviewControls.svelte";
+1 -1
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import Button from "$components/ui/Button.svelte";
import { X as Cross } from "@lucide/svelte";
import { fly } from "svelte/transition";
import Cross from "~icons/lucide/x";
interface Props {
text: string;
+1 -1
View File
@@ -3,7 +3,7 @@
import InputGroup from "$components/layout/InputGroup.svelte";
import Button from "$components/ui/Button.svelte";
import { textsState } from "$states/texts.svelte";
import { Plus } from "@lucide/svelte";
import Plus from "~icons/lucide/plus";
import TextInlineEdit from "./TextInlineEdit.svelte";
import TextInput from "./TextInput.svelte";
+7 -10
View File
@@ -1,6 +1,9 @@
<script lang="ts">
import type { TextAlignType } from "$lib/constants";
import { TextAlignCenter, TextAlignEnd, TextAlignStart } from "@lucide/svelte";
import TextAlignCenter from "~icons/lucide/text-align-center";
import TextAlignEnd from "~icons/lucide/text-align-end";
import TextAlignStart from "~icons/lucide/text-align-start";
// import { TextAlignCenter, TextAlignEnd, TextAlignStart } from "@lucide/svelte";
interface Props {
align: TextAlignType;
@@ -31,30 +34,24 @@
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
}
.align-btn :global(svg) {
width: 16px;
height: 16px;
stroke: var(--text-secondary);
transition: var(--transition);
}
.align-btn:hover {
background: var(--bg-hover);
border-color: var(--accent-primary);
}
.align-btn:hover :global(svg) {
stroke: var(--accent-primary);
color: var(--accent-primary);
}
.align-btn.active {
background: var(--accent-primary);
border-color: var(--accent-primary);
}
.align-btn.active :global(svg) {
stroke: white;
color: white;
}
</style>
+1 -9
View File
@@ -1,11 +1,3 @@
import "@testing-library/jest-dom/vitest";
import { vi } from "vitest";
import "vitest-canvas-mock";
import "web-animations-js";
declare global {
var jest: typeof vi;
}
globalThis.jest = vi;
await import("jest-canvas-mock");
@@ -1,13 +1,9 @@
import ImageManager from "$components/image/ImageManager.svelte";
import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest";
import { render } from "@testing-library/svelte";
import { describe, it } from "vitest";
describe("ImageManager.svelte", () => {
it("should render without crashing", () => {
render(ImageManager);
});
});
+2 -6
View File
@@ -1,10 +1,8 @@
import { render, screen, fireEvent } from "@testing-library/svelte";
import { describe, expect, it } from "vitest";
import Alignment from "$components/ui/Alignment.svelte";
import { render } from "@testing-library/svelte";
import { describe, it } from "vitest";
describe("Alignment.svelte", () => {
it("should render without crashing", () => {
render(Alignment, {
props: {
@@ -12,6 +10,4 @@ describe("Alignment.svelte", () => {
},
});
});
});
+2 -1
View File
@@ -13,6 +13,7 @@
"strictNullChecks": true,
"exactOptionalPropertyTypes": true,
"moduleResolution": "bundler",
"allowArbitraryExtensions": true
"allowArbitraryExtensions": true,
"types": ["unplugin-icons/types/svelte"]
}
}
+7 -1
View File
@@ -1,9 +1,15 @@
import { sveltekit } from "@sveltejs/kit/vite";
import Icons from "unplugin-icons/vite";
import { defineConfig } from "vite";
export default defineConfig({
build: {
assetsInlineLimit: Infinity,
},
plugins: [sveltekit()],
plugins: [
sveltekit(),
Icons({
compiler: "svelte",
}),
],
});
+13 -1
View File
@@ -1,14 +1,21 @@
import { sveltekit } from "@sveltejs/kit/vite";
import Icons from "unplugin-icons/vite";
import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [sveltekit()],
plugins: [
sveltekit(),
Icons({
compiler: "svelte",
}),
],
test: {
environment: "jsdom",
globals: true,
isolate: true,
setupFiles: ["./tests/setup.ts"],
include: ["tests/**/*.{test,spec}.{js,ts}"],
exclude: ["**/node_modules/**", "**/dist/**", "**/.svelte-kit/**", "**/build/**"],
env: {
DEBUG_PRINT_LIMIT: "0",
},
@@ -26,6 +33,11 @@ export default defineConfig({
"**/coverage/**",
],
},
server: {
deps: {
inline: [/unplugin-icons/],
},
},
},
resolve: process.env.VITEST
? {