This commit is contained in:
Stephen Zhou 2026-04-02 09:23:40 +08:00
parent eae0718c19
commit 3c33301a08
No known key found for this signature in database
5 changed files with 140 additions and 25 deletions

12
pnpm-lock.yaml generated
View File

@ -57,6 +57,12 @@ catalogs:
'@iconify-json/ri':
specifier: 1.2.10
version: 1.2.10
'@iconify/tools':
specifier: 4.2.0
version: 4.2.0
'@iconify/utils':
specifier: 3.1.0
version: 3.1.0
'@lexical/link':
specifier: 0.42.0
version: 0.42.0
@ -1006,6 +1012,12 @@ importers:
'@iconify-json/ri':
specifier: 'catalog:'
version: 1.2.10
'@iconify/tools':
specifier: 'catalog:'
version: 4.2.0
'@iconify/utils':
specifier: 'catalog:'
version: 3.1.0
'@mdx-js/loader':
specifier: 'catalog:'
version: 3.1.1(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))

View File

@ -86,6 +86,8 @@ catalog:
"@hono/node-server": 1.19.11
"@iconify-json/heroicons": 1.2.3
"@iconify-json/ri": 1.2.10
"@iconify/tools": 4.2.0
"@iconify/utils": 3.1.0
"@lexical/code": 0.42.0
"@lexical/link": 0.42.0
"@lexical/list": 0.42.0

View File

@ -163,6 +163,8 @@
"@hono/node-server": "catalog:",
"@iconify-json/heroicons": "catalog:",
"@iconify-json/ri": "catalog:",
"@iconify/tools": "catalog:",
"@iconify/utils": "catalog:",
"@mdx-js/loader": "catalog:",
"@mdx-js/react": "catalog:",
"@mdx-js/rollup": "catalog:",

View File

