diff --git a/.changeset/sweet-houses-kick.md b/.changeset/sweet-houses-kick.md new file mode 100644 index 0000000000..daeca90ffd --- /dev/null +++ b/.changeset/sweet-houses-kick.md @@ -0,0 +1,5 @@ +--- +"create-react-router": patch +--- + +chore: replace chalk with picocolors diff --git a/contributors.yml b/contributors.yml index 31584cfcfc..e26d62fcde 100644 --- a/contributors.yml +++ b/contributors.yml @@ -356,6 +356,7 @@ - robbtraister - RobHannay - robinvdvleuten +- roli-lpci - rossipedia - rtmann - rtzll diff --git a/package.json b/package.json index 568a7299e6..581823b18f 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/parser": "^7.5.0", "babel-jest": "^29.7.0", "babel-plugin-dev-expression": "^0.2.3", - "chalk": "^4.1.2", + "picocolors": "^1.1.1", "dox": "^1.0.0", "eslint": "^8.57.0", "eslint-config-react-app": "^7.0.1", diff --git a/packages/create-react-router/package.json b/packages/create-react-router/package.json index a2df126d02..dd0aaafaf5 100644 --- a/packages/create-react-router/package.json +++ b/packages/create-react-router/package.json @@ -39,7 +39,7 @@ "dependencies": { "@remix-run/web-fetch": "^4.4.2", "arg": "^5.0.1", - "chalk": "^4.1.2", + "picocolors": "^1.1.1", "execa": "5.1.1", "gunzip-maybe": "^1.4.2", "log-update": "^5.0.1", diff --git a/packages/create-react-router/utils.ts b/packages/create-react-router/utils.ts index 0effcdb084..6c30c56c85 100644 --- a/packages/create-react-router/utils.ts +++ b/packages/create-react-router/utils.ts @@ -5,56 +5,69 @@ import process from "node:process"; import os from "node:os"; import { type Key as ActionKey } from "node:readline"; import { erase, cursor } from "sisteransi"; -import chalk from "chalk"; +import pc from "picocolors"; // https://no-color.org/ -const SUPPORTS_COLOR = chalk.supportsColor && !process.env.NO_COLOR; +// picocolors natively respects NO_COLOR and FORCE_COLOR env vars +const SUPPORTS_COLOR = pc.isColorSupported; export const color = { supportsColor: SUPPORTS_COLOR, - heading: safeColor(chalk.bold), - arg: safeColor(chalk.yellowBright), - error: safeColor(chalk.red), - warning: safeColor(chalk.yellow), - hint: safeColor(chalk.blue), - bold: safeColor(chalk.bold), - black: safeColor(chalk.black), - white: safeColor(chalk.white), - blue: safeColor(chalk.blue), - cyan: safeColor(chalk.cyan), - red: safeColor(chalk.red), - yellow: safeColor(chalk.yellow), - green: safeColor(chalk.green), - blackBright: safeColor(chalk.blackBright), - whiteBright: safeColor(chalk.whiteBright), - blueBright: safeColor(chalk.blueBright), - cyanBright: safeColor(chalk.cyanBright), - redBright: safeColor(chalk.redBright), - yellowBright: safeColor(chalk.yellowBright), - greenBright: safeColor(chalk.greenBright), - bgBlack: safeColor(chalk.bgBlack), - bgWhite: safeColor(chalk.bgWhite), - bgBlue: safeColor(chalk.bgBlue), - bgCyan: safeColor(chalk.bgCyan), - bgRed: safeColor(chalk.bgRed), - bgYellow: safeColor(chalk.bgYellow), - bgGreen: safeColor(chalk.bgGreen), - bgBlackBright: safeColor(chalk.bgBlackBright), - bgWhiteBright: safeColor(chalk.bgWhiteBright), - bgBlueBright: safeColor(chalk.bgBlueBright), - bgCyanBright: safeColor(chalk.bgCyanBright), - bgRedBright: safeColor(chalk.bgRedBright), - bgYellowBright: safeColor(chalk.bgYellowBright), - bgGreenBright: safeColor(chalk.bgGreenBright), - gray: safeColor(chalk.gray), - dim: safeColor(chalk.dim), - reset: safeColor(chalk.reset), - inverse: safeColor(chalk.inverse), - hex: (color: string) => safeColor(chalk.hex(color)), - underline: chalk.underline, + heading: safeColor(pc.bold), + arg: safeColor(pc.yellowBright), + error: safeColor(pc.red), + warning: safeColor(pc.yellow), + hint: safeColor(pc.blue), + bold: safeColor(pc.bold), + black: safeColor(pc.black), + white: safeColor(pc.white), + blue: safeColor(pc.blue), + cyan: safeColor(pc.cyan), + red: safeColor(pc.red), + yellow: safeColor(pc.yellow), + green: safeColor(pc.green), + blackBright: safeColor(pc.blackBright), + whiteBright: safeColor(pc.whiteBright), + blueBright: safeColor(pc.blueBright), + cyanBright: safeColor(pc.cyanBright), + redBright: safeColor(pc.redBright), + yellowBright: safeColor(pc.yellowBright), + greenBright: safeColor(pc.greenBright), + bgBlack: safeColor(pc.bgBlack), + bgWhite: safeColor(pc.bgWhite), + bgBlue: safeColor(pc.bgBlue), + bgCyan: safeColor(pc.bgCyan), + bgRed: safeColor(pc.bgRed), + bgYellow: safeColor(pc.bgYellow), + bgGreen: safeColor(pc.bgGreen), + bgBlackBright: safeColor(pc.bgBlackBright), + bgWhiteBright: safeColor(pc.bgWhiteBright), + bgBlueBright: safeColor(pc.bgBlueBright), + bgCyanBright: safeColor(pc.bgCyanBright), + bgRedBright: safeColor(pc.bgRedBright), + bgYellowBright: safeColor(pc.bgYellowBright), + bgGreenBright: safeColor(pc.bgGreenBright), + gray: safeColor(pc.gray), + dim: safeColor(pc.dim), + reset: safeColor(pc.reset), + inverse: safeColor(pc.inverse), + hex: (hex: string) => safeColor(hexColor(hex)), + underline: pc.underline, }; -function safeColor(style: chalk.Chalk) { +/** + * Converts a hex color string to an ANSI true-color (24-bit) formatter. + * Used by the loading indicator gradient animation. + */ +function hexColor(hex: string): (input: string) => string { + let h = hex.replace("#", ""); + let r = parseInt(h.substring(0, 2), 16); + let g = parseInt(h.substring(2, 4), 16); + let b = parseInt(h.substring(4, 6), 16); + return (input: string) => `\x1b[38;2;${r};${g};${b}m${input}\x1b[39m`; +} + +function safeColor(style: (input: string) => string) { return SUPPORTS_COLOR ? style : identity; } @@ -93,8 +106,8 @@ export function logError(message: string) { function logBullet( logger: typeof log | typeof logError, - colorizePrefix: (v: V) => V, - colorizeText: (v: V) => V, + colorizePrefix: (v: string) => string, + colorizeText: (v: string) => string, symbol: string, prefix: string, text?: string | string[], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 098fc66e24..ec15823e78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,9 +115,6 @@ importers: babel-plugin-dev-expression: specifier: ^0.2.3 version: 0.2.3(@babel/core@7.27.7) - chalk: - specifier: ^4.1.2 - version: 4.1.2 dox: specifier: ^1.0.0 version: 1.0.0 @@ -160,6 +157,9 @@ importers: jsonfile: specifier: ^6.1.0 version: 6.1.0 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 prettier: specifier: ^3.6.2 version: 3.6.2 @@ -828,9 +828,6 @@ importers: arg: specifier: ^5.0.1 version: 5.0.2 - chalk: - specifier: ^4.1.2 - version: 4.1.2 execa: specifier: 5.1.1 version: 5.1.1 @@ -840,6 +837,9 @@ importers: log-update: specifier: ^5.0.1 version: 5.0.1 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 proxy-agent: specifier: ^6.3.0 version: 6.4.0 diff --git a/scripts/playground.js b/scripts/playground.js index b987ecaef0..20ea5648b0 100644 --- a/scripts/playground.js +++ b/scripts/playground.js @@ -4,7 +4,7 @@ let { existsSync, readdirSync } = require("node:fs"); let { cp } = require("node:fs/promises"); let path = require("node:path"); let prompts = require("prompts"); -let chalk = require("chalk"); +let pc = require("picocolors"); copyPlayground(); @@ -40,8 +40,8 @@ async function copyPlayground() { console.log( [ "", - chalk.green`Created local copy of "${templateName}"`, - chalk.green`To start playground, run:`, + pc.green(`Created local copy of "${templateName}"`), + pc.green(`To start playground, run:`), "", `cd ${relativeDestDir}`, "pnpm dev", diff --git a/scripts/version.js b/scripts/version.js index 71d96c6c16..6fc21a9a94 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -1,6 +1,6 @@ const fs = require("node:fs"); const { execSync } = require("child_process"); -const chalk = require("chalk"); +const pc = require("picocolors"); const semver = require("semver"); const { @@ -40,20 +40,18 @@ async function run() { packageName = pkg.name; pkg.version = version; }); - console.log( - chalk.green(` Updated ${packageName} to version ${version}`), - ); + console.log(pc.green(` Updated ${packageName} to version ${version}`)); } // 3. Commit and tag if (!skipGit) { execSync(`git commit --all --message="Version ${version}"`); execSync(`git tag -a -m "Version ${version}" v${version}`); - console.log(chalk.green(` Committed and tagged version ${version}`)); + console.log(pc.green(` Committed and tagged version ${version}`)); } } catch (error) { console.log(); - console.error(chalk.red(` ${error.message}`)); + console.error(pc.red(` ${error.message}`)); console.log(); return 1; }