diff --git a/README.md b/README.md index e4a3ea9..ab7d7e2 100644 --- a/README.md +++ b/README.md @@ -105,16 +105,19 @@ an [issue](https://github.com/webdiscus/ansis/issues) on GitHub. ## πŸ”„ [Why switch to Ansis](#switch-to-ansis) Today, the two [smallest](#compare-size) and [fastest](#benchmark) libraries are `ansis` and `picocolors`. -Both are recommended by the [ES Tooling](https://github.com/es-tooling) community as the best replacements for older, bulkier libraries. +Both are [recommended](https://github.com/es-tooling/module-replacements/blob/main/docs/modules/chalk.md) by the [ES Tooling](https://github.com/es-tooling) community as replacements for older, bulkier libraries. ### πŸ“¦ Unpacked size + +The package size in `node_modules` directory: + - `picocolors`: [6.4 kB][npm-picocolors] - A micro library with only basic features. - `Π°nsis`: [7.0 kB][npm-ansis] - A powerful library containing all the features you need. -- `chalk`: [44.2 kB][npm-chalk] - Provides similar functionality to Ansis but is larger. +- `chalk`: [44.2 kB][npm-chalk] - Provides similar functionality to Ansis. ### ⚑ Performance -- `picocolors`: The fastest when applying a single style (e.g., `red` only). +- `picocolors`: The fastest when applying a single style (e.g., `red`) only. - `Π°nsis`: The fastest when applying two or more styles (e.g., `red` + `bgWhite`). - `chalk`: Slower than both **Ansis** and **Picocolors** in all use cases. @@ -132,10 +135,10 @@ Only `ansis`, `chalk`, and `picocolors` are actively maintained, unlike many oth ### πŸ€” Which One Should You Use? -- If you only use a single style, such as `red('foo')`, **Picocolors** is the best solution. +- If you only use a single style, e.g., `red('foo')`, **Picocolors** is the best solution. - However, if you need more, like combining multiple styles (e.g., `red` + `bold` + `bgWhite`),\ - [ANSI256 colors](#256-colors), [Truecolor](#truecolor), + [256 colors](#256-colors), [Truecolor](#truecolor), or support for a wide range of [environments](#color-support), then **Ansis** is the better choice. @@ -147,13 +150,28 @@ Explore the list of [features](#compare), [package sizes](#compare-size), and [b > Use the chained syntax provided by libraries like `ansis` and `chalk`.\ > Avoid nested calls, as they are [much slower](#bench-3-styles) and less readable than the chained syntax.\ > _**Keep your code clean and readable!**_ -> ```js -> red.bold.bgWhite`Error` βœ… ansis: faster, shorter, readable -> pico.red(pico.bold(pico.bgWhite('Error'))) ❌ picocolor: slower, longer, unreadable -> -> red`Error: ${cyan.underline(file)} not found!` βœ… ansis 😊 -> pico.red(`Error: ${pico.cyan(pico.underline(file))} not found!`) ❌ picocolor πŸ₯΄ -> ``` + +#### Usage examples +```js +import ansis, { red, green, cyan } from 'ansis' // βœ…βœ… supports both default and named imports +import chalk from 'chalk' // βœ…βŒ doesn't support named import +import pico from 'picocolors' // βœ…βŒ doesn't support named import + +ansis.red('Error') // ansis ❌ slower than picocolors +chalk.red('Error') // chalk ❌ slower than ansis +pico.red('Error') // picocolors βœ… fastest + +red.bold.bgWhite`Error` // ansis βœ…βœ…βœ… fastest, short, readable +chalk.red.bold.bgWhite('Error') // chalk βŒβ˜‘οΈβœ… slower, short, readable +pico.red(pico.bold(pico.bgWhite('Error'))) // picocolors ❌❌❌ slowest, long, unreadable + +green`Create ${blue.bold`React`} app.` // ansis βœ… usability 😊 +chalk.green(`Create ${chalk.blue.bold('React')} app.`) // chalk β˜‘οΈ usability πŸ™‚ +pico.green(`Create ${pico.blue(pico.bold('React'))} app.`) // picocolors ❌ usability πŸ₯΄ +``` + +> [!TIP] +> Ansis supports **nested template strings**, so you can colorize text without using parentheses. ## [How to switch to Ansis](#switch-to-ansis) diff --git a/compare/index.js b/compare/index.js index b605fcb..826e4db 100644 --- a/compare/index.js +++ b/compare/index.js @@ -10,8 +10,8 @@ import colorCli from 'colors-cli/safe.js'; import kleur from 'kleur'; import * as kleurColors from 'kleur/colors'; import * as kolorist from 'kolorist'; -import picocolors from 'picocolors'; -import ansis, { greenBright, redBright, bgRed, bgBlueBright, black, yellow, hex } from 'ansis'; +import pico from 'picocolors'; +import ansis, { greenBright, redBright, bgRed, bgBlueBright, green, blue, black, yellow, hex } from 'ansis'; import { hexToRgb } from '../src/utils.js'; import spectrum from './spectrum.js'; @@ -60,7 +60,7 @@ function showSupportOfDeepNestedStyling() { logWithLabel(greenBright.inverse` OK `, 'kolorist: ', deepNestedFixture(kolorist)); logWithLabel(greenBright.inverse` OK `, 'colors.js: ', deepNestedFixture(colorsJs)); logWithLabel(greenBright.inverse` OK `, 'colorette: ', deepNestedFixture(colorette)); - logWithLabel(greenBright.inverse` OK `, 'picocolors: ', deepNestedFixture(picocolors)); + logWithLabel(greenBright.inverse` OK `, 'picocolors: ', deepNestedFixture(pico)); logWithLabel(greenBright.inverse` OK `, 'cli-color: ', deepNestedFixture(cliColor)); logWithLabel(black.bgYellow` BUG `, 'colors-cli: ', deepNestedFixture(colorCli)); logWithLabel(greenBright.inverse` OK `, 'ansi-colors: ', deepNestedFixture(ansiColors)); @@ -91,7 +91,7 @@ function showSupportOfNestedTemplateStrings() { logWithLabel(bgRed` FAIL `, 'kolorist: ', nestedTemplateStringFixture(kolorist)); logWithLabel(bgRed` FAIL `, 'colors.js: ', nestedTemplateStringFixture(colorsJs)); logWithLabel(bgRed` FAIL `, 'colorette: ', nestedTemplateStringFixture(colorette)); - logWithLabel(bgRed` FAIL `, 'picocolors: ', nestedTemplateStringFixture(picocolors)); + logWithLabel(bgRed` FAIL `, 'picocolors: ', nestedTemplateStringFixture(pico)); logWithLabel(bgRed` FAIL `, 'cli-color: ', nestedTemplateStringFixture(cliColor)); logWithLabel(bgRed` FAIL `, 'colors-cli: ', nestedTemplateStringFixture(colorCli)); logWithLabel(bgRed` FAIL `, 'ansi-colors: ', nestedTemplateStringFixture(ansiColors)); @@ -106,7 +106,7 @@ function showSupportOfBreakStyleAtNewLine() { logWithLabel(bgRed` FAIL `, 'kolorist: ', kolorist.bgCyan(breakStyleAtNewLineFixture)); logWithLabel(greenBright.inverse` OK `, 'colors.js: ', colorsJs.bgCyan(breakStyleAtNewLineFixture)); logWithLabel(bgRed` FAIL `, 'colorette: ', colorette.bgCyan(breakStyleAtNewLineFixture)); - logWithLabel(bgRed` FAIL `, 'picocolors: ', picocolors.bgCyan(breakStyleAtNewLineFixture)); + logWithLabel(bgRed` FAIL `, 'picocolors: ', pico.bgCyan(breakStyleAtNewLineFixture)); logWithLabel(bgRed` FAIL `, 'cli-color: ', cliColor.bgCyan(breakStyleAtNewLineFixture)); logWithLabel(bgRed` FAIL `, 'colors-cli: ', colorCli.cyan_b(breakStyleAtNewLineFixture)); logWithLabel(greenBright.inverse` OK `, 'ansi-colors: ', ansiColors.bgCyan(breakStyleAtNewLineFixture)); @@ -137,3 +137,13 @@ showSupportOfDeepNestedChainedStyling(); showSupportOfNestedTemplateStrings(); showSupportOfBreakStyleAtNewLine(); showFallbackToSupportedColorSpace(); + +console.log(green`New ${blue.bold`React`} app is created!`); +console.log(chalk.green`New ${chalk.blue.bold('React')} app is created!`); +console.log(chalk.green(`New ${chalk.blue.bold('React')} app is created!`)); +console.log(chalk.green(`New ${chalk.blue.bold`React`} app is created!`)); + +console.log(pico.green(`Create ${pico.blue(pico.bold('React'))} app!`)); +console.log(pico.green`Create ${pico.blue(pico.bold`React`)} app!`); + +console.log(pico.green(`Create ${pico.blue(pico.bold`React`)} app!`)); diff --git a/src/index.type.d.ts b/src/index.type.d.ts index 21cb841..a970ffa 100644 --- a/src/index.type.d.ts +++ b/src/index.type.d.ts @@ -25,17 +25,6 @@ type BBC = `${BC}Bright`; /** * Base ANSI Colors - * 4515 - * 3713 - * 3263; 4515 - 3263 = 1252 - * 3228; 4515 - 3228 = 1287 - * 3161; 4515 - 3161 = 1354 - * 3148; 4515 - 3148 = 1367 => 8.97 kB - beta.0 - * - * 2611; 4515 - 2611 = 1904 => 8.4 kB - * 2492; 4515 - 2492 = 2023 => 8.3 kB - * 2244; 4515 - 2244 = 2271 => 8.1 kB - * 2201; 4515 - 2201 = 2314 => 8.0 kB */ type AnsiColors = | BC diff --git a/test/ts/module-import-esnext/expected/index.out b/test/ts/module-import-esnext/expected/index.out index 8c25740..41fb7f1 100644 --- a/test/ts/module-import-esnext/expected/index.out +++ b/test/ts/module-import-esnext/expected/index.out @@ -8,6 +8,7 @@ Hello World! default: cyanBright extended: pink extended: orange +formatValue [string] extended color: apple italic destructured default color: red destructured extended color: pink diff --git a/test/ts/module-import-esnext/src/index.ts b/test/ts/module-import-esnext/src/index.ts index b6c6e5e..592f2ae 100644 --- a/test/ts/module-import-esnext/src/index.ts +++ b/test/ts/module-import-esnext/src/index.ts @@ -1,5 +1,5 @@ // TS1484: AnsiColorsExtend is a type and must be imported using a type-only import when `verbatimModuleSyntax` is enabled. -import ansis, { type AnsiColorsExtend, bgAnsi256, bgGray, bgCyanBright } from 'ansis'; +import ansis, { Ansis, type AnsiColorsExtend, greenBright, bgAnsi256, bgGray, bgCyanBright } from 'ansis'; const log = console.log; @@ -39,6 +39,11 @@ const myLog = (style: AnsiColorsExtend, message: string) = log((ansis as Record)[style](message)); }; +// OK +const formatValue = (value: any, colorFn: Ansis) => { + return colorFn(`${value} ${greenBright(`[${typeof value}]`)}`); +}; + myLog('red', 'default: red'); // default style, OK myLog('cyanBright', 'default: cyanBright'); // default style, OK myLog('pink', 'extended: pink'); // extended style, OK @@ -46,6 +51,8 @@ myLog('orange', 'extended: orange'); // extended style, OK //myLog('apple', 'extended: apple'); // OK //myLog('unknown', 'message'); // TS Error, OK +log(formatValue('formatValue', ansis.red)); + log(ansis.apple.italic`extended color: apple italic`); log(red`destructured default color: red`); log(pink`destructured extended color: pink`); diff --git a/test/ts/module-import-node16/expected/index.out b/test/ts/module-import-node16/expected/index.out index 8c25740..41fb7f1 100644 --- a/test/ts/module-import-node16/expected/index.out +++ b/test/ts/module-import-node16/expected/index.out @@ -8,6 +8,7 @@ Hello World! default: cyanBright extended: pink extended: orange +formatValue [string] extended color: apple italic destructured default color: red destructured extended color: pink diff --git a/test/ts/module-import-node16/src/index.ts b/test/ts/module-import-node16/src/index.ts index b6c6e5e..d917d4a 100644 --- a/test/ts/module-import-node16/src/index.ts +++ b/test/ts/module-import-node16/src/index.ts @@ -1,8 +1,15 @@ // TS1484: AnsiColorsExtend is a type and must be imported using a type-only import when `verbatimModuleSyntax` is enabled. -import ansis, { type AnsiColorsExtend, bgAnsi256, bgGray, bgCyanBright } from 'ansis'; +import ansis, { Ansis, type AnsiColorsExtend, greenBright, bgAnsi256, bgGray, bgCyanBright } from 'ansis'; + +//import pico from 'picocolors'; // ok +//import { blue } from 'picocolors'; // Error: Named export 'blue' not found. The requested module 'picocolors' is a CommonJS module, which may not support all module.exports as named exports. const log = console.log; +// test Picocolors in TS +//log(pico.red('pico red')); // no color output +//log(blue('pico blue')); // fatal error + let isSupported = ansis.isSupported(); log('isSupported: ', ansis.ansi256(192)`${isSupported}`); log('bgAnsi256: ', bgAnsi256(127)(1993)); // test number value @@ -39,6 +46,11 @@ const myLog = (style: AnsiColorsExtend, message: string) = log((ansis as Record)[style](message)); }; +// OK +const formatValue = (value: any, colorFn: Ansis) => { + return colorFn(`${value} ${greenBright(`[${typeof value}]`)}`); +}; + myLog('red', 'default: red'); // default style, OK myLog('cyanBright', 'default: cyanBright'); // default style, OK myLog('pink', 'extended: pink'); // extended style, OK @@ -46,6 +58,8 @@ myLog('orange', 'extended: orange'); // extended style, OK //myLog('apple', 'extended: apple'); // OK //myLog('unknown', 'message'); // TS Error, OK +log(formatValue('formatValue', ansis.red)); + log(ansis.apple.italic`extended color: apple italic`); log(red`destructured default color: red`); log(pink`destructured extended color: pink`);