feat: css js minify

This commit is contained in:
Corentin Bringer 2025-07-20 20:19:10 +02:00
commit af689db270
31 changed files with 379 additions and 6 deletions

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "CSS/JS minimieren",
"description": "Komprimieren Sie Ihren CSS- oder JavaScript-Code, indem Sie überflüssige Leerzeichen, Zeilenumbrüche und Kommentare entfernen.",
"shortDescription": "CSS- und JavaScript-Code minimieren",
"longDescription": "",
"toolInfo": {
"title": "CSS/JS minimieren",
"description": "Dieses Tool minimiert Ihren CSS- oder JavaScript-Code, indem es unnötige Zeichen wie Leerzeichen, Zeilenumbrüche und Kommentare entfernt ohne die Funktionalität zu beeinträchtigen. Ideal zur Optimierung der Webleistung und zur Reduzierung der Dateigröße vor dem Deployment."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Tools zum Arbeiten mit XML-Datenstrukturen Viewer, Beautifier, Validator und vieles mehr",
"title": "XML-Tools"
},
"dev": {
"description": "Unverzichtbare Tools für Entwickler: Code-Formatter, Encoder/Decoder, Vergleichswerkzeuge, UUID-Generatoren und vieles mehr",
"title": "Entwickler-Tools"
}
},
"csv": {

View file

@ -0,0 +1,13 @@
{
"cssJsMinify": {
"title": "Minify CSS/JS",
"description": "Compress your CSS or JavaScript code by removing unnecessary spaces, line breaks, and comments.",
"shortDescription": "Minify CSS and JavaScript code",
"longDescription": "",
"language": "Language",
"toolInfo": {
"title": "Minify CSS/JS",
"description": "This tool minifies your CSS or JavaScript code by removing unnecessary characters like whitespace, line breaks, and comments—without affecting functionality. Ideal for optimizing web performance and reducing file size before deployment."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Tools for working with XML data structures - viewer, beautifier, validator and much more",
"title": "XML Tools"
},
"dev": {
"description": "Essential utilities for developers: code formatters, encoders/decoders, diff tools, UUID generators, and more",
"title": "Dev Tools"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "Minificar CSS/JS",
"description": "Comprime tu código CSS o JavaScript eliminando espacios, saltos de línea y comentarios innecesarios.",
"shortDescription": "Minificar código CSS y JavaScript",
"longDescription": "",
"toolInfo": {
"title": "Minificar CSS/JS",
"description": "Esta herramienta minifica tu código CSS o JavaScript eliminando caracteres innecesarios como espacios en blanco, saltos de línea y comentarios, sin afectar su funcionalidad. Ideal para optimizar el rendimiento web y reducir el tamaño de los archivos antes de su implementación."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Herramientas para trabajar con estructuras de datos XML: visor, embellecedor, validador y mucho más",
"title": "Herramientas XML"
},
"dev": {
"description": "Herramientas esenciales para desarrolladores: formateadores de código, codificadores/decodificadores, herramientas de comparación, generadores de UUID y mucho más",
"title": "Herramientas de desarrollo"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "Minifier CSS/JS",
"description": "Compressez votre code CSS ou JavaScript en supprimant les espaces, sauts de ligne et commentaires inutiles.",
"shortDescription": "Minifier du code CSS et JavaScript",
"longDescription": "",
"toolInfo": {
"title": "Minifier CSS/JS",
"description": "Cet outil minifie votre code CSS ou JavaScript en supprimant les caractères superflus comme les espaces, les sauts de ligne et les commentaires — sans altérer le fonctionnement du code. Idéal pour optimiser les performances web et réduire la taille des fichiers avant mise en production."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Outils pour travailler avec des structures de données XML - visualiseur, embellisseur, validateur et bien plus encore",
"title": "Outils XML"
},
"dev": {
"description": "Outils essentiels pour les développeurs : formateurs de code, encodeurs/décodeurs, outils de comparaison, générateurs d'UUID et bien plus encore",
"title": "Outils de développement"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "CSS/JS को संक्षिप्त करें",
"description": "अनावश्यक स्पेस, लाइन ब्रेक और टिप्पणियाँ हटाकर अपने CSS या JavaScript कोड को संक्षिप्त करें।",
"shortDescription": "CSS और JavaScript कोड को मिनिफाई करें",
"longDescription": "",
"toolInfo": {
"title": "CSS/JS को संक्षिप्त करें",
"description": "यह टूल आपके CSS या JavaScript कोड से अनावश्यक वर्ण जैसे स्पेस, लाइन ब्रेक और टिप्पणियाँ हटाकर उसे संक्षिप्त करता है, बिना कार्यक्षमता को प्रभावित किए। यह वेब प्रदर्शन को बेहतर बनाने और परिनियोजन से पहले फ़ाइल का आकार कम करने के लिए आदर्श है।"
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "XML डेटा संरचनाओं के साथ काम करने के लिए टूल्स - व्यूअर, ब्यूटिफायर, वैलिडेटर और बहुत कुछ",
"title": "XML टूल्स"
},
"dev": {
"description": "डेवलपर्स के लिए आवश्यक उपकरण: कोड फ़ॉर्मैटर, एन्कोडर/डिकोडर, तुलना उपकरण, UUID जनरेटर और बहुत कुछ",
"title": "डेव टूल्स"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "CSS/JSの最小化",
"description": "不要なスペース、改行、コメントを削除してCSSまたはJavaScriptコードを圧縮します。",
"shortDescription": "CSSおよびJavaScriptコードを最小化",
"longDescription": "",
"toolInfo": {
"title": "CSS/JSの最小化",
"description": "このツールは、不要な文字空白、改行、コメントなどを削除することで、CSSまたはJavaScriptコードを最小化します。機能を損なうことなく、Webパフォーマンスを最適化し、デプロイ前のファイルサイズを削減するのに最適です。"
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "XML データ構造を操作するためのツール - ビューア、ビューティファイア、バリデータなど",
"title": "XMLツール"
},
"dev": {
"description": "開発者のための必須ツール:コードフォーマッター、エンコーダー/デコーダー、差分ツール、UUIDジェネレーターなど",
"title": "開発ツール"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "CSS/JS verkleinen",
"description": "Comprimeer je CSS- of JavaScript-code door overbodige spaties, regeleinden en opmerkingen te verwijderen.",
"shortDescription": "CSS- en JavaScript-code verkleinen",
"longDescription": "",
"toolInfo": {
"title": "CSS/JS verkleinen",
"description": "Deze tool verkleint je CSS- of JavaScript-code door onnodige tekens zoals spaties, regeleinden en opmerkingen te verwijderen — zonder de functionaliteit aan te tasten. Ideaal om de webprestaties te optimaliseren en de bestandsgrootte vóór deployment te verkleinen."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Hulpmiddelen voor het werken met XML-datastructuren - viewer, beautifier, validator en nog veel meer",
"title": "XML-hulpmiddelen"
},
"dev": {
"description": "Essentiële hulpmiddelen voor ontwikkelaars: codeformatters, encoders/decoders, vergelijkingstools, UUID-generators en meer",
"title": "Ontwikkelaarstools"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "Minificar CSS/JS",
"description": "Comprime seu código CSS ou JavaScript removendo espaços, quebras de linha e comentários desnecessários.",
"shortDescription": "Minificar código CSS e JavaScript",
"longDescription": "",
"toolInfo": {
"title": "Minificar CSS/JS",
"description": "Esta ferramenta minifica seu código CSS ou JavaScript removendo caracteres desnecessários, como espaços em branco, quebras de linha e comentários — sem afetar a funcionalidade. Ideal para otimizar o desempenho da web e reduzir o tamanho dos arquivos antes da implantação."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Ferramentas para trabalhar com estruturas de dados XML - visualizador, embelezador, validador e muito mais",
"title": "Ferramentas XML"
},
"dev": {
"description": "Ferramentas essenciais para desenvolvedores: formatadores de código, codificadores/decodificadores, ferramentas de comparação, geradores de UUID e muito mais",
"title": "Ferramentas de desenvolvimento"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "Минификация CSS/JS",
"description": "Сожмите ваш CSS или JavaScript код, удалив ненужные пробелы, разрывы строк и комментарии.",
"shortDescription": "Минифицировать CSS и JavaScript код",
"longDescription": "",
"toolInfo": {
"title": "Минификация CSS/JS",
"description": "Этот инструмент минимизирует ваш CSS или JavaScript код, удаляя лишние символы, такие как пробелы, переносы строк и комментарии — без потери функциональности. Идеально подходит для оптимизации производительности сайта и уменьшения размера файлов перед развертыванием."
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "Инструменты для работы с XML-структурами данных — просмотрщик, улучшитель, валидатор и многое другое",
"title": "XML-инструменты"
},
"dev": {
"description": "Необходимые инструменты для разработчиков: форматеры кода, энкодеры/декодеры, инструменты сравнения, генераторы UUID и многое другое",
"title": "Инструменты разработчика"
}
},
"csv": {

View file

@ -0,0 +1,12 @@
{
"cssJsMinify": {
"title": "压缩 CSS/JS",
"description": "通过删除不必要的空格、换行和注释来压缩您的 CSS 或 JavaScript 代码。",
"shortDescription": "压缩 CSS 和 JavaScript 代码",
"longDescription": "",
"toolInfo": {
"title": "压缩 CSS/JS",
"description": "该工具通过删除空格、换行符和注释等多余字符来压缩您的 CSS 或 JavaScript 代码,同时不影响功能。非常适合在部署前优化网页性能并减少文件大小。"
}
}
}

View file

@ -71,6 +71,10 @@
"xml": {
"description": "处理 XML 数据结构的工具 - 查看器、美化器、验证器等等",
"title": "XML 工具"
},
"dev": {
"description": "开发者必备工具:代码格式化器、编码器/解码器、差异比较工具、UUID 生成器等",
"title": "开发工具"
}
},
"csv": {

View file

@ -150,7 +150,8 @@ const validNamespaces = [
'audio',
'xml',
'translation',
'image'
'image',
'dev'
];
const isValidI18nNamespace = (value) => {
return validNamespaces.includes(value);

View file

@ -55,7 +55,16 @@ const translationFiles = [
namespace: 'time',
file: '../src/pages/tools/time/i18n/en.json'
},
{ lang: 'en', namespace: 'xml', file: '../src/pages/tools/xml/i18n/en.json' },
{
lang: 'en',
namespace: 'xml',
file: '../src/pages/tools/xml/i18n/en.json'
},
{
lang: 'en',
namespace: 'dev',
file: '../src/pages/tools/dev/i18n/en.json'
},
// Hindi translations
{ lang: 'hi', namespace: 'translation', file: '../src/i18n/hi.json' },

View file

@ -12,6 +12,7 @@ import pdf from '../../public/locales/en/pdf.json';
import audio from '../../public/locales/en/audio.json';
import xml from '../../public/locales/en/xml.json';
import image from '../../public/locales/en/image.json';
import dev from '../../public/locales/en/dev.json';
declare module 'i18next' {
interface CustomTypeOptions {
@ -28,6 +29,7 @@ declare module 'i18next' {
audio: typeof audio;
xml: typeof xml;
image: typeof image;
dev: typeof dev;
};
}
}

View file

@ -14,7 +14,8 @@ export const validNamespaces = [
'audio',
'xml',
'translation',
'image'
'image',
'dev'
] as const satisfies readonly Namespace[];
export type I18nNamespaces = (typeof validNamespaces)[number];

View file

@ -0,0 +1,56 @@
import { expect, describe, it } from 'vitest';
import { convertUnixToDate } from './service';
describe('convertUnixToDate', () => {
it('should convert a single Unix timestamp with label (UTC)', () => {
const input = '0';
const result = convertUnixToDate(input, true, false);
expect(result).toBe('1970-01-01 00:00:00.000 UTC');
});
it('should convert a single Unix timestamp without label (UTC)', () => {
const input = '1234567890';
const result = convertUnixToDate(input, false, false);
expect(result).toBe('2009-02-13 23:31:30.000');
});
it('should convert a single Unix timestamp in local time', () => {
const input = '1234567890';
const result = convertUnixToDate(input, true, true);
expect(result.endsWith('UTC')).toBe(false);
});
it('should handle multiple lines with label (UTC)', () => {
const input = '0\n2147483647';
const result = convertUnixToDate(input, true, false);
expect(result).toBe(
'1970-01-01 00:00:00.000 UTC\n2038-01-19 03:14:07.000 UTC'
);
});
it('should handle multiple lines with local time', () => {
const input = '1672531199\n1721287227';
const result = convertUnixToDate(input, false, true);
const lines = result.split('\n');
expect(lines.length).toBe(2);
expect(lines[0].endsWith('UTC')).toBe(false);
});
it('should return empty string for invalid input', () => {
const input = 'not_a_number';
const result = convertUnixToDate(input, true, false);
expect(result).toBe('');
});
it('should return empty string for empty input', () => {
const input = '';
const result = convertUnixToDate(input, false, false);
expect(result).toBe('');
});
it('should ignore invalid lines in multiline input', () => {
const input = 'abc\n1600000000';
const result = convertUnixToDate(input, true, false);
expect(result).toBe('\n2020-09-13 12:26:40.000 UTC');
});
});

View file

@ -0,0 +1,87 @@
import { Box, FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import { useState } from 'react';
import ToolContent from '@components/ToolContent';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import { useTranslation } from 'react-i18next';
import { ToolComponentProps } from '@tools/defineTool';
import { GetGroupsType } from '@components/options/ToolOptions';
import { CardExampleType } from '@components/examples/ToolExamples';
import { minifyCss, minifyJs } from './service';
const initialValues = {
language: 'css' as 'css' | 'js'
};
type InitialValuesType = typeof initialValues;
const exampleCards: CardExampleType<InitialValuesType>[] = [
{
title: 'Minify CSS Example',
description: 'This example shows how a simple CSS block is minified.',
sampleText: `body {\n margin: 0;\n padding: 0;\n background-color: white;\n}`,
sampleResult: `body{margin:0;padding:0;background-color:white}`,
sampleOptions: { language: 'css' }
},
{
title: 'Minify JS Example',
description: 'This example demonstrates JavaScript minification.',
sampleText: `function hello(name) {\n console.log("Hello, " + name);\n}`,
sampleResult: `function hello(name){console.log("Hello,"+name)}`,
sampleOptions: { language: 'js' }
}
];
export default function CssJsMinify({ title }: ToolComponentProps) {
const { t } = useTranslation('dev');
const [input, setInput] = useState('');
const [result, setResult] = useState('');
const compute = (values: InitialValuesType, input: string) => {
const minified =
values.language === 'css' ? minifyCss(input) : minifyJs(input);
setResult(minified);
};
const getGroups: GetGroupsType<InitialValuesType> = ({
values,
updateField
}) => [
{
title: t('cssJsMinify.language'),
component: (
<Box mt={1}>
<FormControl fullWidth>
<InputLabel>{t('cssJsMinify.language')}</InputLabel>
<Select
value={values.language}
onChange={(e) =>
updateField('language', e.target.value as 'css' | 'js')
}
>
<MenuItem value="css">CSS</MenuItem>
<MenuItem value="js">JavaScript</MenuItem>
</Select>
</FormControl>
</Box>
)
}
];
return (
<ToolContent
title={title}
input={input}
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
resultComponent={<ToolTextResult value={result} />}
initialValues={initialValues}
exampleCards={exampleCards}
getGroups={getGroups}
setInput={setInput}
compute={compute}
toolInfo={{
title: t('cssJsMinify.toolInfo.title'),
description: t('cssJsMinify.toolInfo.description')
}}
/>
);
}

View file

@ -0,0 +1,15 @@
import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('dev', {
i18n: {
name: 'dev:cssJsMinify.title',
description: 'dev:cssJsMinify.description',
shortDescription: 'dev:cssJsMinify.shortDescription',
longDescription: 'dev:cssJsMinify.longDescription'
},
path: 'css-js-minify',
icon: 'material-symbols:code',
keywords: ['css', 'js', 'minify'],
component: lazy(() => import('./index'))
});

View file

@ -0,0 +1,28 @@
import { containsOnlyDigits } from '@utils/string';
export function minifyCss(input: string): string {
try {
return input
.replace(/\/\*[\s\S]*?\*\//g, '') // remove comments
.replace(/\s*([{}:;,])\s*/g, '$1') // remove spaces around tokens
.replace(/\s+/g, ' ') // collapse whitespace
.replace(/;}/g, '}') // remove unnecessary semicolons
.trim();
} catch {
return '/* CSS minification error */';
}
}
export function minifyJs(input: string): string {
try {
return input
.replace(/\/\/[^\n]*/g, '') // remove line comments
.replace(/\/\*[\s\S]*?\*\//g, '') // remove block comments
.replace(/\s*([=+\-*/{}();,:<>|&!])\s*/g, '$1') // remove spaces around operators
.replace(/\s+/g, ' ') // collapse spaces
.replace(/;\s*}/g, '}') // remove semicolon before }
.trim();
} catch {
return '// JavaScript minification error';
}
}

View file

@ -0,0 +1,3 @@
import { tool as cssJsMinify } from './css-js-minify/meta';
export const devTools = [cssJsMinify];

View file

@ -30,7 +30,8 @@ export type ToolCategory =
| 'pdf'
| 'image-generic'
| 'audio'
| 'xml';
| 'xml'
| 'dev';
export interface DefinedTool {
type: ToolCategory;

View file

@ -13,6 +13,7 @@ import { timeTools } from '../pages/tools/time';
import { IconifyIcon } from '@iconify/react';
import { pdfTools } from '../pages/tools/pdf';
import { xmlTools } from '../pages/tools/xml';
import { devTools } from '../pages/tools/dev';
import { TFunction } from 'i18next';
import { FullI18nKey, I18nNamespaces } from '../i18n';
@ -30,7 +31,8 @@ const toolCategoriesOrder: ToolCategory[] = [
'png',
'time',
'xml',
'gif'
'gif',
'dev'
];
export const tools: DefinedTool[] = [
...imageTools,
@ -43,7 +45,8 @@ export const tools: DefinedTool[] = [
...numberTools,
...timeTools,
...audioTools,
...xmlTools
...xmlTools,
...devTools
];
const categoriesConfig: {
type: ToolCategory;
@ -134,6 +137,12 @@ const categoriesConfig: {
icon: 'mdi-light:xml',
value: 'translation:categories.xml.description',
title: 'translation:categories.xml.title'
},
{
type: 'dev',
icon: 'mdi:code-block-braces',
value: 'translation:categories.dev.description',
title: 'translation:categories.dev.title'
}
];
// use for changelogs