diff --git a/package.json b/package.json index 3434260d0ff4..d82606d6fb5a 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "babel-jest": "workspace:*", "babel-loader": "^9.0.0", "camelcase": "^6.2.0", - "chalk": "^4.0.0", "dedent": "^1.0.0", "eslint": "^8.8.0", "eslint-config-prettier": "^9.0.0", @@ -66,6 +65,7 @@ "netlify-plugin-cache": "^1.0.3", "node-notifier": "^10.0.0", "p-limit": "^3.1.0", + "picocolors": "^1.0.1", "pkg-dir": "^5.0.0", "prettier": "^3.0.3", "promise": "^8.0.2", diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index 4cb0811461bc..9e1c02439a3e 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -24,8 +24,8 @@ "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^7.0.0", "babel-preset-jest": "workspace:*", - "chalk": "^4.0.0", "graceful-fs": "^4.2.9", + "picocolors": "^1.0.1", "slash": "^3.0.0" }, "devDependencies": { diff --git a/packages/babel-jest/src/index.ts b/packages/babel-jest/src/index.ts index b67b93de8781..5ef43fb6ffbc 100644 --- a/packages/babel-jest/src/index.ts +++ b/packages/babel-jest/src/index.ts @@ -13,8 +13,8 @@ import { transformSync as babelTransform, transformAsync as babelTransformAsync, } from '@babel/core'; -import chalk = require('chalk'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import slash = require('slash'); import type { TransformOptions as JestTransformOptions, @@ -38,9 +38,9 @@ function assertLoadedBabelConfig( ): asserts babelConfig { if (!babelConfig) { throw new Error( - `babel-jest: Babel ignores ${chalk.bold( + `babel-jest: Babel ignores ${pico.bold( slash(path.relative(cwd, filename)), - )} - make sure to include the file in Jest's ${chalk.bold( + )} - make sure to include the file in Jest's ${pico.bold( 'transformIgnorePatterns', )} as well.`, ); diff --git a/packages/create-jest/package.json b/packages/create-jest/package.json index 42342b7b892c..1a87cba80ce8 100644 --- a/packages/create-jest/package.json +++ b/packages/create-jest/package.json @@ -23,11 +23,11 @@ }, "dependencies": { "@jest/types": "workspace:*", - "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-config": "workspace:*", "jest-util": "workspace:*", + "picocolors": "^1.0.1", "prompts": "^2.0.1" }, "engines": { diff --git a/packages/create-jest/src/runCreate.ts b/packages/create-jest/src/runCreate.ts index fcaa3d46a3f1..0a3875445ed6 100644 --- a/packages/create-jest/src/runCreate.ts +++ b/packages/create-jest/src/runCreate.ts @@ -6,9 +6,9 @@ */ import * as path from 'path'; -import chalk = require('chalk'); import exit = require('exit'); import * as fs from 'graceful-fs'; +import picocolors = require('picocolors'); import prompts = require('prompts'); import {constants} from 'jest-config'; import {clearLine, tryRealpath} from 'jest-util'; @@ -37,9 +37,9 @@ export async function runCLI(): Promise { clearLine(process.stderr); clearLine(process.stdout); if (error instanceof Error && Boolean(error?.stack)) { - console.error(chalk.red(error.stack)); + console.error(picocolors.red(error.stack)); } else { - console.error(chalk.red(error)); + console.error(picocolors.red(String(error))); } exit(1); @@ -103,7 +103,7 @@ export async function runCreate(rootDir = process.cwd()): Promise { // Start the init process console.log(); console.log( - chalk.underline( + picocolors.underline( 'The following questions will help Jest to create a suitable configuration for your project\n', ), ); @@ -146,7 +146,7 @@ export async function runCreate(rootDir = process.cwd()): Promise { fs.writeFileSync(projectPackageJsonPath, modifiedPackageJson); console.log(''); - console.log(`✏️ Modified ${chalk.cyan(projectPackageJsonPath)}`); + console.log(`✏️ Modified ${picocolors.cyan(projectPackageJsonPath)}`); } const generatedConfig = generateConfigFile( @@ -159,6 +159,6 @@ export async function runCreate(rootDir = process.cwd()): Promise { console.log(''); console.log( - `📝 Configuration file created at ${chalk.cyan(jestConfigPath)}`, + `📝 Configuration file created at ${picocolors.cyan(jestConfigPath)}`, ); } diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index a4a5ea4c3e0b..5efee1040749 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -36,6 +36,7 @@ "jest-snapshot": "workspace:*", "jest-util": "workspace:*", "p-limit": "^3.1.0", + "picocolors": "^1.0.1", "pretty-format": "workspace:*", "pure-rand": "^6.0.0", "slash": "^3.0.0", diff --git a/packages/jest-circus/src/formatNodeAssertErrors.ts b/packages/jest-circus/src/formatNodeAssertErrors.ts index 3d617aa78475..f160d9e29c00 100644 --- a/packages/jest-circus/src/formatNodeAssertErrors.ts +++ b/packages/jest-circus/src/formatNodeAssertErrors.ts @@ -6,7 +6,7 @@ */ import {AssertionError} from 'assert'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Circus} from '@jest/types'; import { type DiffOptions, @@ -93,10 +93,10 @@ const operatorMessage = (operator: string | undefined) => { const assertThrowingMatcherHint = (operatorName: string) => operatorName - ? chalk.dim('assert') + - chalk.dim(`.${operatorName}(`) + - chalk.red('function') + - chalk.dim(')') + ? pico.dim('assert') + + pico.dim(`.${operatorName}(`) + + pico.red('function') + + pico.dim(')') : ''; const assertMatcherHint = ( @@ -108,18 +108,15 @@ const assertMatcherHint = ( if (operator === '==' && expected === true) { message = - chalk.dim('assert') + - chalk.dim('(') + - chalk.red('received') + - chalk.dim(')'); + pico.dim('assert') + pico.dim('(') + pico.red('received') + pico.dim(')'); } else if (operatorName) { message = - chalk.dim('assert') + - chalk.dim(`.${operatorName}(`) + - chalk.red('received') + - chalk.dim(', ') + - chalk.green('expected') + - chalk.dim(')'); + pico.dim('assert') + + pico.dim(`.${operatorName}(`) + + pico.red('received') + + pico.dim(', ') + + pico.green('expected') + + pico.dim(')'); } return message; @@ -141,10 +138,10 @@ function assertionErrorMessage( return ( // eslint-disable-next-line prefer-template buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset('Expected the function not to throw an error.\n') + - chalk.reset('Instead, it threw:\n') + + pico.reset('Expected the function not to throw an error.\n') + + pico.reset('Instead, it threw:\n') + ` ${printReceived(actual)}` + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + trimmedStack ); } @@ -153,16 +150,16 @@ function assertionErrorMessage( if (error.generatedMessage) { return ( buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset(error.message) + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset(error.message) + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + trimmedStack ); } return ( buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset('Expected the function to throw an error.\n') + - chalk.reset("But it didn't throw anything.") + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset('Expected the function to throw an error.\n') + + pico.reset("But it didn't throw anything.") + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + trimmedStack ); } @@ -170,7 +167,7 @@ function assertionErrorMessage( if (operatorName === 'fail') { return ( buildHintString(assertMatcherHint(operator, operatorName, expected)) + - chalk.reset(hasCustomMessage ? `Message:\n ${message}` : '') + + pico.reset(hasCustomMessage ? `Message:\n ${message}` : '') + trimmedStack ); } @@ -178,11 +175,11 @@ function assertionErrorMessage( return ( // eslint-disable-next-line prefer-template buildHintString(assertMatcherHint(operator, operatorName, expected)) + - chalk.reset(`Expected value ${operatorMessage(operator)}`) + + pico.reset(`Expected value ${operatorMessage(operator)}`) + ` ${printExpected(expected)}\n` + - chalk.reset('Received:\n') + + pico.reset('Received:\n') + ` ${printReceived(actual)}` + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + (diffString ? `\n\nDifference:\n\n${diffString}` : '') + trimmedStack ); diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index 62febb8f3fe6..1b498e9a9a10 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -18,12 +18,12 @@ "@jest/core": "workspace:*", "@jest/test-result": "workspace:*", "@jest/types": "workspace:*", - "chalk": "^4.0.0", "exit": "^0.1.2", "import-local": "^3.0.2", "jest-config": "workspace:*", "jest-util": "workspace:*", "jest-validate": "workspace:*", + "picocolors": "^1.0.1", "yargs": "^17.3.1" }, "devDependencies": { diff --git a/packages/jest-cli/src/run.ts b/packages/jest-cli/src/run.ts index b526b03f9f68..d9f1fff46396 100644 --- a/packages/jest-cli/src/run.ts +++ b/packages/jest-cli/src/run.ts @@ -6,8 +6,8 @@ */ import * as path from 'path'; -import chalk = require('chalk'); import exit = require('exit'); +import * as pico from 'picocolors'; import yargs = require('yargs'); import {getVersion, runCLI} from '@jest/core'; import type {AggregatedResult} from '@jest/test-result'; @@ -31,9 +31,9 @@ export async function run( clearLine(process.stderr); clearLine(process.stdout); if (error?.stack) { - console.error(chalk.red(error.stack)); + console.error(pico.red(error.stack)); } else { - console.error(chalk.red(error)); + console.error(pico.red(error)); } exit(1); @@ -117,7 +117,7 @@ const readResultsAndExit = ( if (globalConfig.forceExit) { if (!globalConfig.detectOpenHandles) { console.warn( - `${chalk.bold( + `${pico.bold( 'Force exiting Jest: ', )}Have you considered using \`--detectOpenHandles\` to detect ` + 'async operations that kept running after all tests finished?', @@ -132,12 +132,14 @@ const readResultsAndExit = ( const timeout = globalConfig.openHandlesTimeout; setTimeout(() => { console.warn( - chalk.yellow.bold( - `Jest did not exit ${ - timeout === 1000 ? 'one second' : `${timeout / 1000} seconds` - } after the test run has completed.\n\n'`, + pico.yellow( + pico.bold( + `Jest did not exit ${ + timeout === 1000 ? 'one second' : `${timeout / 1000} seconds` + } after the test run has completed.\n\n'`, + ), ) + - chalk.yellow( + pico.yellow( 'This usually means that there are asynchronous operations that ' + "weren't stopped in your tests. Consider running Jest with " + '`--detectOpenHandles` to troubleshoot this issue.', diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index 587135537d7d..236772c92771 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -40,7 +40,6 @@ "@jest/test-sequencer": "workspace:*", "@jest/types": "workspace:*", "babel-jest": "workspace:*", - "chalk": "^4.0.0", "ci-info": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^10.3.10", @@ -56,6 +55,7 @@ "jest-validate": "workspace:*", "micromatch": "^4.0.8", "parse-json": "^5.2.0", + "picocolors": "^1.0.1", "pretty-format": "workspace:*", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" diff --git a/packages/jest-config/src/Deprecated.ts b/packages/jest-config/src/Deprecated.ts index c319f13d2be4..cf41075d04ce 100644 --- a/packages/jest-config/src/Deprecated.ts +++ b/packages/jest-config/src/Deprecated.ts @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {DeprecatedOptions} from 'jest-validate'; function formatDeprecation(message: string): string { const lines = [ - message.replaceAll(/\*(.+?)\*/g, (_, s) => chalk.bold(`"${s}"`)), + message.replaceAll(/\*(.+?)\*/g, (_, s) => pico.bold(`"${s}"`)), '', 'Please update your configuration.', ]; @@ -19,40 +19,40 @@ function formatDeprecation(message: string): string { const deprecatedOptions: DeprecatedOptions = { browser: () => - ` Option ${chalk.bold( + ` Option ${pico.bold( '"browser"', )} has been deprecated. Please install "browser-resolve" and use the "resolver" option in Jest configuration as shown in the documentation: https://jestjs.io/docs/configuration#resolver-string`, collectCoverageOnlyFrom: (_options: { collectCoverageOnlyFrom?: Record; - }) => ` Option ${chalk.bold( + }) => ` Option ${pico.bold( '"collectCoverageOnlyFrom"', - )} was replaced by ${chalk.bold('"collectCoverageFrom"')}. + )} was replaced by ${pico.bold('"collectCoverageFrom"')}. Please update your configuration.`, - extraGlobals: (_options: {extraGlobals?: string}) => ` Option ${chalk.bold( + extraGlobals: (_options: {extraGlobals?: string}) => ` Option ${pico.bold( '"extraGlobals"', - )} was replaced by ${chalk.bold('"sandboxInjectedGlobals"')}. + )} was replaced by ${pico.bold('"sandboxInjectedGlobals"')}. Please update your configuration.`, init: () => - ` Option ${chalk.bold( + ` Option ${pico.bold( '"init"', )} has been deprecated. Please use "create-jest" package as shown in the documentation: https://jestjs.io/docs/getting-started#generate-a-basic-configuration-file`, - moduleLoader: (_options: {moduleLoader?: string}) => ` Option ${chalk.bold( + moduleLoader: (_options: {moduleLoader?: string}) => ` Option ${pico.bold( '"moduleLoader"', - )} was replaced by ${chalk.bold('"runtime"')}. + )} was replaced by ${pico.bold('"runtime"')}. Please update your configuration.`, preprocessorIgnorePatterns: (_options: { preprocessorIgnorePatterns?: Array; - }) => ` Option ${chalk.bold( + }) => ` Option ${pico.bold( '"preprocessorIgnorePatterns"', - )} was replaced by ${chalk.bold( + )} was replaced by ${pico.bold( '"transformIgnorePatterns"', )}, which support multiple preprocessors. @@ -60,9 +60,9 @@ const deprecatedOptions: DeprecatedOptions = { scriptPreprocessor: (_options: { scriptPreprocessor?: string; - }) => ` Option ${chalk.bold( + }) => ` Option ${pico.bold( '"scriptPreprocessor"', - )} was replaced by ${chalk.bold( + )} was replaced by ${pico.bold( '"transform"', )}, which support multiple preprocessors. @@ -70,9 +70,9 @@ const deprecatedOptions: DeprecatedOptions = { setupTestFrameworkScriptFile: (_options: { setupTestFrameworkScriptFile?: string; - }) => ` Option ${chalk.bold( + }) => ` Option ${pico.bold( '"setupTestFrameworkScriptFile"', - )} was replaced by configuration ${chalk.bold( + )} was replaced by configuration ${pico.bold( '"setupFilesAfterEnv"', )}, which supports multiple paths. @@ -80,7 +80,7 @@ const deprecatedOptions: DeprecatedOptions = { testPathDirs: (_options: { testPathDirs?: Array; - }) => ` Option ${chalk.bold('"testPathDirs"')} was replaced by ${chalk.bold( + }) => ` Option ${pico.bold('"testPathDirs"')} was replaced by ${pico.bold( '"roots"', )}. @@ -92,17 +92,17 @@ const deprecatedOptions: DeprecatedOptions = { 'Option *testPathPattern* was replaced by *testPathPatterns*.', ), - testURL: (_options: {testURL?: string}) => ` Option ${chalk.bold( + testURL: (_options: {testURL?: string}) => ` Option ${pico.bold( '"testURL"', - )} was replaced by passing the URL via ${chalk.bold( + )} was replaced by passing the URL via ${pico.bold( '"testEnvironmentOptions.url"', )}. Please update your configuration.`, - timers: (_options: {timers?: string}) => ` Option ${chalk.bold( + timers: (_options: {timers?: string}) => ` Option ${pico.bold( '"timers"', - )} was replaced by ${chalk.bold('"fakeTimers"')}. + )} was replaced by ${pico.bold('"fakeTimers"')}. Please update your configuration.`, }; diff --git a/packages/jest-config/src/ReporterValidationErrors.ts b/packages/jest-config/src/ReporterValidationErrors.ts index 661d91a4ce6f..889ed98030b2 100644 --- a/packages/jest-config/src/ReporterValidationErrors.ts +++ b/packages/jest-config/src/ReporterValidationErrors.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {getType} from 'jest-get-type'; import {ValidationError} from 'jest-validate'; @@ -28,9 +28,9 @@ export function createReporterError( ): ValidationError { const errorMessage = ` Reporter at index ${reporterIndex} must be of type:\n` + - ` ${chalk.bold.green(validReporterTypes.join(' or '))}\n` + + ` ${pico.bold(pico.green(validReporterTypes.join(' or ')))}\n` + ' but instead received:\n' + - ` ${chalk.bold.red(getType(reporterValue))}`; + ` ${pico.bold(pico.red(getType(reporterValue)))}`; return new ValidationError(ERROR, errorMessage, DOCUMENTATION_NOTE); } @@ -47,12 +47,14 @@ export function createArrayReporterError( ` Unexpected value for ${valueName} ` + `at index ${valueIndex} of reporter at index ${reporterIndex}\n` + ' Expected:\n' + - ` ${chalk.bold.red(expectedType)}\n` + + ` ${pico.bold(pico.red(expectedType))}\n` + ' Got:\n' + - ` ${chalk.bold.green(getType(value))}\n` + + ` ${pico.bold(pico.green(getType(value)))}\n` + ' Reporter configuration:\n' + - ` ${chalk.bold.green( - JSON.stringify(arrayReporter, null, 2).split('\n').join('\n '), + ` ${pico.bold( + pico.green( + JSON.stringify(arrayReporter, null, 2).split('\n').join('\n '), + ), )}`; return new ValidationError(ERROR, errorMessage, DOCUMENTATION_NOTE); diff --git a/packages/jest-config/src/color.ts b/packages/jest-config/src/color.ts index c9ff80d4c22f..bfbb05eed5bc 100644 --- a/packages/jest-config/src/color.ts +++ b/packages/jest-config/src/color.ts @@ -6,9 +6,8 @@ */ import {createHash} from 'crypto'; -import type {ForegroundColor} from 'chalk'; -type Color = typeof ForegroundColor; +type Color = 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white'; const colors: Array = [ 'red', diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 8523938629ca..ccc261f38869 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -6,8 +6,8 @@ */ import * as path from 'path'; -import chalk = require('chalk'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {tryRealpath} from 'jest-util'; import * as constants from './constants'; @@ -228,16 +228,16 @@ const ensureNoDuplicateConfigs = ( const {configPath} = config; if (configPathMap.has(configPath)) { - const message = `Whoops! Two projects resolved to the same config path: ${chalk.bold( + const message = `Whoops! Two projects resolved to the same config path: ${pico.bold( String(configPath), )}: - Project 1: ${chalk.bold(projects[parsedConfigs.indexOf(config)])} - Project 2: ${chalk.bold( + Project 1: ${pico.bold(projects[parsedConfigs.indexOf(config)])} + Project 2: ${pico.bold( projects[parsedConfigs.indexOf(configPathMap.get(configPath))], )} -This usually means that your ${chalk.bold( +This usually means that your ${pico.bold( '"projects"', )} config includes a directory that doesn't have any configuration recognizable by Jest. Please fix it. `; diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index a0724cc09754..e2843ab9c64e 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -8,11 +8,11 @@ import {createHash} from 'crypto'; import {totalmem} from 'os'; import * as path from 'path'; -import chalk = require('chalk'); import merge = require('deepmerge'); import {glob} from 'glob'; import {statSync} from 'graceful-fs'; import micromatch = require('micromatch'); +import * as pico from 'picocolors'; import {TestPathPatterns} from '@jest/pattern'; import type {Config} from '@jest/types'; import {replacePathSepForRegex} from 'jest-regex-util'; @@ -69,7 +69,7 @@ function verifyDirectoryExists(path: string, key: string) { if (!rootStat.isDirectory()) { throw createConfigError( - ` ${chalk.bold(path)} in the ${chalk.bold( + ` ${pico.bold(path)} in the ${pico.bold( key, )} option is not a directory.`, ); @@ -81,7 +81,7 @@ function verifyDirectoryExists(path: string, key: string) { if (error.code === 'ENOENT') { throw createConfigError( - ` Directory ${chalk.bold(path)} in the ${chalk.bold( + ` Directory ${pico.bold(path)} in the ${pico.bold( key, )} option was not found.`, ); @@ -89,7 +89,7 @@ function verifyDirectoryExists(path: string, key: string) { // Not sure in which cases `statSync` can throw, so let's just show the underlying error to the user throw createConfigError( - ` Got an error trying to find ${chalk.bold(path)} in the ${chalk.bold( + ` Got an error trying to find ${pico.bold(path)} in the ${pico.bold( key, )} option.\n\n Error was: ${error.message}`, ); @@ -149,7 +149,7 @@ const setupPreset = async ( } catch (error: any) { if (error instanceof SyntaxError || error instanceof TypeError) { throw createConfigError( - ` Preset ${chalk.bold(presetPath)} is invalid:\n\n ${ + ` Preset ${pico.bold(presetPath)} is invalid:\n\n ${ error.message }\n ${error.stack}`, ); @@ -163,24 +163,24 @@ const setupPreset = async ( if (preset) { throw createConfigError( - ` Module ${chalk.bold( + ` Module ${pico.bold( presetPath, )} should have "jest-preset.js" or "jest-preset.json" file at the root.`, ); } throw createConfigError( - ` Preset ${chalk.bold(presetPath)} not found relative to rootDir ${chalk.bold(options.rootDir)}.`, + ` Preset ${pico.bold(presetPath)} not found relative to rootDir ${pico.bold(options.rootDir)}.`, ); } throw createConfigError( - ` Missing dependency in ${chalk.bold(presetPath)}:\n\n ${ + ` Missing dependency in ${pico.bold(presetPath)}:\n\n ${ error.message }\n ${error.stack}`, ); } throw createConfigError( - ` An unknown error occurred in ${chalk.bold(presetPath)}:\n\n ${ + ` An unknown error occurred in ${pico.bold(presetPath)}:\n\n ${ error.message }\n ${error.stack}`, ); @@ -331,7 +331,7 @@ const normalizeRootDir = ( // Assert that there *is* a rootDir if (!options.rootDir) { throw createConfigError( - ` Configuration option ${chalk.bold('rootDir')} must be specified.`, + ` Configuration option ${pico.bold('rootDir')} must be specified.`, ); } options.rootDir = path.normalize(options.rootDir); @@ -410,7 +410,7 @@ const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => { // eslint-disable-next-line no-console console.log( - chalk.red( + pico.red( ` Invalid testPattern ${testPathPatterns.toPretty()} supplied. ` + 'Running all tests instead.', ), @@ -425,7 +425,7 @@ const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => { function printConfig(opts: Array) { const string = opts.map(ext => `'${ext}'`).join(', '); - return chalk.bold(`extensionsToTreatAsEsm: [${string}]`); + return pico.bold(`extensionsToTreatAsEsm: [${string}]`); } function validateExtensionsToTreatAsEsm( @@ -443,7 +443,7 @@ function validateExtensionsToTreatAsEsm( throw createConfigError( ` Option: ${printConfig( extensionsToTreatAsEsm, - )} includes a string that does not start with a period (${chalk.bold( + )} includes a string that does not start with a period (${pico.bold( '.', )}). Please change your configuration to ${printConfig( @@ -454,17 +454,17 @@ function validateExtensionsToTreatAsEsm( if (extensionsToTreatAsEsm.includes('.js')) { throw createConfigError( - ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${chalk.bold( + ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${pico.bold( "'.js'", - )} which is always inferred based on ${chalk.bold( + )} which is always inferred based on ${pico.bold( 'type', - )} in its nearest ${chalk.bold('package.json')}.`, + )} in its nearest ${pico.bold('package.json')}.`, ); } if (extensionsToTreatAsEsm.includes('.cjs')) { throw createConfigError( - ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${chalk.bold( + ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${pico.bold( "'.cjs'", )} which is always treated as CommonJS.`, ); @@ -472,7 +472,7 @@ function validateExtensionsToTreatAsEsm( if (extensionsToTreatAsEsm.includes('.mjs')) { throw createConfigError( - ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${chalk.bold( + ` Option: ${printConfig(extensionsToTreatAsEsm)} includes ${pico.bold( "'.mjs'", )} which is always treated as an ECMAScript Module.`, ); @@ -805,7 +805,7 @@ export default async function normalize( const errorMessage = " moduleFileExtensions must include 'js':\n" + ' but instead received:\n' + - ` ${chalk.bold.red(JSON.stringify(value))}`; + ` ${pico.bold(pico.red(JSON.stringify(value)))}`; // If `js` is not included, any dependency Jest itself injects into // the environment, like jasmine or sourcemap-support, will need to @@ -852,7 +852,7 @@ export default async function normalize( typeof color !== 'string' ) { const errorMessage = - ` Option "${chalk.bold('displayName')}" must be of type:\n\n` + + ` Option "${pico.bold('displayName')}" must be of type:\n\n` + ' {\n' + ' name: string;\n' + ' color: string;\n' + @@ -871,7 +871,7 @@ export default async function normalize( case 'testTimeout': { if (oldOptions[key] < 0) { throw createConfigError( - ` Option "${chalk.bold('testTimeout')}" must be a natural number.`, + ` Option "${pico.bold('testTimeout')}" must be a natural number.`, ); } @@ -1096,8 +1096,8 @@ export default async function normalize( if (newOptions.testRegex.length > 0 && options.testMatch) { throw createConfigError( - ` Configuration options ${chalk.bold('testMatch')} and` + - ` ${chalk.bold('testRegex')} cannot be used together.`, + ` Configuration options ${pico.bold('testMatch')} and` + + ` ${pico.bold('testRegex')} cannot be used together.`, ); } diff --git a/packages/jest-config/src/resolveConfigPath.ts b/packages/jest-config/src/resolveConfigPath.ts index d6cd21da82d2..97bef17df76c 100644 --- a/packages/jest-config/src/resolveConfigPath.ts +++ b/packages/jest-config/src/resolveConfigPath.ts @@ -6,8 +6,8 @@ */ import * as path from 'path'; -import chalk = require('chalk'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import slash = require('slash'); import {ValidationError} from 'jest-validate'; import { @@ -88,9 +88,9 @@ const resolveConfigPathByTraversing = ( if (!isFile(absolutePath)) { throw new ValidationError( `${BULLET}Validation Error`, - ` Configuration in ${chalk.bold(packageJson)} is not valid. ` + + ` Configuration in ${pico.bold(packageJson)} is not valid. ` + `Jest expects the string configuration to point to a file, but ${absolutePath} is not. ` + - `Please check your Jest configuration in ${chalk.bold( + `Please check your Jest configuration in ${pico.bold( packageJson, )}.`, DOCUMENTATION_NOTE, @@ -171,7 +171,7 @@ function extraIfPackageJson(configPath: string) { const makeMultipleConfigsErrorMessage = ( configPaths: Array, ): [string, string, string] => [ - `${BULLET}${chalk.bold('Multiple configurations found')}`, + `${BULLET}${pico.bold('Multiple configurations found')}`, [ ...configPaths.map( configPath => diff --git a/packages/jest-config/src/utils.ts b/packages/jest-config/src/utils.ts index 78be841f767e..4aa4a469cc99 100644 --- a/packages/jest-config/src/utils.ts +++ b/packages/jest-config/src/utils.ts @@ -6,7 +6,7 @@ */ import * as path from 'path'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import Resolver from 'jest-resolve'; import {ValidationError} from 'jest-validate'; @@ -17,8 +17,8 @@ type ResolveOptions = { optional?: boolean; }; -export const BULLET: string = chalk.bold('\u25CF '); -export const DOCUMENTATION_NOTE = ` ${chalk.bold( +export const BULLET: string = pico.bold('\u25CF '); +export const DOCUMENTATION_NOTE = ` ${pico.bold( 'Configuration Documentation:', )} https://jestjs.io/docs/configuration @@ -41,10 +41,10 @@ export const resolve = ( if (!module && !optional) { throw createValidationError( - ` Module ${chalk.bold(filePath)} in the ${chalk.bold( + ` Module ${pico.bold(filePath)} in the ${pico.bold( key, )} option was not found. - ${chalk.bold('')} is: ${rootDir}`, + ${pico.bold('')} is: ${rootDir}`, ); } /// can cast as string since nulls will be thrown diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index e387505e1034..e3c93966ea9a 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -21,9 +21,9 @@ "dependencies": { "@jest/types": "workspace:*", "@types/node": "*", - "chalk": "^4.0.0", "jest-message-util": "workspace:*", "jest-util": "workspace:*", + "picocolors": "^1.0.1", "slash": "^3.0.0" }, "devDependencies": { diff --git a/packages/jest-console/src/BufferedConsole.ts b/packages/jest-console/src/BufferedConsole.ts index 21162ac14289..b5cbc3ef64b2 100644 --- a/packages/jest-console/src/BufferedConsole.ts +++ b/packages/jest-console/src/BufferedConsole.ts @@ -8,7 +8,7 @@ import {AssertionError, strict as assert} from 'assert'; import {Console} from 'console'; import {type InspectOptions, format, formatWithOptions, inspect} from 'util'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {ErrorWithStack, formatTime, invariant} from 'jest-util'; import type { ConsoleBuffer, @@ -116,7 +116,7 @@ export default class BufferedConsole extends Console { this._groupDepth++; if (title != null || rest.length > 0) { - this._log('group', chalk.bold(format(title, ...rest))); + this._log('group', pico.bold(format(title, ...rest))); } } @@ -124,7 +124,7 @@ export default class BufferedConsole extends Console { this._groupDepth++; if (title != null || rest.length > 0) { - this._log('groupCollapsed', chalk.bold(format(title, ...rest))); + this._log('groupCollapsed', pico.bold(format(title, ...rest))); } } diff --git a/packages/jest-console/src/CustomConsole.ts b/packages/jest-console/src/CustomConsole.ts index 41457aa7fc77..6460251eb6a2 100644 --- a/packages/jest-console/src/CustomConsole.ts +++ b/packages/jest-console/src/CustomConsole.ts @@ -9,7 +9,7 @@ import {AssertionError, strict as assert} from 'assert'; import {Console} from 'console'; import type {WriteStream} from 'tty'; import {type InspectOptions, format, formatWithOptions, inspect} from 'util'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {clearLine, formatTime} from 'jest-util'; import type {LogCounters, LogMessage, LogTimers, LogType} from './types'; @@ -95,7 +95,7 @@ export default class CustomConsole extends Console { this._groupDepth++; if (title != null || args.length > 0) { - this._log('group', chalk.bold(format(title, ...args))); + this._log('group', pico.bold(format(title, ...args))); } } @@ -103,7 +103,7 @@ export default class CustomConsole extends Console { this._groupDepth++; if (title != null || args.length > 0) { - this._log('groupCollapsed', chalk.bold(format(title, ...args))); + this._log('groupCollapsed', pico.bold(format(title, ...args))); } } diff --git a/packages/jest-console/src/__tests__/CustomConsole.test.ts b/packages/jest-console/src/__tests__/CustomConsole.test.ts index 84b71ece4a39..8e44a8dbef32 100644 --- a/packages/jest-console/src/__tests__/CustomConsole.test.ts +++ b/packages/jest-console/src/__tests__/CustomConsole.test.ts @@ -7,7 +7,7 @@ import {Writable} from 'stream'; import type {WriteStream} from 'tty'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import CustomConsole from '../CustomConsole'; describe('CustomConsole', () => { @@ -142,9 +142,9 @@ describe('CustomConsole', () => { _console.group('second'); _console.log('there'); - expect(_stdout).toBe(` ${chalk.bold('first')} + expect(_stdout).toBe(` ${pico.bold('first')} hey - ${chalk.bold('second')} + ${pico.bold('second')} there `); }); diff --git a/packages/jest-console/src/__tests__/bufferedConsole.test.ts b/packages/jest-console/src/__tests__/bufferedConsole.test.ts index bf6560c73455..042e922ef0e0 100644 --- a/packages/jest-console/src/__tests__/bufferedConsole.test.ts +++ b/packages/jest-console/src/__tests__/bufferedConsole.test.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import BufferedConsole from '../BufferedConsole'; describe('CustomConsole', () => { @@ -104,9 +104,9 @@ describe('CustomConsole', () => { _console.group('second'); _console.log('there'); - expect(stdout()).toBe(` ${chalk.bold('first')} + expect(stdout()).toBe(` ${pico.bold('first')} hey - ${chalk.bold('second')} + ${pico.bold('second')} there`); }); diff --git a/packages/jest-console/src/getConsoleOutput.ts b/packages/jest-console/src/getConsoleOutput.ts index 66d6ed8e4ef7..de1198dcaa9f 100644 --- a/packages/jest-console/src/getConsoleOutput.ts +++ b/packages/jest-console/src/getConsoleOutput.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import { type StackTraceConfig, @@ -34,13 +34,13 @@ export default function getConsoleOutput( let noCodeFrame = true; if (type === 'warn') { - message = chalk.yellow(message); - typeMessage = chalk.yellow(typeMessage); + message = pico.yellow(message); + typeMessage = pico.yellow(typeMessage); noStackTrace = globalConfig?.noStackTrace ?? false; noCodeFrame = false; } else if (type === 'error') { - message = chalk.red(message); - typeMessage = chalk.red(typeMessage); + message = pico.red(message); + typeMessage = pico.red(typeMessage); noStackTrace = globalConfig?.noStackTrace ?? false; noCodeFrame = false; } @@ -53,8 +53,8 @@ export default function getConsoleOutput( const formattedStackTrace = formatStackTrace(origin, config, options); return `${ - output + TITLE_INDENT + chalk.dim(typeMessage) - }\n${message.trimEnd()}\n${chalk.dim(formattedStackTrace.trimEnd())}\n\n`; + output + TITLE_INDENT + pico.dim(typeMessage) + }\n${message.trimEnd()}\n${pico.dim(formattedStackTrace.trimEnd())}\n\n`; }, ''); return `${logEntries.trimEnd()}\n`; diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index c66b856b159b..a66aafe18c9c 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -22,7 +22,6 @@ "@jest/types": "workspace:*", "@types/node": "*", "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", "ci-info": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", @@ -40,6 +39,7 @@ "jest-validate": "workspace:*", "jest-watcher": "workspace:*", "micromatch": "^4.0.8", + "picocolors": "^1.0.1", "pretty-format": "workspace:*", "slash": "^3.0.0", "strip-ansi": "^6.0.0" diff --git a/packages/jest-core/src/FailedTestsInteractiveMode.ts b/packages/jest-core/src/FailedTestsInteractiveMode.ts index 07caa7876572..ec7c5595d8d5 100644 --- a/packages/jest-core/src/FailedTestsInteractiveMode.ts +++ b/packages/jest-core/src/FailedTestsInteractiveMode.ts @@ -6,7 +6,7 @@ */ import ansiEscapes = require('ansi-escapes'); -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {AggregatedResult, AssertionLocation} from '@jest/test-result'; import {pluralize, specialChars} from 'jest-util'; import {KEYS} from 'jest-watcher'; @@ -16,10 +16,10 @@ type RunnerUpdateFunction = (failure?: AssertionLocation) => void; const {ARROW, CLEAR} = specialChars; function describeKey(key: string, description: string) { - return `${chalk.dim(`${ARROW}Press`)} ${key} ${chalk.dim(description)}`; + return `${pico.dim(`${ARROW}Press`)} ${key} ${pico.dim(description)}`; } -const TestProgressLabel = chalk.bold('Interactive Test Progress'); +const TestProgressLabel = pico.bold('Interactive Test Progress'); export default class FailedTestsInteractiveMode { private _isActive = false; @@ -105,7 +105,7 @@ export default class FailedTestsInteractiveMode { this._pipe.write(CLEAR); const messages: Array = [ - chalk.bold('Watch Usage'), + pico.bold('Watch Usage'), describeKey('Enter', 'to return to watch mode.'), ]; @@ -118,8 +118,8 @@ export default class FailedTestsInteractiveMode { let stats = `${pluralize('test', this._countPaths)} reviewed`; if (this._skippedNum > 0) { - const skippedText = chalk.bold.yellow( - `${pluralize('test', this._skippedNum)} skipped`, + const skippedText = pico.bold( + pico.yellow(`${pluralize('test', this._skippedNum)} skipped`), ); stats = `${stats}, ${skippedText}`; @@ -129,7 +129,7 @@ export default class FailedTestsInteractiveMode { TestProgressLabel, `${ARROW}${stats}`, '\n', - chalk.bold('Watch Usage'), + pico.bold('Watch Usage'), describeKey('r', 'to restart Interactive Mode.'), describeKey('q', 'to quit Interactive Mode.'), describeKey('Enter', 'to return to watch mode.'), @@ -146,8 +146,8 @@ export default class FailedTestsInteractiveMode { let stats = `${pluralize('test', numRemaining)} remaining`; if (this._skippedNum > 0) { - const skippedText = chalk.bold.yellow( - `${pluralize('test', this._skippedNum)} skipped`, + const skippedText = pico.bold( + pico.yellow(`${pluralize('test', this._skippedNum)} skipped`), ); stats = `${stats}, ${skippedText}`; @@ -157,7 +157,7 @@ export default class FailedTestsInteractiveMode { TestProgressLabel, `${ARROW}${stats}`, '\n', - chalk.bold('Watch Usage'), + pico.bold('Watch Usage'), describeKey('s', 'to skip the current test.'), describeKey('q', 'to quit Interactive Mode.'), describeKey('Enter', 'to return to watch mode.'), diff --git a/packages/jest-core/src/SnapshotInteractiveMode.ts b/packages/jest-core/src/SnapshotInteractiveMode.ts index 0f9ec0a886b5..b1e9a8839f9c 100644 --- a/packages/jest-core/src/SnapshotInteractiveMode.ts +++ b/packages/jest-core/src/SnapshotInteractiveMode.ts @@ -6,7 +6,7 @@ */ import ansiEscapes = require('ansi-escapes'); -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {AggregatedResult, AssertionLocation} from '@jest/test-result'; import {pluralize, specialChars} from 'jest-util'; import {KEYS} from 'jest-watcher'; @@ -48,37 +48,35 @@ export default class SnapshotInteractiveMode { const numPass = this._countPaths - this._testAssertions.length; const numRemaining = this._countPaths - numPass - this._skippedNum; - let stats = chalk.bold.dim( - `${pluralize('snapshot', numRemaining)} remaining`, + let stats = pico.bold( + pico.dim(`${pluralize('snapshot', numRemaining)} remaining`), ); if (numPass) { - stats += `, ${chalk.bold.green( - `${pluralize('snapshot', numPass)} updated`, + stats += `, ${pico.bold( + pico.green(`${pluralize('snapshot', numPass)} updated`), )}`; } if (this._skippedNum) { - stats += `, ${chalk.bold.yellow( - `${pluralize('snapshot', this._skippedNum)} skipped`, + stats += `, ${pico.bold( + pico.yellow(`${pluralize('snapshot', this._skippedNum)} skipped`), )}`; } const messages = [ - `\n${chalk.bold('Interactive Snapshot Progress')}`, + `\n${pico.bold('Interactive Snapshot Progress')}`, ARROW + stats, - `\n${chalk.bold('Watch Usage')}`, + `\n${pico.bold('Watch Usage')}`, - `${chalk.dim(`${ARROW}Press `)}u${chalk.dim( + `${pico.dim(`${ARROW}Press `)}u${pico.dim( ' to update failing snapshots for this test.', )}`, - `${chalk.dim(`${ARROW}Press `)}s${chalk.dim( - ' to skip the current test.', - )}`, + `${pico.dim(`${ARROW}Press `)}s${pico.dim(' to skip the current test.')}`, - `${chalk.dim(`${ARROW}Press `)}q${chalk.dim( + `${pico.dim(`${ARROW}Press `)}q${pico.dim( ' to quit Interactive Snapshot Mode.', )}`, - `${chalk.dim(`${ARROW}Press `)}Enter${chalk.dim( + `${pico.dim(`${ARROW}Press `)}Enter${pico.dim( ' to trigger a test run.', )}`, ]; @@ -90,29 +88,29 @@ export default class SnapshotInteractiveMode { this._pipe.write(CLEAR); const numPass = this._countPaths - this._testAssertions.length; - let stats = chalk.bold.dim( - `${pluralize('snapshot', this._countPaths)} reviewed`, + let stats = pico.bold( + pico.dim(`${pluralize('snapshot', this._countPaths)} reviewed`), ); if (numPass) { - stats += `, ${chalk.bold.green( - `${pluralize('snapshot', numPass)} updated`, + stats += `, ${pico.bold( + pico.green(`${pluralize('snapshot', numPass)} updated`), )}`; } if (this._skippedNum) { - stats += `, ${chalk.bold.yellow( - `${pluralize('snapshot', this._skippedNum)} skipped`, + stats += `, ${pico.bold( + pico.yellow(`${pluralize('snapshot', this._skippedNum)} skipped`), )}`; } const messages = [ - `\n${chalk.bold('Interactive Snapshot Result')}`, + `\n${pico.bold('Interactive Snapshot Result')}`, ARROW + stats, - `\n${chalk.bold('Watch Usage')}`, + `\n${pico.bold('Watch Usage')}`, - `${chalk.dim(`${ARROW}Press `)}r${chalk.dim( + `${pico.dim(`${ARROW}Press `)}r${pico.dim( ' to restart Interactive Snapshot Mode.', )}`, - `${chalk.dim(`${ARROW}Press `)}q${chalk.dim( + `${pico.dim(`${ARROW}Press `)}q${pico.dim( ' to quit Interactive Snapshot Mode.', )}`, ]; @@ -124,20 +122,20 @@ export default class SnapshotInteractiveMode { this._pipe.write(CLEAR); const numPass = this._countPaths - this._testAssertions.length; - let stats = chalk.bold.dim( - `${pluralize('snapshot', this._countPaths)} reviewed`, + let stats = pico.bold( + pico.dim(`${pluralize('snapshot', this._countPaths)} reviewed`), ); if (numPass) { - stats += `, ${chalk.bold.green( - `${pluralize('snapshot', numPass)} updated`, + stats += `, ${pico.bold( + pico.green(`${pluralize('snapshot', numPass)} updated`), )}`; } const messages = [ - `\n${chalk.bold('Interactive Snapshot Result')}`, + `\n${pico.bold('Interactive Snapshot Result')}`, ARROW + stats, - `\n${chalk.bold('Watch Usage')}`, + `\n${pico.bold('Watch Usage')}`, - `${chalk.dim(`${ARROW}Press `)}Enter${chalk.dim( + `${pico.dim(`${ARROW}Press `)}Enter${pico.dim( ' to return to watch mode.', )}`, ]; diff --git a/packages/jest-core/src/cli/index.ts b/packages/jest-core/src/cli/index.ts index ca35c0556d53..a7d4d40ab98f 100644 --- a/packages/jest-core/src/cli/index.ts +++ b/packages/jest-core/src/cli/index.ts @@ -7,9 +7,9 @@ import {performance} from 'perf_hooks'; import type {WriteStream} from 'tty'; -import chalk = require('chalk'); import exit = require('exit'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import {CustomConsole} from '@jest/console'; import type {AggregatedResult, TestContext} from '@jest/test-result'; import type {Config} from '@jest/types'; @@ -129,7 +129,7 @@ export async function runCLI( const openHandlesString = pluralize('open handle', formatted.length, 's'); const message = - chalk.red( + pico.red( `\nJest has detected the following ${openHandlesString} potentially keeping Jest from exiting:\n\n`, ) + formatted.join('\n\n'); diff --git a/packages/jest-core/src/getChangedFilesPromise.ts b/packages/jest-core/src/getChangedFilesPromise.ts index 252eb67ad087..3b512e6ba7e3 100644 --- a/packages/jest-core/src/getChangedFilesPromise.ts +++ b/packages/jest-core/src/getChangedFilesPromise.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import { type ChangedFilesPromise, @@ -31,7 +31,7 @@ export default function getChangedFilesPromise( .filter(line => !line.includes('Command failed:')) .join('\n'); - console.error(chalk.red(`\n\n${message}`)); + console.error(pico.red(`\n\n${message}`)); process.exit(1); }); diff --git a/packages/jest-core/src/getNoTestFound.ts b/packages/jest-core/src/getNoTestFound.ts index 7d6ae6e5e7bb..4d399cd18561 100644 --- a/packages/jest-core/src/getNoTestFound.ts +++ b/packages/jest-core/src/getNoTestFound.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {pluralize} from 'jest-util'; import type {TestRunData} from './types'; @@ -26,15 +26,15 @@ export default function getNoTestFound( .map(p => `"${p}"`) .join(', ')}`; } else { - dataMessage = `Pattern: ${chalk.yellow( + dataMessage = `Pattern: ${pico.yellow( globalConfig.testPathPatterns.toPretty(), )} - 0 matches`; } if (willExitWith0) { return ( - `${chalk.bold('No tests found, exiting with code 0')}\n` + - `In ${chalk.bold(globalConfig.rootDir)}` + + `${pico.bold('No tests found, exiting with code 0')}\n` + + `In ${pico.bold(globalConfig.rootDir)}` + '\n' + ` ${pluralize('file', testFiles, 's')} checked across ${pluralize( 'project', @@ -46,10 +46,10 @@ export default function getNoTestFound( } return ( - `${chalk.bold('No tests found, exiting with code 1')}\n` + + `${pico.bold('No tests found, exiting with code 1')}\n` + 'Run with `--passWithNoTests` to exit with code 0' + '\n' + - `In ${chalk.bold(globalConfig.rootDir)}` + + `In ${pico.bold(globalConfig.rootDir)}` + '\n' + ` ${pluralize('file', testFiles, 's')} checked across ${pluralize( 'project', diff --git a/packages/jest-core/src/getNoTestFoundFailed.ts b/packages/jest-core/src/getNoTestFoundFailed.ts index acab5c62a8af..f74531521c64 100644 --- a/packages/jest-core/src/getNoTestFoundFailed.ts +++ b/packages/jest-core/src/getNoTestFoundFailed.ts @@ -5,16 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {isInteractive} from 'jest-util'; export default function getNoTestFoundFailed( globalConfig: Config.GlobalConfig, ): string { - let msg = chalk.bold('No failed test found.'); + let msg = pico.bold('No failed test found.'); if (isInteractive) { - msg += chalk.dim( + msg += pico.dim( `\n${ globalConfig.watch ? 'Press `f` to quit "only failed tests" mode.' diff --git a/packages/jest-core/src/getNoTestFoundPassWithNoTests.ts b/packages/jest-core/src/getNoTestFoundPassWithNoTests.ts index 768a18e96f61..840d050f2faf 100644 --- a/packages/jest-core/src/getNoTestFoundPassWithNoTests.ts +++ b/packages/jest-core/src/getNoTestFoundPassWithNoTests.ts @@ -5,8 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; export default function getNoTestFoundPassWithNoTests(): string { - return chalk.bold('No tests found, exiting with code 0'); + return pico.bold('No tests found, exiting with code 0'); } diff --git a/packages/jest-core/src/getNoTestFoundRelatedToChangedFiles.ts b/packages/jest-core/src/getNoTestFoundRelatedToChangedFiles.ts index 995153f2f25b..ca44a27f78fd 100644 --- a/packages/jest-core/src/getNoTestFoundRelatedToChangedFiles.ts +++ b/packages/jest-core/src/getNoTestFoundRelatedToChangedFiles.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {isInteractive} from 'jest-util'; @@ -15,10 +15,10 @@ export default function getNoTestFoundRelatedToChangedFiles( const ref = globalConfig.changedSince ? `"${globalConfig.changedSince}"` : 'last commit'; - let msg = chalk.bold(`No tests found related to files changed since ${ref}.`); + let msg = pico.bold(`No tests found related to files changed since ${ref}.`); if (isInteractive) { - msg += chalk.dim( + msg += pico.dim( `\n${ globalConfig.watch ? 'Press `a` to run all tests, or run Jest with `--watchAll`.' diff --git a/packages/jest-core/src/getNoTestFoundVerbose.ts b/packages/jest-core/src/getNoTestFoundVerbose.ts index bd5f2ab355b4..7bda26329198 100644 --- a/packages/jest-core/src/getNoTestFoundVerbose.ts +++ b/packages/jest-core/src/getNoTestFoundVerbose.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {pluralize} from 'jest-util'; import type {Stats, TestRunData} from './types'; @@ -29,7 +29,7 @@ export default function getNoTestFoundVerbose( ? value.join(', ') : String(value); const matches = pluralize('match', stats[key] || 0, 'es'); - return ` ${key}: ${chalk.yellow(valueAsString)} - ${matches}`; + return ` ${key}: ${pico.yellow(valueAsString)} - ${matches}`; } return null; }) @@ -37,7 +37,7 @@ export default function getNoTestFoundVerbose( .join('\n'); return testRun.matches.total - ? `In ${chalk.bold(config.rootDir)}\n` + + ? `In ${pico.bold(config.rootDir)}\n` + ` ${pluralize( 'file', testRun.matches.total || 0, @@ -56,19 +56,19 @@ export default function getNoTestFoundVerbose( .map(p => `"${p}"`) .join(', ')}`; } else { - dataMessage = `Pattern: ${chalk.yellow( + dataMessage = `Pattern: ${pico.yellow( globalConfig.testPathPatterns.toPretty(), )} - 0 matches`; } if (willExitWith0) { - return `${chalk.bold( + return `${pico.bold( 'No tests found, exiting with code 0', )}\n${individualResults.join('\n')}\n${dataMessage}`; } return ( - `${chalk.bold('No tests found, exiting with code 1')}\n` + + `${pico.bold('No tests found, exiting with code 1')}\n` + 'Run with `--passWithNoTests` to exit with code 0' + `\n${individualResults.join('\n')}\n${dataMessage}` ); diff --git a/packages/jest-core/src/getProjectNamesMissingWarning.ts b/packages/jest-core/src/getProjectNamesMissingWarning.ts index 6a6e1cf145aa..c3da545fac0d 100644 --- a/packages/jest-core/src/getProjectNamesMissingWarning.ts +++ b/packages/jest-core/src/getProjectNamesMissingWarning.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import getProjectDisplayName from './getProjectDisplayName'; @@ -29,7 +29,7 @@ export default function getProjectNamesMissingWarning( if (opts.ignoreProjects) { args.push('--ignoreProjects'); } - return chalk.yellow( + return pico.yellow( `You provided values for ${args.join(' and ')} but ${ numberOfProjectsWithoutAName === 1 ? 'a project does not have a name' diff --git a/packages/jest-core/src/getSelectProjectsMessage.ts b/packages/jest-core/src/getSelectProjectsMessage.ts index 0d67295c32fb..1698db1e70bc 100644 --- a/packages/jest-core/src/getSelectProjectsMessage.ts +++ b/packages/jest-core/src/getSelectProjectsMessage.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import getProjectDisplayName from './getProjectDisplayName'; @@ -27,21 +27,21 @@ function getNoSelectionWarning(opts: { selectProjects: Array | undefined; }): string { if (opts.ignoreProjects && opts.selectProjects) { - return chalk.yellow( + return pico.yellow( 'You provided values for --selectProjects and --ignoreProjects, but no projects were found matching the selection.\n' + 'Are you ignoring all the selected projects?\n', ); } else if (opts.ignoreProjects) { - return chalk.yellow( + return pico.yellow( 'You provided values for --ignoreProjects, but no projects were found matching the selection.\n' + 'Are you ignoring all projects?\n', ); } else if (opts.selectProjects) { - return chalk.yellow( + return pico.yellow( 'You provided values for --selectProjects but no projects were found matching the selection.\n', ); } else { - return chalk.yellow('No projects were found.\n'); + return pico.yellow('No projects were found.\n'); } } @@ -51,7 +51,7 @@ function getProjectsRunningMessage( if (projectConfigs.length === 1) { const name = getProjectDisplayName(projectConfigs[0]) ?? ''; - return `Running one project: ${chalk.bold(name)}\n`; + return `Running one project: ${pico.bold(name)}\n`; } const projectsList = projectConfigs .map(getProjectNameListElement) @@ -64,6 +64,6 @@ function getProjectNameListElement( projectConfig: Config.ProjectConfig, ): string { const name = getProjectDisplayName(projectConfig); - const elementContent = name ? chalk.bold(name) : ''; + const elementContent = name ? pico.bold(name) : ''; return `- ${elementContent}`; } diff --git a/packages/jest-core/src/lib/activeFiltersMessage.ts b/packages/jest-core/src/lib/activeFiltersMessage.ts index c1c9230c6544..58c1142fcde7 100644 --- a/packages/jest-core/src/lib/activeFiltersMessage.ts +++ b/packages/jest-core/src/lib/activeFiltersMessage.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Config} from '@jest/types'; import {isNonNullable} from 'jest-util'; @@ -15,16 +15,16 @@ const activeFilters = (globalConfig: Config.GlobalConfig): string => { if (testNamePattern || testPathPatterns.isSet()) { const filters = [ testPathPatterns.isSet() - ? chalk.dim('filename ') + chalk.yellow(testPathPatterns.toPretty()) + ? pico.dim('filename ') + pico.yellow(testPathPatterns.toPretty()) : null, testNamePattern - ? chalk.dim('test name ') + chalk.yellow(`/${testNamePattern}/`) + ? pico.dim('test name ') + pico.yellow(`/${testNamePattern}/`) : null, ] .filter(isNonNullable) .join(', '); - const messages = `\n${chalk.bold('Active Filters: ')}${filters}`; + const messages = `\n${pico.bold('Active Filters: ')}${filters}`; return messages; } diff --git a/packages/jest-core/src/lib/handleDeprecationWarnings.ts b/packages/jest-core/src/lib/handleDeprecationWarnings.ts index f56c79f1509d..930a16cc30b8 100644 --- a/packages/jest-core/src/lib/handleDeprecationWarnings.ts +++ b/packages/jest-core/src/lib/handleDeprecationWarnings.ts @@ -6,7 +6,7 @@ */ import type {ReadStream, WriteStream} from 'tty'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {KEYS} from 'jest-watcher'; export default function handleDeprecationWarnings( @@ -16,9 +16,9 @@ export default function handleDeprecationWarnings( return new Promise((resolve, reject) => { if (typeof stdin.setRawMode === 'function') { const messages = [ - chalk.red('There are deprecation warnings.\n'), - `${chalk.dim(' \u203A Press ')}Enter${chalk.dim(' to continue.')}`, - `${chalk.dim(' \u203A Press ')}Esc${chalk.dim(' to exit.')}`, + pico.red('There are deprecation warnings.\n'), + `${pico.dim(' \u203A Press ')}Enter${pico.dim(' to continue.')}`, + `${pico.dim(' \u203A Press ')}Esc${pico.dim(' to exit.')}`, ]; pipe.write(messages.join('\n')); diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index 28d97d83c222..cc0b3cff844d 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import {performance} from 'perf_hooks'; import type {WriteStream} from 'tty'; -import chalk = require('chalk'); import exit = require('exit'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import {CustomConsole} from '@jest/console'; import { type AggregatedResult, @@ -178,7 +178,7 @@ export default async function runJest({ ).every(scm => repos[scm].size === 0); if (noSCM) { process.stderr.write( - `\n${chalk.bold( + `\n${pico.bold( '--watch', )} is not supported without git/hg, please use --watchAll\n`, ); diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 5831baf5ca06..9c2f4dac8ba2 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -19,9 +19,9 @@ "./package.json": "./package.json" }, "dependencies": { - "chalk": "^4.0.0", "diff-sequences": "workspace:*", "jest-get-type": "workspace:*", + "picocolors": "^1.0.1", "pretty-format": "workspace:*" }, "devDependencies": { diff --git a/packages/jest-diff/src/__tests__/diff.test.ts b/packages/jest-diff/src/__tests__/diff.test.ts index 64347ca05547..fc155a93bb62 100644 --- a/packages/jest-diff/src/__tests__/diff.test.ts +++ b/packages/jest-diff/src/__tests__/diff.test.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import stripAnsi = require('strip-ansi'); import {alignedAnsiStyleSerializer} from '@jest/test-utils'; import {diff} from '../'; @@ -718,7 +718,7 @@ describe('context', () => { expand: false, }; if (!validContextLines) { - options.patchColor = chalk.dim; + options.patchColor = pico.dim; } const result = diff( @@ -940,9 +940,9 @@ describe('options 7980', () => { const options = { aAnnotation: 'Original', - aColor: chalk.red, + aColor: pico.red, bAnnotation: 'Modified', - bColor: chalk.green, + bColor: pico.green, }; test('diff', () => { @@ -974,8 +974,8 @@ describe('options', () => { describe('change color', () => { const options = { - changeColor: chalk.bold, - commonColor: chalk.yellow, + changeColor: pico.bold, + commonColor: pico.yellow, }; test('diffStringsUnified', () => { @@ -1091,7 +1091,7 @@ describe('options', () => { test('diff yellowish common', () => { const options = { - commonLineTrailingSpaceColor: chalk.bgYellow, + commonLineTrailingSpaceColor: pico.bgYellow, }; expect(diff(aTrailingSpaces, bTrailingSpaces, options)).toMatchSnapshot(); diff --git a/packages/jest-diff/src/index.ts b/packages/jest-diff/src/index.ts index 4b87be7d720f..c5f3ec8aabb0 100644 --- a/packages/jest-diff/src/index.ts +++ b/packages/jest-diff/src/index.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {getType} from 'jest-get-type'; import { type PrettyFormatOptions, @@ -85,8 +85,8 @@ export function diff(a: any, b: any, options?: DiffOptions): string | null { if (expectedType !== getType(b)) { return ( ' Comparing two different types of values.' + - ` Expected ${chalk.green(expectedType)} but ` + - `received ${chalk.red(getType(b))}.` + ` Expected ${pico.green(expectedType)} but ` + + `received ${pico.red(getType(b))}.` ); } diff --git a/packages/jest-diff/src/normalizeDiffOptions.ts b/packages/jest-diff/src/normalizeDiffOptions.ts index 3072bea01597..9a536722cf20 100644 --- a/packages/jest-diff/src/normalizeDiffOptions.ts +++ b/packages/jest-diff/src/normalizeDiffOptions.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {CompareKeys} from 'pretty-format'; import type {DiffOptions, DiffOptionsNormalized} from './types'; @@ -15,14 +15,14 @@ const DIFF_CONTEXT_DEFAULT = 5; const OPTIONS_DEFAULT: DiffOptionsNormalized = { aAnnotation: 'Expected', - aColor: chalk.green, + aColor: pico.green, aIndicator: '-', bAnnotation: 'Received', - bColor: chalk.red, + bColor: pico.red, bIndicator: '+', - changeColor: chalk.inverse, + changeColor: pico.inverse, changeLineTrailingSpaceColor: noColor, - commonColor: chalk.dim, + commonColor: pico.dim, commonIndicator: ' ', commonLineTrailingSpaceColor: noColor, compareKeys: undefined, @@ -31,7 +31,7 @@ const OPTIONS_DEFAULT: DiffOptionsNormalized = { expand: true, includeChangeCounts: false, omitAnnotationLines: false, - patchColor: chalk.yellow, + patchColor: pico.yellow, }; const getCompareKeys = (compareKeys?: CompareKeys): CompareKeys => diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index 891375ef54a9..2454fabe5710 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -28,9 +28,9 @@ "license": "MIT", "dependencies": { "@jest/types": "workspace:*", - "chalk": "^4.0.0", "jest-get-type": "workspace:*", "jest-util": "workspace:*", + "picocolors": "^1.0.1", "pretty-format": "workspace:*" }, "engines": { diff --git a/packages/jest-each/src/validation.ts b/packages/jest-each/src/validation.ts index ffb770ca4e51..0c54ad49c4c9 100644 --- a/packages/jest-each/src/validation.ts +++ b/packages/jest-each/src/validation.ts @@ -6,14 +6,14 @@ * */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import type {Global} from '@jest/types'; import {format as pretty} from 'pretty-format'; type TemplateData = Global.TemplateData; -const EXPECTED_COLOR = chalk.green; -const RECEIVED_COLOR = chalk.red; +const EXPECTED_COLOR = pico.green; +const RECEIVED_COLOR = pico.red; export const validateArrayTable = (table: unknown): void => { if (!Array.isArray(table)) { diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index a013338e3801..899deb1e3b68 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -25,7 +25,6 @@ "@jest/test-result": "workspace:*", "@jest/types": "workspace:*", "@types/node": "*", - "chalk": "^4.0.0", "co": "^4.6.0", "is-generator-fn": "^2.0.0", "jest-each": "workspace:*", @@ -35,6 +34,7 @@ "jest-snapshot": "workspace:*", "jest-util": "workspace:*", "p-limit": "^3.1.0", + "picocolors": "^1.0.1", "pretty-format": "workspace:*" }, "devDependencies": { diff --git a/packages/jest-jasmine2/src/assertionErrorMessage.ts b/packages/jest-jasmine2/src/assertionErrorMessage.ts index 5251719466f5..c6727505adda 100644 --- a/packages/jest-jasmine2/src/assertionErrorMessage.ts +++ b/packages/jest-jasmine2/src/assertionErrorMessage.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import { type DiffOptions, diff, @@ -56,10 +56,10 @@ const operatorMessage = (operator: string | null) => { const assertThrowingMatcherHint = (operatorName: string) => operatorName - ? chalk.dim('assert') + - chalk.dim(`.${operatorName}(`) + - chalk.red('function') + - chalk.dim(')') + ? pico.dim('assert') + + pico.dim(`.${operatorName}(`) + + pico.red('function') + + pico.dim(')') : ''; const assertMatcherHint = ( @@ -71,18 +71,15 @@ const assertMatcherHint = ( if (operator === '==' && expected === true) { message = - chalk.dim('assert') + - chalk.dim('(') + - chalk.red('received') + - chalk.dim(')'); + pico.dim('assert') + pico.dim('(') + pico.red('received') + pico.dim(')'); } else if (operatorName) { message = - chalk.dim('assert') + - chalk.dim(`.${operatorName}(`) + - chalk.red('received') + - chalk.dim(', ') + - chalk.green('expected') + - chalk.dim(')'); + pico.dim('assert') + + pico.dim(`.${operatorName}(`) + + pico.red('received') + + pico.dim(', ') + + pico.green('expected') + + pico.dim(')'); } return message; @@ -103,9 +100,9 @@ function assertionErrorMessage( if (operatorName === 'doesNotThrow') { return `${ buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset('Expected the function not to throw an error.\n') + - chalk.reset('Instead, it threw:\n') - } ${printReceived(actual)}${chalk.reset( + pico.reset('Expected the function not to throw an error.\n') + + pico.reset('Instead, it threw:\n') + } ${printReceived(actual)}${pico.reset( hasCustomMessage ? `\n\nMessage:\n ${message}` : '', )}${trimmedStack}`; } @@ -114,16 +111,16 @@ function assertionErrorMessage( if (error.generatedMessage) { return ( buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset(error.message) + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset(error.message) + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + trimmedStack ); } return ( buildHintString(assertThrowingMatcherHint(operatorName)) + - chalk.reset('Expected the function to throw an error.\n') + - chalk.reset("But it didn't throw anything.") + - chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + + pico.reset('Expected the function to throw an error.\n') + + pico.reset("But it didn't throw anything.") + + pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '') + trimmedStack ); } @@ -131,17 +128,17 @@ function assertionErrorMessage( if (operatorName === 'fail') { return ( buildHintString(assertMatcherHint(operator, operatorName, expected)) + - chalk.reset(hasCustomMessage ? `Message:\n ${message}` : '') + + pico.reset(hasCustomMessage ? `Message:\n ${message}` : '') + trimmedStack ); } return `${ buildHintString(assertMatcherHint(operator, operatorName, expected)) + - chalk.reset(`Expected value ${operatorMessage(operator)}`) - } ${printExpected(expected)}\n${chalk.reset('Received:\n')} ${printReceived( + pico.reset(`Expected value ${operatorMessage(operator)}`) + } ${printExpected(expected)}\n${pico.reset('Received:\n')} ${printReceived( actual, - )}${chalk.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '')}${ + )}${pico.reset(hasCustomMessage ? `\n\nMessage:\n ${message}` : '')}${ diffString ? `\n\nDifference:\n\n${diffString}` : '' }${trimmedStack}`; } diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index 10aa579ad8a5..b7eae5685392 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -23,9 +23,9 @@ "./package.json": "./package.json" }, "dependencies": { - "chalk": "^4.0.0", "jest-diff": "workspace:*", "jest-get-type": "workspace:*", + "picocolors": "^1.0.1", "pretty-format": "workspace:*" }, "devDependencies": { diff --git a/packages/jest-matcher-utils/src/__tests__/index.test.ts b/packages/jest-matcher-utils/src/__tests__/index.test.ts index 2db009cf8514..e2374d983ac3 100644 --- a/packages/jest-matcher-utils/src/__tests__/index.test.ts +++ b/packages/jest-matcher-utils/src/__tests__/index.test.ts @@ -6,7 +6,7 @@ * */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {alignedAnsiStyleSerializer} from '@jest/test-utils'; import {format as prettyFormat} from 'pretty-format'; import { @@ -329,19 +329,19 @@ describe('matcherHint', () => { {expectedColor, secondArgument: '...expected'}, ); - const substringNegative = chalk.green(expectedArgument); + const substringNegative = pico.green(expectedArgument); expect(received).not.toMatch(substringNegative); }); test('receivedColor', () => { - const receivedColor = chalk.cyan.bgAnsi256(158); + const receivedColor = (arg: string): string => pico.cyan(pico.bgBlue(arg)); const receivedArgument = 'received'; const received = matcherHint('toMatchSnapshot', receivedArgument, '', { receivedColor, }); - const substringNegative = chalk.red(receivedArgument); + const substringNegative = pico.red(receivedArgument); const substringPositive = receivedColor(receivedArgument); expect(received).not.toMatch(substringNegative); @@ -349,14 +349,14 @@ describe('matcherHint', () => { }); test('secondArgumentColor', () => { - const secondArgumentColor = chalk.bold; + const secondArgumentColor = pico.bold; const secondArgument = 'hint'; const received = matcherHint('toMatchSnapshot', undefined, 'properties', { secondArgument, secondArgumentColor, }); - const substringNegative = chalk.green(secondArgument); + const substringNegative = pico.green(secondArgument); const substringPositive = secondArgumentColor(secondArgument); expect(received).not.toMatch(substringNegative); diff --git a/packages/jest-matcher-utils/src/index.ts b/packages/jest-matcher-utils/src/index.ts index 3e90b1ebf87f..119db9711184 100644 --- a/packages/jest-matcher-utils/src/index.ts +++ b/packages/jest-matcher-utils/src/index.ts @@ -7,7 +7,7 @@ /* eslint-disable local/ban-types-eventually */ -import chalk = require('chalk'); +import * as pico from 'picocolors'; import { DIFF_DELETE, DIFF_EQUAL, @@ -48,7 +48,7 @@ const PLUGINS = [ AsymmetricMatcher, ]; -type MatcherHintColor = (arg: string) => string; // subset of Chalk type +type MatcherHintColor = (arg: string) => string; // subset of pico type export type MatcherHintOptions = { comment?: string; @@ -63,11 +63,11 @@ export type MatcherHintOptions = { export type DiffOptions = ImportDiffOptions; -export const EXPECTED_COLOR = chalk.green; -export const RECEIVED_COLOR = chalk.red; -export const INVERTED_COLOR = chalk.inverse; -export const BOLD_WEIGHT = chalk.bold; -export const DIM_COLOR = chalk.dim; +export const EXPECTED_COLOR = pico.green; +export const RECEIVED_COLOR = pico.red; +export const INVERTED_COLOR = pico.inverse; +export const BOLD_WEIGHT = pico.bold; +export const DIM_COLOR = pico.dim; const MULTILINE_REGEXP = /\n/; const SPACE_SYMBOL = '\u{00B7}'; // middle dot @@ -89,7 +89,7 @@ const NUMBERS = [ 'thirteen', ]; -export const SUGGEST_TO_CONTAIN_EQUAL = chalk.dim( +export const SUGGEST_TO_CONTAIN_EQUAL = pico.dim( 'Looks like you wanted to test for object/array equality with the stricter `toContain` matcher. You probably need to use `toContainEqual` instead.', ); @@ -128,7 +128,7 @@ export const stringify = ( }; export const highlightTrailingWhitespace = (text: string): string => - text.replaceAll(/\s+$/gm, chalk.inverse('$&')); + text.replaceAll(/\s+$/gm, pico.inverse('$&')); // Instead of inverse highlight which now implies a change, // replace common spaces with middle dot at the end of any line. @@ -339,8 +339,8 @@ export const printDiffOrStringify = ( return diffStringsUnified(expected, received, { aAnnotation: expectedLabel, bAnnotation: receivedLabel, - changeLineTrailingSpaceColor: chalk.bgYellow, - commonLineTrailingSpaceColor: chalk.bgYellow, + changeLineTrailingSpaceColor: pico.bgYellow, + commonLineTrailingSpaceColor: pico.bgYellow, emptyFirstOrLastLinePlaceholder: '↵', // U+21B5 expand, includeChangeCounts: true, @@ -516,7 +516,7 @@ export const matcherErrorMessage = ( generic: string, // condition which correct value must fulfill specific?: string, // incorrect value returned from call to printWithType ): string => - `${hint}\n\n${chalk.bold('Matcher error')}: ${generic}${ + `${hint}\n\n${pico.bold('Matcher error')}: ${generic}${ typeof specific === 'string' ? `\n\n${specific}` : '' }`; diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index 751cf0ee5e0a..ed0c1a991b06 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -25,9 +25,9 @@ "@babel/code-frame": "^7.12.13", "@jest/types": "workspace:*", "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.8", + "picocolors": "^1.0.1", "pretty-format": "workspace:*", "slash": "^3.0.0", "stack-utils": "^2.0.3" diff --git a/packages/jest-message-util/src/index.ts b/packages/jest-message-util/src/index.ts index fd6efbb88e30..e410002ec831 100644 --- a/packages/jest-message-util/src/index.ts +++ b/packages/jest-message-util/src/index.ts @@ -9,9 +9,9 @@ import * as path from 'path'; import {fileURLToPath} from 'url'; import {types} from 'util'; import {codeFrameColumns} from '@babel/code-frame'; -import chalk = require('chalk'); import * as fs from 'graceful-fs'; import micromatch = require('micromatch'); +import * as pico from 'picocolors'; import slash = require('slash'); import StackUtils = require('stack-utils'); import type {Config, TestResult} from '@jest/types'; @@ -58,8 +58,8 @@ const TITLE_INDENT = ' '; const MESSAGE_INDENT = ' '; const STACK_INDENT = ' '; const ANCESTRY_SEPARATOR = ' \u203A '; -const TITLE_BULLET = chalk.bold('\u25CF '); -const STACK_TRACE_COLOR = chalk.dim; +const TITLE_BULLET = pico.bold('\u25CF '); +const STACK_TRACE_COLOR = pico.dim; const STACK_PATH_REGEXP = /\s*at.*\(?(:\d*:\d*|native)\)?/; const EXEC_ERROR_MESSAGE = 'Test suite failed to run'; const NOT_EMPTY_LINE_REGEXP = /^(?!$)/gm; @@ -111,10 +111,14 @@ function checkForCommonEnvironmentErrors(error: string) { function warnAboutWrongTestEnvironment(error: string, env: 'jsdom' | 'node') { return ( - chalk.bold.red( - `The error below may be caused by using the wrong test environment, see ${chalk.dim.underline( - 'https://jestjs.io/docs/configuration#testenvironment-string', - )}.\nConsider using the "${env}" test environment.\n\n`, + pico.bold( + pico.red( + `The error below may be caused by using the wrong test environment, see ${pico.dim( + pico.underline( + 'https://jestjs.io/docs/configuration#testenvironment-string', + ), + )}.\nConsider using the "${env}" test environment.\n\n`, + ), ) + error ); } @@ -305,7 +309,7 @@ export const formatPath = ( micromatch([filePath], config.testMatch).length > 0) || filePath === relativeTestPath ) { - filePath = chalk.reset.cyan(filePath); + filePath = pico.reset(pico.cyan(filePath)); } return STACK_TRACE_COLOR(match[1]) + filePath + STACK_TRACE_COLOR(match[3]); }; @@ -488,12 +492,14 @@ export const formatResultsErrors = ( content, ); - const title = `${chalk.bold.red( - TITLE_INDENT + - TITLE_BULLET + - result.ancestorTitles.join(ANCESTRY_SEPARATOR) + - (result.ancestorTitles.length > 0 ? ANCESTRY_SEPARATOR : '') + - result.title, + const title = `${pico.bold( + pico.red( + TITLE_INDENT + + TITLE_BULLET + + result.ancestorTitles.join(ANCESTRY_SEPARATOR) + + (result.ancestorTitles.length > 0 ? ANCESTRY_SEPARATOR : '') + + result.title, + ), )}\n`; return `${title}\n${formatErrorStack( diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index db8fd9e52753..0187a20d1825 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -25,11 +25,11 @@ "@jest/environment": "workspace:*", "@jest/transform": "workspace:*", "@jest/types": "workspace:*", - "chalk": "^4.0.0", "jest-config": "workspace:*", "jest-runtime": "workspace:*", "jest-util": "workspace:*", "jest-validate": "workspace:*", + "picocolors": "^1.0.1", "repl": "^0.1.3", "yargs": "^17.3.1" }, diff --git a/packages/jest-repl/src/cli/runtime-cli.ts b/packages/jest-repl/src/cli/runtime-cli.ts index 5997b040a769..2bd6d66ae9bc 100644 --- a/packages/jest-repl/src/cli/runtime-cli.ts +++ b/packages/jest-repl/src/cli/runtime-cli.ts @@ -12,7 +12,7 @@ import { } from 'os'; import * as path from 'path'; import * as util from 'util'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import yargs = require('yargs'); import {CustomConsole} from '@jest/console'; import type {JestEnvironment} from '@jest/environment'; @@ -142,7 +142,7 @@ export async function run( } } catch (error: any) { console.error( - chalk.red(util.types.isNativeError(error) ? error.stack : error), + pico.red(util.types.isNativeError(error) ? error.stack : error), ); process.on('exit', () => { process.exitCode = 1; diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index 82b70946c59f..f4af2eaa1596 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -21,7 +21,6 @@ "@jest/types": "workspace:*", "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", - "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^10.3.10", @@ -34,6 +33,7 @@ "jest-message-util": "workspace:*", "jest-util": "workspace:*", "jest-worker": "workspace:*", + "picocolors": "^1.0.1", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", diff --git a/packages/jest-reporters/src/CoverageReporter.ts b/packages/jest-reporters/src/CoverageReporter.ts index 39b8636e39fa..efb6f64bf650 100644 --- a/packages/jest-reporters/src/CoverageReporter.ts +++ b/packages/jest-reporters/src/CoverageReporter.ts @@ -8,13 +8,13 @@ import * as path from 'path'; import {mergeProcessCovs} from '@bcoe/v8-coverage'; import type {EncodedSourceMap} from '@jridgewell/trace-mapping'; -import chalk = require('chalk'); import {glob} from 'glob'; import * as fs from 'graceful-fs'; import istanbulCoverage = require('istanbul-lib-coverage'); import istanbulReport = require('istanbul-lib-report'); import libSourceMaps = require('istanbul-lib-source-maps'); import istanbulReports = require('istanbul-reports'); +import * as pico from 'picocolors'; import v8toIstanbul = require('v8-to-istanbul'); import type { AggregatedResult, @@ -33,9 +33,6 @@ import type {ReporterContext} from './types'; type CoverageWorker = typeof import('./CoverageWorker'); -const FAIL_COLOR = chalk.bold.red; -const RUNNING_TEST_COLOR = chalk.bold.dim; - export default class CoverageReporter extends BaseReporter { private readonly _context: ReporterContext; private readonly _coverageMap: istanbulCoverage.CoverageMap; @@ -93,7 +90,7 @@ export default class CoverageReporter extends BaseReporter { aggregatedResults.coverageMap = map; } catch (error: any) { console.error( - chalk.red(` + pico.red(` Failed to write coverage reports: ERROR: ${error.toString()} STACK: ${error.stack} @@ -132,7 +129,7 @@ export default class CoverageReporter extends BaseReporter { if (isInteractive) { process.stderr.write( - RUNNING_TEST_COLOR('Running coverage on untested files...'), + pico.dim(pico.bold('Running coverage on untested files...')), ); } @@ -192,7 +189,7 @@ export default class CoverageReporter extends BaseReporter { } } catch (error: any) { console.error( - chalk.red( + pico.red( [ `Failed to collect coverage from ${filename}`, `ERROR: ${error.message}`, @@ -426,7 +423,7 @@ export default class CoverageReporter extends BaseReporter { ); if (errors.length > 0) { - this.log(`${FAIL_COLOR(errors.join('\n'))}`); + this.log(`${pico.bold(pico.red(errors.join('\n')))}`); this._setError(new Error(errors.join('\n'))); } } diff --git a/packages/jest-reporters/src/__tests__/utils.test.ts b/packages/jest-reporters/src/__tests__/utils.test.ts index 68444f537ee2..434c9b70a4c9 100644 --- a/packages/jest-reporters/src/__tests__/utils.test.ts +++ b/packages/jest-reporters/src/__tests__/utils.test.ts @@ -6,7 +6,7 @@ */ import * as path from 'path'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import stripAnsi = require('strip-ansi'); import {makeProjectConfig} from '@jest/test-utils'; import printDisplayName from '../printDisplayName'; @@ -16,10 +16,10 @@ import wrapAnsiString from '../wrapAnsiString'; describe('wrapAnsiString()', () => { it('wraps a long string containing ansi chars', () => { const string = - `abcde ${chalk.red.bold('red-bold')} 1234456` + - `${chalk.dim('bcd')} ` + + `abcde ${pico.red(pico.bold('red-bold'))} 1234456` + + `${pico.dim('bcd')} ` + '123ttttttththththththththththththththththththththth' + - `tetetetetettetetetetetetetete${chalk.underline.bold('stnhsnthsnth')}` + + `tetetetetettetetetetetetetete${pico.underline(pico.bold('stnhsnthsnth'))}` + 'ssot'; expect(wrapAnsiString(string, 10)).toMatchSnapshot(); expect(stripAnsi(wrapAnsiString(string, 10))).toMatchSnapshot(); diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 984ee8a20b90..eff9cfef18bb 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -19,12 +19,12 @@ "./package.json": "./package.json" }, "dependencies": { - "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "jest-haste-map": "workspace:*", "jest-pnp-resolver": "^1.2.2", "jest-util": "workspace:*", "jest-validate": "workspace:*", + "picocolors": "^1.0.1", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" diff --git a/packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts b/packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts index 5d8412b27131..427717f8fa96 100644 --- a/packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts +++ b/packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts @@ -12,8 +12,8 @@ describe('isBuiltinModule', () => { expect(isBuiltinModule('path')).toBe(true); }); - it('should return false for the `chalk` module', () => { - expect(isBuiltinModule('chalk')).toBe(false); + it('should return false for the `picocolors` module', () => { + expect(isBuiltinModule('picocolors')).toBe(false); }); it('should return true for the `_http_common` module', () => { diff --git a/packages/jest-resolve/src/resolver.ts b/packages/jest-resolve/src/resolver.ts index 32bb4d8cd9f9..04d09c0a657b 100644 --- a/packages/jest-resolve/src/resolver.ts +++ b/packages/jest-resolve/src/resolver.ts @@ -6,7 +6,7 @@ */ import * as path from 'path'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import slash = require('slash'); import type {IModuleMap} from 'jest-haste-map'; import {tryRealpath} from 'jest-util'; @@ -838,17 +838,17 @@ const createNoMappedModuleFoundError = ( : mappedModuleName; const error = new Error( - chalk.red(`${chalk.bold('Configuration error')}: + pico.red(`${pico.bold('Configuration error')}: -Could not locate module ${chalk.bold(moduleName)} mapped as: -${chalk.bold(mappedAs)}. +Could not locate module ${pico.bold(moduleName)} mapped as: +${pico.bold(mappedAs)}. Please check your configuration for these entries: { "moduleNameMapper": { - "${regex.toString()}": "${chalk.bold(original)}" + "${regex.toString()}": "${pico.bold(original)}" }, - "resolver": ${chalk.bold(String(resolver))} + "resolver": ${pico.bold(String(resolver))} }`), ); diff --git a/packages/jest-resolve/src/utils.ts b/packages/jest-resolve/src/utils.ts index 979a2f0921ac..af10db0b8a6f 100644 --- a/packages/jest-resolve/src/utils.ts +++ b/packages/jest-resolve/src/utils.ts @@ -6,12 +6,12 @@ */ import * as path from 'path'; -import chalk = require('chalk'); +import * as pico from 'picocolors'; import {ValidationError} from 'jest-validate'; import Resolver from './resolver'; -const BULLET: string = chalk.bold('\u25CF '); -const DOCUMENTATION_NOTE = ` ${chalk.bold('Configuration Documentation:')} +const BULLET: string = pico.bold('\u25CF '); +const DOCUMENTATION_NOTE = ` ${pico.bold('Configuration Documentation:')} https://jestjs.io/docs/configuration `; @@ -73,9 +73,9 @@ const resolveWithPrefix = ( } catch {} throw createValidationError( - ` ${humanOptionName} ${chalk.bold( + ` ${humanOptionName} ${pico.bold( fileName, - )} cannot be found. Make sure the ${chalk.bold( + )} cannot be found. Make sure the ${pico.bold( optionName, )} configuration option points to an existing node module.`, ); diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index 8ef53bfff624..5b7870560fb9 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -25,7 +25,6 @@ "@jest/transform": "workspace:*", "@jest/types": "workspace:*", "@types/node": "*", - "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "workspace:*", @@ -39,6 +38,7 @@ "jest-watcher": "workspace:*", "jest-worker": "workspace:*", "p-limit": "^3.1.0", + "picocolors": "^1.0.1", "source-map-support": "0.5.13" }, "devDependencies": { diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index f55f2791f262..23726a40ac51 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -5,9 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -import chalk = require('chalk'); import Emittery = require('emittery'); import pLimit = require('p-limit'); +import * as pico from 'picocolors'; import type { Test, TestEvents, @@ -184,7 +184,7 @@ export default class TestRunner extends EmittingTestRunner { const {forceExited} = await worker.end(); if (forceExited) { console.error( - chalk.yellow( + pico.yellow( 'A worker process has failed to exit gracefully and has been force exited. ' + 'This is likely caused by tests leaking due to improper teardown. ' + 'Try running with --detectOpenHandles to find leaks. ' + diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 5a20296dd21e..8edadafbdc78 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -7,8 +7,8 @@ */ import {runInContext} from 'node:vm'; -import chalk = require('chalk'); import * as fs from 'graceful-fs'; +import * as pico from 'picocolors'; import sourcemapSupport = require('source-map-support'); import { BufferedConsole, @@ -46,8 +46,8 @@ function freezeConsole( message: LogMessage, ) { const error = new ErrorWithStack( - `${chalk.red( - `${chalk.bold( + `${pico.red( + `${pico.bold( 'Cannot log after tests are done.', )} Did you forget to wait for something async in your test?`, )}\nAttempted to log "${message}".`, diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 04d8286a5af5..756ad940e29b 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -27,7 +27,6 @@ "@jest/transform": "workspace:*", "@jest/types": "workspace:*", "@types/node": "*", - "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^10.3.10", @@ -39,6 +38,7 @@ "jest-resolve": "workspace:*", "jest-snapshot": "workspace:*", "jest-util": "workspace:*", + "picocolors": "^1.0.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 477be4b7ef22..114f2e935743 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -112,7 +112,9 @@ type ModuleRegistry = Map; // users who require one of these modules in their tests will still get the module from inside the VM. // Prefer listing a module here only if it is impractical to use the jest-resolve-outside-vm-option where it is required, // e.g. because there are many require sites spread across the dependency graph. -const INTERNAL_MODULE_REQUIRE_OUTSIDE_OPTIMIZED_MODULES = new Set(['chalk']); +const INTERNAL_MODULE_REQUIRE_OUTSIDE_OPTIMIZED_MODULES = new Set([ + 'picocolors', +]); const JEST_RESOLVE_OUTSIDE_VM_OPTION = Symbol.for( 'jest-resolve-outside-vm-option', ); diff --git a/scripts/build.mjs b/scripts/build.mjs index 0f919d1a869c..29038aa17495 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -9,9 +9,9 @@ import {strict as assert} from 'assert'; import {createRequire} from 'module'; import * as path from 'path'; import util from 'util'; -import chalk from 'chalk'; import dedent from 'dedent'; import fs from 'graceful-fs'; +import pico from 'picocolors'; import webpack from 'webpack'; import { ERROR, @@ -24,7 +24,7 @@ import { const require = createRequire(import.meta.url); async function buildNodePackages() { - process.stdout.write(chalk.inverse(' Bundling packages \n')); + process.stdout.write(pico.inverse(' Bundling packages \n')); const buildConfigs = createBuildConfigs(); diff --git a/scripts/buildTs.mjs b/scripts/buildTs.mjs index bdd931651815..e730dcdbcbb4 100644 --- a/scripts/buildTs.mjs +++ b/scripts/buildTs.mjs @@ -8,11 +8,11 @@ import {strict as assert} from 'assert'; import * as os from 'os'; import * as path from 'path'; -import chalk from 'chalk'; import execa from 'execa'; import {glob} from 'glob'; import fs from 'graceful-fs'; import pLimit from 'p-limit'; +import pico from 'picocolors'; import stripJsonComments from 'strip-json-comments'; import {getPackagesWithTsConfig} from './buildUtils.mjs'; @@ -102,7 +102,7 @@ for (const {packageDir, pkg} of packagesWithTs) { if (hasJestTestUtils) { throw new Error( - chalk.red( + pico.red( `Package '${pkg.name}' declares '@jest/test-utils' as dependency, but it must be declared as dev dependency`, ), ); @@ -129,7 +129,7 @@ for (const {packageDir, pkg} of packagesWithTs) { if (hasJestTestUtils && testUtilsReferences.length === 0) { throw new Error( - chalk.red( + pico.red( `Package '${ pkg.name }' declares '@jest/test-utils' as dev dependency, but it is not referenced in:\n\n${tsConfigPaths.join( @@ -141,7 +141,7 @@ for (const {packageDir, pkg} of packagesWithTs) { if (!hasJestTestUtils && testUtilsReferences.length > 0) { throw new Error( - chalk.red( + pico.red( `Package '${ pkg.name }' does not declare '@jest/test-utils' as dev dependency, but it is referenced in:\n\n${testUtilsReferences.join( @@ -159,21 +159,23 @@ const args = [ ...process.argv.slice(2), ]; -console.log(chalk.inverse(' Building TypeScript definition files ')); +console.log(pico.inverse(' Building TypeScript definition files ')); try { await execa('yarn', args, {stdio: 'inherit'}); console.log( - chalk.inverse.green(' Successfully built TypeScript definition files '), + pico.inverse( + pico.green(' Successfully built TypeScript definition files '), + ), ); } catch (error) { console.error( - chalk.inverse.red(' Unable to build TypeScript definition files '), + pico.inverse(pico.red(' Unable to build TypeScript definition files ')), ); throw error; } -console.log(chalk.inverse(' Validating TypeScript definition files ')); +console.log(pico.inverse(' Validating TypeScript definition files ')); // we want to limit the number of processes we spawn const cpus = Math.max( @@ -219,8 +221,8 @@ try { .filter(([, content]) => content.length > 0) .filter(hit => hit.length > 0) .map(([file, references]) => - chalk.red( - `${chalk.bold( + pico.red( + `${pico.bold( file, )} has the following non-node type references:\n\n${references}\n`, ), @@ -251,12 +253,14 @@ try { ); } catch (error) { console.error( - chalk.inverse.red(' Unable to validate TypeScript definition files '), + pico.inverse(pico.red(' Unable to validate TypeScript definition files ')), ); throw error; } console.log( - chalk.inverse.green(' Successfully validated TypeScript definition files '), + pico.inverse( + pico.green(' Successfully validated TypeScript definition files '), + ), ); diff --git a/scripts/buildUtils.mjs b/scripts/buildUtils.mjs index a92a16df950b..7dc27788f62a 100644 --- a/scripts/buildUtils.mjs +++ b/scripts/buildUtils.mjs @@ -9,8 +9,8 @@ import {strict as assert} from 'assert'; import {createRequire} from 'module'; import * as path from 'path'; import {fileURLToPath} from 'url'; -import chalk from 'chalk'; import fs from 'graceful-fs'; +import pico from 'picocolors'; import {sync as readPkg} from 'read-pkg'; import webpack from 'webpack'; import nodeExternals from 'webpack-node-externals'; @@ -22,8 +22,8 @@ export const PACKAGES_DIR = path.resolve( ); const require = createRequire(import.meta.url); -export const OK = chalk.reset.inverse.bold.green(' DONE '); -export const ERROR = chalk.reset.inverse.bold.red(' BOOM '); +export const OK = pico.reset(pico.inverse(pico.bold(pico.green(' DONE ')))); +export const ERROR = pico.reset(pico.inverse(pico.bold(pico.red(' BOOM ')))); export const typeOnlyPackages = new Set([ 'babel-preset-jest', diff --git a/scripts/bundleTs.mjs b/scripts/bundleTs.mjs index f506d4a08507..f1cd0175bd86 100644 --- a/scripts/bundleTs.mjs +++ b/scripts/bundleTs.mjs @@ -13,10 +13,10 @@ import { Extractor, ExtractorConfig, } from '@microsoft/api-extractor'; -import chalk from 'chalk'; import {ESLint} from 'eslint'; import {glob} from 'glob'; import fs from 'graceful-fs'; +import pico from 'picocolors'; import pkgDir from 'pkg-dir'; import {rimraf} from 'rimraf'; import {copyrightSnippet, getPackagesWithTsConfig} from './buildUtils.mjs'; @@ -32,7 +32,7 @@ const packagesToBundle = getPackagesWithTsConfig().filter( p => !excludedPackages.has(p.pkg.name), ); -console.log(chalk.inverse(' Extracting TypeScript definition files ')); +console.log(pico.inverse(' Extracting TypeScript definition files ')); const sharedExtractorConfig = { $schema: @@ -118,7 +118,6 @@ let compilerState; await Promise.all( packagesToBundle.map(async ({packageDir, pkg}) => { const configFile = path.resolve(packageDir, 'api-extractor.json'); - await fs.promises.writeFile( configFile, JSON.stringify( @@ -151,7 +150,9 @@ await Promise.all( if (!extractorResult.succeeded || extractorResult.warningCount > 0) { console.error( - chalk.inverse.red(' Unable to extract TypeScript definition files '), + pico.inverse( + pico.red(' Unable to extract TypeScript definition files '), + ), ); throw new Error( `API Extractor completed with ${extractorResult.errorCount} errors and ${extractorResult.warningCount} warnings`, @@ -232,5 +233,7 @@ await Promise.all( ); console.log( - chalk.inverse.green(' Successfully extracted TypeScript definition files '), + pico.inverse( + pico.green(' Successfully extracted TypeScript definition files '), + ), ); diff --git a/scripts/lintTs.mjs b/scripts/lintTs.mjs index 5f92e8380c9e..cfddc6d4451a 100644 --- a/scripts/lintTs.mjs +++ b/scripts/lintTs.mjs @@ -10,9 +10,9 @@ import * as os from 'os'; import * as path from 'path'; import * as url from 'url'; -import chalk from 'chalk'; import {ESLint} from 'eslint'; import pLimit from 'p-limit'; +import pico from 'picocolors'; import {getPackagesWithTsConfig} from './buildUtils.mjs'; // we want to limit the number of processes we spawn @@ -178,7 +178,7 @@ try { ); } catch (error) { console.error( - chalk.inverse.red(' Unable to lint using TypeScript info files '), + pico.inverse(pico.red(' Unable to lint using TypeScript info files ')), ); throw error; @@ -192,12 +192,14 @@ if (allLintResults.length > 0) { console.error(resultText); console.error( - chalk.inverse.red(' Unable to lint using TypeScript info files '), + pico.inverse(pico.red(' Unable to lint using TypeScript info files ')), ); process.exitCode = 1; } else { console.log( - chalk.inverse.green(' Successfully linted using TypeScript info files '), + pico.inverse( + pico.green(' Successfully linted using TypeScript info files '), + ), ); } diff --git a/scripts/verifyOldTs.mjs b/scripts/verifyOldTs.mjs index 574e9fef9c2a..583196b2dec1 100644 --- a/scripts/verifyOldTs.mjs +++ b/scripts/verifyOldTs.mjs @@ -8,9 +8,9 @@ import {createRequire} from 'module'; import * as path from 'path'; import {fileURLToPath} from 'url'; -import chalk from 'chalk'; import execa from 'execa'; import fs from 'graceful-fs'; +import pico from 'picocolors'; import stripJsonComments from 'strip-json-comments'; /* eslint-disable import/order */ import tempy from 'tempy'; @@ -73,8 +73,8 @@ function smoketest() { execa.sync('yarn', ['tsc', '--project', '.'], {cwd, stdio: 'inherit'}); console.log( - chalk.inverse.green( - ` Successfully compiled Jest with TypeScript ${tsVersion} `, + pico.inverse( + pico.green(` Successfully compiled Jest with TypeScript ${tsVersion} `), ), ); } finally { @@ -82,6 +82,6 @@ function smoketest() { } } -console.log(chalk.inverse(` Running smoketest using TypeScript@${tsVersion} `)); +console.log(pico.inverse(` Running smoketest using TypeScript@${tsVersion} `)); smoketest(); -console.log(chalk.inverse.green(' Successfully ran smoketest ')); +console.log(pico.inverse(pico.green(' Successfully ran smoketest '))); diff --git a/scripts/verifyPnP.mjs b/scripts/verifyPnP.mjs index 31ace2088a11..b85bbecd9aed 100644 --- a/scripts/verifyPnP.mjs +++ b/scripts/verifyPnP.mjs @@ -7,11 +7,11 @@ import * as path from 'path'; import {fileURLToPath} from 'url'; -import chalk from 'chalk'; import dedent from 'dedent'; import execa from 'execa'; import fs from 'graceful-fs'; import yaml from 'js-yaml'; +import pico from 'picocolors'; import tempy from 'tempy'; const rootDirectory = path.resolve( @@ -75,7 +75,9 @@ try { }); execa.sync('yarn', ['jest'], {cwd, stdio: 'inherit'}); - console.log(chalk.inverse.green(' Successfully ran Jest with PnP linker ')); + console.log( + pico.inverse(pico.green(' Successfully ran Jest with PnP linker ')), + ); } finally { fs.rmSync(cwd, {force: true, recursive: true}); } diff --git a/scripts/watch.mjs b/scripts/watch.mjs index 15900562c028..e95ebeeff135 100644 --- a/scripts/watch.mjs +++ b/scripts/watch.mjs @@ -9,7 +9,7 @@ * Watch files for changes and rebuild (copy from 'src/' to `build/`) if changed */ -import chalk from 'chalk'; +import pico from 'picocolors'; import webpack from 'webpack'; import {createWebpackConfigs} from './buildUtils.mjs'; @@ -17,13 +17,13 @@ const compiler = webpack(createWebpackConfigs()); let hasBuilt = false; -console.log(chalk.inverse(' Bundling packages ')); +console.log(pico.inverse(' Bundling packages ')); compiler.watch({}, (error, stats) => { if (!hasBuilt) { hasBuilt = true; - console.log(chalk.red('->'), chalk.cyan('Watching for changes…')); + console.log(pico.red('->'), pico.cyan('Watching for changes…')); } if (error) { @@ -41,7 +41,7 @@ compiler.watch({}, (error, stats) => { console.warn('warning', warning.message); } } else { - console.log(chalk.red('->'), chalk.green('Rebuilt packages')); + console.log(pico.red('->'), pico.green('Rebuilt packages')); } } }); diff --git a/yarn.lock b/yarn.lock index 3fbf9bd66357..a6b1f0a3f8b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3101,9 +3101,9 @@ __metadata: "@jest/test-utils": "workspace:*" "@jest/types": "workspace:*" "@types/node": "*" - chalk: ^4.0.0 jest-message-util: "workspace:*" jest-util: "workspace:*" + picocolors: ^1.0.1 slash: ^3.0.0 languageName: unknown linkType: soft @@ -3125,7 +3125,6 @@ __metadata: "@types/micromatch": ^4.0.7 "@types/node": "*" ansi-escapes: ^4.2.1 - chalk: ^4.0.0 ci-info: ^4.0.0 exit: ^0.1.2 graceful-fs: ^4.2.9 @@ -3143,6 +3142,7 @@ __metadata: jest-validate: "workspace:*" jest-watcher: "workspace:*" micromatch: ^4.0.8 + picocolors: ^1.0.1 pretty-format: "workspace:*" slash: ^3.0.0 strip-ansi: ^6.0.0 @@ -3279,7 +3279,6 @@ __metadata: babel-jest: "workspace:*" babel-loader: ^9.0.0 camelcase: ^6.2.0 - chalk: ^4.0.0 dedent: ^1.0.0 eslint: ^8.8.0 eslint-config-prettier: ^9.0.0 @@ -3317,6 +3316,7 @@ __metadata: netlify-plugin-cache: ^1.0.3 node-notifier: ^10.0.0 p-limit: ^3.1.0 + picocolors: ^1.0.1 pkg-dir: ^5.0.0 prettier: ^3.0.3 promise: ^8.0.2 @@ -3367,7 +3367,6 @@ __metadata: "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/node-notifier": ^8.0.0 - chalk: ^4.0.0 collect-v8-coverage: ^1.0.0 exit: ^0.1.2 glob: ^10.3.10 @@ -3383,6 +3382,7 @@ __metadata: jest-worker: "workspace:*" mock-fs: ^5.1.2 node-notifier: ^10.0.0 + picocolors: ^1.0.1 slash: ^3.0.0 string-length: ^4.0.1 strip-ansi: ^6.0.0 @@ -7052,8 +7052,8 @@ __metadata: "@types/graceful-fs": ^4.1.3 babel-plugin-istanbul: ^7.0.0 babel-preset-jest: "workspace:*" - chalk: ^4.0.0 graceful-fs: ^4.2.9 + picocolors: ^1.0.1 slash: ^3.0.0 peerDependencies: "@babel/core": ^7.11.0 @@ -8503,11 +8503,11 @@ __metadata: "@types/exit": ^0.1.30 "@types/graceful-fs": ^4.1.3 "@types/prompts": ^2.0.1 - chalk: ^4.0.0 exit: ^0.1.2 graceful-fs: ^4.2.9 jest-config: "workspace:*" jest-util: "workspace:*" + picocolors: ^1.0.1 prompts: ^2.0.1 bin: create-jest: ./bin/create-jest.js @@ -13151,6 +13151,7 @@ __metadata: jest-snapshot: "workspace:*" jest-util: "workspace:*" p-limit: ^3.1.0 + picocolors: ^1.0.1 pretty-format: "workspace:*" pure-rand: ^6.0.0 slash: ^3.0.0 @@ -13168,12 +13169,12 @@ __metadata: "@jest/types": "workspace:*" "@types/exit": ^0.1.30 "@types/yargs": ^17.0.8 - chalk: ^4.0.0 exit: ^0.1.2 import-local: ^3.0.2 jest-config: "workspace:*" jest-util: "workspace:*" jest-validate: "workspace:*" + picocolors: ^1.0.1 yargs: ^17.3.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -13197,7 +13198,6 @@ __metadata: "@types/micromatch": ^4.0.7 "@types/parse-json": ^4.0.0 babel-jest: "workspace:*" - chalk: ^4.0.0 ci-info: ^4.0.0 deepmerge: ^4.2.2 esbuild: ^0.23.0 @@ -13215,6 +13215,7 @@ __metadata: jest-validate: "workspace:*" micromatch: ^4.0.8 parse-json: ^5.2.0 + picocolors: ^1.0.1 pretty-format: "workspace:*" semver: ^7.5.3 slash: ^3.0.0 @@ -13240,9 +13241,9 @@ __metadata: resolution: "jest-diff@workspace:packages/jest-diff" dependencies: "@jest/test-utils": "workspace:*" - chalk: ^4.0.0 diff-sequences: "workspace:*" jest-get-type: "workspace:*" + picocolors: ^1.0.1 pretty-format: "workspace:*" strip-ansi: ^6.0.0 languageName: unknown @@ -13262,9 +13263,9 @@ __metadata: resolution: "jest-each@workspace:packages/jest-each" dependencies: "@jest/types": "workspace:*" - chalk: ^4.0.0 jest-get-type: "workspace:*" jest-util: "workspace:*" + picocolors: ^1.0.1 pretty-format: "workspace:*" languageName: unknown linkType: soft @@ -13350,7 +13351,6 @@ __metadata: "@jest/types": "workspace:*" "@types/co": ^4.6.2 "@types/node": "*" - chalk: ^4.0.0 co: ^4.6.0 is-generator-fn: ^2.0.0 jest-each: "workspace:*" @@ -13360,6 +13360,7 @@ __metadata: jest-snapshot: "workspace:*" jest-util: "workspace:*" p-limit: ^3.1.0 + picocolors: ^1.0.1 pretty-format: "workspace:*" languageName: unknown linkType: soft @@ -13392,9 +13393,9 @@ __metadata: dependencies: "@jest/test-utils": "workspace:*" "@types/node": "*" - chalk: ^4.0.0 jest-diff: "workspace:*" jest-get-type: "workspace:*" + picocolors: ^1.0.1 pretty-format: "workspace:*" languageName: unknown linkType: soft @@ -13426,9 +13427,9 @@ __metadata: "@types/graceful-fs": ^4.1.3 "@types/micromatch": ^4.0.7 "@types/stack-utils": ^2.0.0 - chalk: ^4.0.0 graceful-fs: ^4.2.9 micromatch: ^4.0.8 + picocolors: ^1.0.1 pretty-format: "workspace:*" slash: ^3.0.0 stack-utils: ^2.0.3 @@ -13490,12 +13491,12 @@ __metadata: "@jest/transform": "workspace:*" "@jest/types": "workspace:*" "@types/yargs": ^17.0.8 - chalk: ^4.0.0 execa: ^5.0.0 jest-config: "workspace:*" jest-runtime: "workspace:*" jest-util: "workspace:*" jest-validate: "workspace:*" + picocolors: ^1.0.1 repl: ^0.1.3 yargs: ^17.3.1 bin: @@ -13525,12 +13526,12 @@ __metadata: "@types/graceful-fs": ^4.1.3 "@types/pnpapi": ^0.0.5 "@types/resolve": ^1.20.2 - chalk: ^4.0.0 graceful-fs: ^4.2.9 jest-haste-map: "workspace:*" jest-pnp-resolver: ^1.2.2 jest-util: "workspace:*" jest-validate: "workspace:*" + picocolors: ^1.0.1 resolve: ^1.20.0 resolve.exports: ^2.0.0 slash: ^3.0.0 @@ -13551,7 +13552,6 @@ __metadata: "@types/graceful-fs": ^4.1.3 "@types/node": "*" "@types/source-map-support": ^0.5.0 - chalk: ^4.0.0 emittery: ^0.13.1 graceful-fs: ^4.2.9 jest-docblock: "workspace:*" @@ -13566,6 +13566,7 @@ __metadata: jest-watcher: "workspace:*" jest-worker: "workspace:*" p-limit: ^3.1.0 + picocolors: ^1.0.1 source-map-support: 0.5.13 languageName: unknown linkType: soft @@ -13584,7 +13585,6 @@ __metadata: "@jest/types": "workspace:*" "@types/graceful-fs": ^4.1.3 "@types/node": "*" - chalk: ^4.0.0 cjs-module-lexer: ^1.0.0 collect-v8-coverage: ^1.0.0 glob: ^10.3.10 @@ -13597,6 +13597,7 @@ __metadata: jest-resolve: "workspace:*" jest-snapshot: "workspace:*" jest-util: "workspace:*" + picocolors: ^1.0.1 slash: ^3.0.0 strip-bom: ^4.0.0 languageName: unknown