Skip to content

Commit

Permalink
refactor: optimize package size
Browse files Browse the repository at this point in the history
  • Loading branch information
webdiscus committed Jan 10, 2025
1 parent d09f2b7 commit cf31548
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 100 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 3.8.1 (2025-01-10)

- refactor: optimize package size

## 3.8.0 (2025-01-09)

- feat: enforce a specific color support by a `FORCE_COLOR` value:
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ Ansis is as [small](#compare-size) as **Picocolors** but has the [functionality]
## 🛠️ Usage

```js
import ansis, { red, green, cyan, black, ansi256, hex } from 'ansis';
import ansis, { red, cyan, ansi256, hex } from 'ansis';

ansis.blueBright('file.txt')
green`Succeful!`
red`Error: ${cyan(file)} not found!`
black.bgYellow`Warning!`
red.bgWhite`ERROR`
ansi256(214)`Orange`
hex('#E0115F').bold.underline('Truecolor!')
```
Expand Down Expand Up @@ -112,7 +111,7 @@ Both are [recommended](https://github.com/es-tooling/module-replacements/blob/ma
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.
- `аnsis`: [6.7 kB][npm-ansis] - A powerful library containing all the features you need.
- `chalk`: [44.2 kB][npm-chalk] - Provides similar functionality to Ansis.

### ⚡ Performance
Expand Down Expand Up @@ -946,7 +945,7 @@ npm run compare
| Npm package | Download tarball size | Unpacked Size | Code size |
|:-----------------------------|-----------------------------------------------------------------------:|-------------------------------:|----------:|
| [`picocolors`][picocolors] | [2.6 kB](https://arve0.github.io/npm-download-size/#picocolors) | [6.4 kB][npm-picocolors] | 2.6 kB
| [`ansis`][ansis] | [3.8 kB](https://arve0.github.io/npm-download-size/#ansis) | [7.0 kB][npm-ansis] | 3.4 kB
| [`ansis`][ansis] | [3.8 kB](https://arve0.github.io/npm-download-size/#ansis) | [6.7 kB][npm-ansis] | 3.4 kB
| [`colorette`][colorette] | [4.9 kB](https://arve0.github.io/npm-download-size/#colorette) | [17.0 kB][npm-colorette] | 3.4 kB
| [`kleur`][kleur] | [6.0 kB](https://arve0.github.io/npm-download-size/#kleur) | [20.3 kB][npm-kleur] | 2.7 kB
| [`ansi-colors`][ansi-colors] | [8.5 kB](https://arve0.github.io/npm-download-size/#ansi-colors) | [26.1 kB][npm-ansi-colors] | 5.8 kB
Expand Down
34 changes: 12 additions & 22 deletions README.npm-src.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
# Ansis

Enable ANSI colors in terminal output. [Docs on GitHub](https://github.com/webdiscus/ansis).

#

<p align="center">
<a href="https://github.com/webdiscus/ansis">
<img width="323" src="https://github.com/webdiscus/ansis/raw/master/docs/img/ansis-logo.png"><br>
ANSI Styling
<img width="323" src="https://github.com/webdiscus/ansis/raw/master/docs/img/logo.png"><br>
</a>
</p>

---
[![codecov](https://codecov.io/gh/webdiscus/ansis/branch/master/graph/badge.svg?token=H7SFJONX1X)](https://codecov.io/gh/webdiscus/ansis)
[![node](https://img.shields.io/npm/dm/ansis)](https://www.npmjs.com/package/ansis)
[![size](https://img.shields.io/bundlephobia/minzip/ansis)](https://bundlephobia.com/package/ansis)

Colorize terminal with ANSI colors & styles, smaller and faster alternative to Chalk.

🚀 [Install and Quick Start](https://github.com/webdiscus/ansis#install)

[Compare features](https://github.com/webdiscus/ansis#compare) with similar packages

📊 [Benchmarks](https://github.com/webdiscus/ansis#benchmark)

📖 [Read full docs on GitHub](https://github.com/webdiscus/ansis)

## Usage

```js
import ansis, { red, green, black, ansi256, hex } from 'ansis';
import ansis, { red, cyan, ansi256, hex } from 'ansis';

ansis.cyan('file')
green('Ok')
red`Error`
black.bgYellow`Warning`
ansis.blueBright('file.txt')
red`Error: ${cyan(file)} not found!`
red.bgWhite`ERROR`
ansi256(214)`Orange`
hex('#E0115F').bold('TrueColor')
hex('#E0115F').bold.underline('Truecolor!')
```

## Highlights
Expand Down
8 changes: 4 additions & 4 deletions README.npm.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h1 align="center"><img src="docs/img/logo.png"></h1>
# Ansis

Colorize terminal with ANSI colors & styles.
Enable ANSI colors in terminal output. [Docs on GitHub](https://github.com/webdiscus/ansis).

## 📖 [Docs on GitHub](https://github.com/webdiscus/ansis)
#

![](docs/img/npm.png)
![](docs/npm.png)
2 changes: 2 additions & 0 deletions bench/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const bench = new Bench({

log(hex('#F88').inverse.bold` -= Benchmark =- `);

bench('Simple, ansis').add(packages['ansis'], () => ansis.red('foo')).run();

// Simple bench
bench('Simple, using 1 style').
add(packages['chalk'], () => chalk.red('foo')).
Expand Down
Binary file removed docs/img/npm.png
Binary file not shown.
Binary file added docs/npm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 4 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
{
"name": "ansis",
"version": "3.8.0",
"version": "3.8.1",
"description": "A small and fast Node.js library for applying ANSI colors and styles in terminal output",
"keywords": [
"ansi",
"colour",
"color",
"colors",
"styles",
"console",
"terminal",
"xterm",
"console",
"cli",
"log",
"logging",
"truecolor",
"rgb",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"truecolor",
"FORCE_COLOR",
"NO_COLOR",
"ansi-colors",
"chalk",
"colorette",
"colors.js",
"kleur",
"picocolors"
"NO_COLOR"
],
"license": "ISC",
"author": "webdiscus (https://github.com/webdiscus)",
Expand Down
48 changes: 19 additions & 29 deletions package.npm.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
{
"name": "ansis",
"version": "3.8.0",
"description": "ANSI colors and styles in terminal output",
"keywords": [
"ansi",
"color",
"console",
"terminal",
"cli"
],
"license": "ISC",
"author": "webdiscus",
"repository": "webdiscus/ansis",
"main": "./index.js",
"types": "./index.d.ts",
"exports": {
".": {
"types": "./index.d.ts",
"require": "./index.js",
"import": "./index.mjs"
}
},
"sideEffects": false,
"engines": {
"node": ">=16"
},
"files": [
"index.*"
]
"name":"ansis",
"version":"3.8.1",
"description":"ANSI colors in terminal output",
"keywords":["ansi","color","style","terminal","cli"],
"license":"ISC",
"author":"webdiscus",
"repository":"webdiscus/ansis",
"main":"./index.js",
"types":"./index.d.ts",
"exports":{
".":{
"types":"./index.d.ts",
"require":"./index.js",
"import":"./index.mjs"
}
},
"sideEffects":false,
"engines":{"node":">=16"},
"files":["index.*"]
}
38 changes: 17 additions & 21 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,43 @@ let stylePrototype;
let createStyle = ({ _p: props }, { open, close }) => {
/**
* Decorate the string with ANSI codes.
* @param {string} strings The normal or template string.
* @param {string} input The input value, can be any or a template string.
* @param {array} values The values of the template string.
* @return {string}
*/
let styleFn = (strings, ...values) => {
let styleFn = (input, ...values) => {
// if the argument is an empty string, an empty string w/o escape codes should be returned
if (strings === '') return strings;
if (input === '') return input;

let props = styleFn._p;
let { _a: openStack, _b: closeStack } = props;

// resolve the input string
let str = strings?.raw
let output = input?.raw
// render template string
? String.raw(strings, ...values)
? String.raw(input, ...values)
// convert to string
: '' + strings;
: '' + input;

// -> detect nested styles
// on node.js, the performance of `includes()` and `~indexOf()` is the same, no difference
if (str.includes('')) {
if (~output.indexOf('')) {
while (props) {
// this implementation is over 30% faster than native String.replaceAll()
//str = str.replaceAll(props.close, props.open);
// -- begin replaceAll, inline the function here to optimize the bundle size
//output = output.replaceAll(props.close, props.open);
// -- begin replaceAll, inline the function here to reduce the bundle size
let search = props.close;
let replacement = props.open;
let searchLength = search.length;
let result = '';
let lastPos;
let lastPos = 0;
let pos;

// the `visible` style has empty open/close props
// the `visible` style has empty open/close properties
if (searchLength) {
for (lastPos = 0; ~(pos = str.indexOf(search, lastPos)); lastPos = pos + searchLength) {
result += str.slice(lastPos, pos) + replacement;
for (; ~(pos = output.indexOf(search, lastPos)); lastPos = pos + searchLength) {
result += output.slice(lastPos, pos) + replacement;
}

if (lastPos) str = result + str.slice(lastPos);
output = result + output.slice(lastPos);
}
// -- end replaceAll

Expand All @@ -73,13 +71,11 @@ let createStyle = ({ _p: props }, { open, close }) => {
}

// -> detect new line
//if (str.includes('\n')) {
// size optimisation: using ~indexOf instead of includes, the compiled bundle is smaller by 1 byte
if (~str.indexOf('\n')) {
str = str.replace(/(\r?\n)/g, closeStack + '$1' + openStack);
if (~output.indexOf('\n')) {
output = output.replace(/(\r?\n)/g, closeStack + '$1' + openStack);
}

return openStack + str + closeStack;
return openStack + output + closeStack;
};

let openStack = open;
Expand Down
4 changes: 2 additions & 2 deletions test/functional.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ describe('style tests', () => {
});

test(`visible with template literal`, () => {
const received = ansis.visible`foo ${green`bar`}`;
const expected = 'foo \x1b[32mbar\x1b[39m';
const received = ansis.visible`foo ${green`bar ${red`baz`} bar`} foo`;
const expected = 'foo \x1b[32mbar \x1b[31mbaz\x1b[32m bar\x1b[39m foo';
expect(esc(received)).toEqual(esc(expected));
});

Expand Down

0 comments on commit cf31548

Please sign in to comment.