mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 11:05:05 +03:00
Backend moved to a separate repository
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import type { Plugin, UserConfig } from 'vite';
|
||||
|
||||
const DEFAULT_DICTIONARY = '_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
|
||||
function counter(dictionary: string = DEFAULT_DICTIONARY) {
|
||||
const sequence: string[] = [dictionary[0]];
|
||||
return () => {
|
||||
const str = sequence.join('');
|
||||
let carry = 0;
|
||||
for (let i = 0; i < sequence.length; i++) {
|
||||
const index = dictionary.indexOf(sequence[i]) + carry + 1;
|
||||
if (index < dictionary.length) {
|
||||
sequence[i] = dictionary[index];
|
||||
/**
|
||||
* Make sure the following rules are not violated:
|
||||
* 1. The first character cannot be a number
|
||||
* 2. The second character cannot be a number if the first is a dash
|
||||
* 3. The dash cannot be the only character
|
||||
*
|
||||
* https://www.w3.org/TR/CSS21/syndata.html#characters
|
||||
*/
|
||||
const [c1, c2] = sequence;
|
||||
if (
|
||||
(c1 >= '0' && c1 <= '9') ||
|
||||
(c1 === '-' && (c2 >= '0' && c2 <= '9')) ||
|
||||
(c1 === '-' && sequence.length === 1)
|
||||
) {
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
carry = 0;
|
||||
break;
|
||||
} else {
|
||||
sequence[i] = dictionary[0];
|
||||
carry = 1;
|
||||
}
|
||||
}
|
||||
if (carry) {
|
||||
sequence.push(dictionary[0]);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
};
|
||||
|
||||
export interface OptimizeCssModuleOptions {
|
||||
dictionary?: string;
|
||||
}
|
||||
|
||||
export function optimizeCssModules(options?: OptimizeCssModuleOptions): Plugin {
|
||||
const next = counter(options?.dictionary);
|
||||
const map: Map<string, string> = new Map();
|
||||
|
||||
return {
|
||||
name: 'optimize-css-modules',
|
||||
apply: 'build',
|
||||
config: () => ({
|
||||
css: {
|
||||
modules: {
|
||||
generateScopedName: (name: string, fileName: string) => {
|
||||
const key = fileName + name;
|
||||
let hash = map.get(key);
|
||||
if (!hash) {
|
||||
map.set(key, (hash = next()));
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { Plugin } from 'vite';
|
||||
import { optimize } from 'svgo';
|
||||
|
||||
export interface OptimizeSvgOptions {
|
||||
/**
|
||||
* Whether to enable SVG optimization
|
||||
* @default true
|
||||
*/
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
const svgoConfig: Parameters<typeof optimize>[1] = {
|
||||
multipass: true,
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
// Keep IDs if they might be referenced (minify instead of remove)
|
||||
cleanupIds: {
|
||||
remove: false,
|
||||
minify: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Optimizes SVG files during build by:
|
||||
* - Minifying SVG code
|
||||
* - Removing metadata and comments
|
||||
* - Removing unnecessary attributes
|
||||
* - Optimizing paths and shapes
|
||||
*/
|
||||
export function optimizeSvg(options?: OptimizeSvgOptions): Plugin {
|
||||
const enabled = options?.enabled !== false;
|
||||
|
||||
return {
|
||||
name: 'optimize-svg',
|
||||
apply: 'build',
|
||||
enforce: 'post',
|
||||
async generateBundle(options, bundle) {
|
||||
if (!enabled) return;
|
||||
|
||||
// Optimize SVGs in the bundle
|
||||
for (const [fileName, chunk] of Object.entries(bundle)) {
|
||||
if (fileName.endsWith('.svg') && chunk.type === 'asset') {
|
||||
try {
|
||||
const svgContent = typeof chunk.source === 'string'
|
||||
? chunk.source
|
||||
: Buffer.from(chunk.source).toString('utf-8');
|
||||
|
||||
const result = optimize(svgContent, svgoConfig);
|
||||
|
||||
if (result.data && result.data !== svgContent) {
|
||||
chunk.source = result.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Failed to optimize SVG ${fileName}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user