@ -1,11 +1,12 @@
/* eslint-disable ts/ban-ts-comment */
// @ts-nocheck
import { readdirSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { icons as heroicons } from '@iconify-json/heroicons'
import { icons as ri } from '@iconify-json/ri'
import { importSvgCollections } from 'iconify-import-svg'
import { cleanupSVG, deOptimisePaths, isEmptyColor, parseColors, runSVGO, SVG } from '@iconify/tools'
import { compareColors, stringToColor } from '@iconify/utils/lib/colors'
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
import { defineConfig, presetIcons, presetTypography, presetWind3, transformerDirectives } from 'unocss'
import tailwindThemeVarDefine from './themes/tailwind-theme-var-define.ts'
@ -13,10 +14,83 @@ const dirname = typeof __dirname !== 'undefined'
? __dirname
: path.dirname(fileURLToPath(import.meta.url))
const parseColorOptions = {
fallback: () => 'currentColor',
const blackColor = stringToColor('black')
const whiteColor = stringToColor('white')
const transformSvgToCurrentColor = (source: string) => {
const svg = new SVG(source)
cleanupSVG(svg)
parseColors(svg, {
defaultColor: 'currentColor',
callback: (attr, colorString, color) => {
if (!color)
throw new Error(`Invalid color: "${colorString}" in attribute ${attr}`)
if (isEmptyColor(color))
return color
if (compareColors(color, blackColor))
return 'currentColor'
if (compareColors(color, whiteColor))
return 'remove'
return 'currentColor'
},
})
runSVGO(svg)
deOptimisePaths(svg)
return svg.toString()
}
const findSvgDirectories = (rootDir: string) => {
const result: string[] = []
const walk = (dir: string) => {
const entries = readdirSync(dir, { withFileTypes: true })
const subdirs: string[] = []
let hasSvgFiles = false
for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.svg'))
hasSvgFiles = true
else if (entry.isDirectory())
subdirs.push(path.join(dir, entry.name))
}
if (hasSvgFiles)
result.push(dir)
for (const subdir of subdirs)
walk(subdir)
}
walk(rootDir)
return result
}
const createCollectionLoaders = (source: string, prefix: string) => {
const directories = findSvgDirectories(source)
return Object.fromEntries(
directories.map((dir) => {
const pathPrefix = path.relative(source, dir).split(path.sep).join('-')
return [
`${prefix}-${pathPrefix}`,
FileSystemIconLoader(dir, transformSvgToCurrentColor),
]
}),
)
}
const publicCollections = createCollectionLoaders(
path.resolve(dirname, 'app/components/base/icons/assets/public'),
'custom-public',
)
const venderCollections = createCollectionLoaders(
path.resolve(dirname, 'app/components/base/icons/assets/vender'),
'custom-vender',
)
export default defineConfig({
blocklist: [
/\$\{/,
@ -46,26 +120,8 @@ export default defineConfig({
presetTypography(),
presetIcons({
collections: {
heroicons,
ri,
...importSvgCollections({
source: path.resolve(dirname, 'app/components/base/icons/assets/public'),
prefix: 'custom-public',
ignoreImportErrors: true,
cleanupSVG: true,
deOptimisePaths: true,
runSVGO: true,
parseColors: parseColorOptions,
}),
...importSvgCollections({
source: path.resolve(dirname, 'app/components/base/icons/assets/vender'),
prefix: 'custom-vender',
ignoreImportErrors: true,
cleanupSVG: true,
deOptimisePaths: true,
runSVGO: true,
parseColors: parseColorOptions,
}),
...publicCollections,
...venderCollections,
},
extraProperties: {
width: '1rem',

View File

@ -1,5 +1,7 @@
import { fileURLToPath } from 'node:url'
import react from '@vitejs/plugin-react'
import autoprefixer from 'autoprefixer'
import UnoCSS from 'unocss/vite'
import vinext from 'vinext'
import Inspect from 'vite-plugin-inspect'
import { defineConfig } from 'vite-plus'
@ -11,6 +13,36 @@ import { nextStaticImageTestPlugin } from './plugins/vite/next-static-image-test
const projectRoot = fileURLToPath(new URL('.', import.meta.url))
const isCI = !!process.env.CI
const rootClientInjectTarget = getRootClientInjectTarget(projectRoot)
const unoCssEntryTarget = `${projectRoot}app/layout.tsx`
const unoGlobalsCssTarget = `${projectRoot}app/styles/globals.css`
const injectUnoCssPlugin = {
name: 'inject-uno-css-entry',
enforce: 'pre' as const,
transform(code: string, id: string) {
if (id !== unoCssEntryTarget || code.includes('virtual:uno.css'))
return
return {
code: `import 'virtual:uno.css'\n${code}`,
map: null,
}
},
}
const stripUnoPreflightDirectivePlugin = {
name: 'strip-uno-preflight-directive',
enforce: 'pre' as const,
transform(code: string, id: string) {
if (id !== unoGlobalsCssTarget || !code.includes('@unocss !preflights;'))
return
return {
code: code.replace('@unocss !preflights;', ''),
map: null,
}
},
}
export default defineConfig(({ mode }) => {
const isTest = mode === 'test'
@ -37,6 +69,7 @@ export default defineConfig(({ mode }) => {
]
: isStorybook
? [
UnoCSS(),
react(),
]
: [
@ -48,6 +81,9 @@ export default defineConfig(({ mode }) => {
injectTarget: rootClientInjectTarget,
projectRoot,
}),
injectUnoCssPlugin,
stripUnoPreflightDirectivePlugin,
UnoCSS(),
react(),
vinext({ react: false }),
customI18nHmrPlugin({ injectTarget: rootClientInjectTarget }),
@ -59,6 +95,13 @@ export default defineConfig(({ mode }) => {
resolve: {
tsconfigPaths: true,
},
css: {
postcss: {
plugins: [
autoprefixer(),
],
},
},
// vinext related config
...(!isTest && !isStorybook