fix: replace node:util.styleText with cross-platform ANSI codes#290
fix: replace node:util.styleText with cross-platform ANSI codes#290
Conversation
Fixes #289 - Replace node:util.styleText with ANSI color codes for browser compatibility - Add cross-platform styleText utility (style-text.ts) - Use environment detection (process.versions.node) instead of require() - Update tests to strip ANSI codes for assertions - Zero dependencies maintained - Bundle size: 1.81 kB gzipped (unchanged)
🦋 Changeset detectedLatest commit: d126ea7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughReplaces Node-only Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller as Test / Caller
participant Errors as errors.ts
participant Style as lib/style-text.ts
Note right of Errors `#eef2ff`: import now uses local styleText
Caller->>Errors: request formatted error
Errors->>Style: styleText(color, text)
alt Node environment
Style-->>Errors: ANSI-wrapped text
else Browser-like environment
Style-->>Errors: plain text
end
Errors-->>Caller: formatted message
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Added import statement for styleText in create-env.test.ts to ensure the test functions correctly. - Removed unnecessary blank line in style-text.ts for cleaner code.
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/arkenv/src/style-text.ts (1)
7-12: Consider using Unicode escape sequences for consistency.While
\x1bworks correctly, using\u001bwould be more consistent with the recommended fix for the test file and avoid potential linter issues across different configurations.Apply this diff if you prefer Unicode escapes:
// ANSI color codes for Node environments const colors = { - red: "\x1b[31m", - yellow: "\x1b[33m", - cyan: "\x1b[36m", - reset: "\x1b[0m", + red: "\u001b[31m", + yellow: "\u001b[33m", + cyan: "\u001b[36m", + reset: "\u001b[0m", } as const;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/arkenv/src/create-env.test.ts(1 hunks)packages/arkenv/src/error.integration.test.ts(2 hunks)packages/arkenv/src/errors.ts(1 hunks)packages/arkenv/src/style-text.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/arkenv/src/error.integration.test.ts (1)
packages/arkenv/src/utils.test.ts (7)
it(4-40)input(29-33)input(17-21)input(5-9)input(35-39)input(23-27)input(11-15)
🪛 GitHub Actions: autofix.ci
packages/arkenv/src/error.integration.test.ts
[error] 7-7: lint/suspicious/noControlCharactersInRegex: Unexpected control character in a regular expression.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test-e2e (e2e)
- GitHub Check: test-e2e (a11y)
🔇 Additional comments (5)
packages/arkenv/src/create-env.test.ts (1)
3-3: LGTM! Import successfully migrated to cross-platform utility.The import path change maintains API compatibility while resolving browser compatibility issues.
packages/arkenv/src/errors.ts (1)
2-2: LGTM! Import successfully migrated to cross-platform utility.The import change resolves the browser compatibility issue while maintaining identical functionality for all
styleTextusage throughout the file.packages/arkenv/src/error.integration.test.ts (1)
133-140: LGTM! Proper ANSI sanitization for test assertions.Stripping ANSI codes before assertions prevents test brittleness and ensures consistent validation across different output modes.
packages/arkenv/src/style-text.ts (2)
17-20: LGTM! Robust Node environment detection.The three-level check (
processexistence,process.versions,process.versions.node) provides reliable differentiation between Node and browser environments for this use case.
28-38: LGTM! Clean cross-platform implementation.The function correctly applies ANSI styling in Node while gracefully degrading to plain text in browsers, achieving the PR's goal of zero-dependency browser compatibility.
- Changed the regex for stripping ANSI color codes to use the escape sequence format for better compatibility. - This adjustment ensures that the tests correctly handle colored output across different environments.
- Move style-text.ts to lib/ folder for better organization - Add lib/README.md explaining reusable library utilities - Add comprehensive unit tests for style-text.ts (15 tests) - Test both Node and browser environments - Test edge cases (null process, special characters, unicode) - Make isNode() check dynamic to support testing with mocked globals - Fix octal escape sequence (\033) for ANSI stripping in tests - All 97 tests passing
- Changed the import path for styleText from './style-text' to './lib/style-text' in create-env.test.ts and errors.ts. - Deleted the now redundant style-text.ts file, as its functionality is no longer needed.
- Changed the Node version in the test setup from 18.0.0 to 22.0.0 to ensure compatibility with the latest features and improvements.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/arkenv/src/lib/style-text.ts (1)
29-39: LGTM! Clean cross-platform implementation.The implementation correctly returns ANSI-styled text in Node and plain text in browsers, achieving the PR's browser-compatibility goal with zero dependencies.
Optional enhancement: Consider respecting the
NO_COLORenvironment variable (a de facto standard) to allow users to disable colors even in Node environments. This is common in CI systems and accessibility tools.Example enhancement:
export const styleText = ( color: "red" | "yellow" | "cyan", text: string, ): string => { // Use ANSI colors in Node environments - if (isNode()) { + if (isNode() && !process.env.NO_COLOR) { return `${colors[color]}${text}${colors.reset}`; } // Fall back to plain text in browsers return text; };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/arkenv/src/create-env.test.ts(1 hunks)packages/arkenv/src/error.integration.test.ts(2 hunks)packages/arkenv/src/errors.ts(1 hunks)packages/arkenv/src/lib/README.md(1 hunks)packages/arkenv/src/lib/style-text.test.ts(1 hunks)packages/arkenv/src/lib/style-text.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/arkenv/src/lib/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/arkenv/src/errors.ts
🧰 Additional context used
🪛 ast-grep (0.39.7)
packages/arkenv/src/error.integration.test.ts
[warning] 7-7: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${String.fromCharCode(27)}\\[[0-9;]*m, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test-e2e (e2e)
🔇 Additional comments (6)
packages/arkenv/src/create-env.test.ts (1)
3-3: LGTM! Clean import migration.The import path has been correctly updated to use the new cross-platform utility while maintaining the same API surface.
packages/arkenv/src/error.integration.test.ts (2)
6-8: LGTM! stripAnsi helper is correctly implemented.The use of
String.fromCharCode(27)to construct the ESC character addresses the linter concern from the previous review. The regex pattern\[[0-9;]*mis safe and not susceptible to ReDoS since the prefix is constant and the pattern itself has no problematic backtracking.Note on static analysis warning: The ast-grep warning about "regex from variable input" is a false positive here.
String.fromCharCode(27)is effectively a constant that always produces the same ESC character, and the overall pattern has no exponential backtracking risks.
134-141: LGTM! Correct sanitization for styled output assertions.The
stripAnsicalls appropriately clean ANSI color codes from error messages, allowing tests to verify the logical structure and content independent of styling.packages/arkenv/src/lib/style-text.ts (2)
7-12: LGTM! Standard ANSI color codes.The color definitions use correct hex escapes for the ESC character and proper SGR (Select Graphic Rendition) sequences.
18-21: LGTM! Robust Node environment detection.The triple-null-check pattern correctly distinguishes Node from browser environments and is appropriately dynamic to support testing with mocked globals.
packages/arkenv/src/lib/style-text.test.ts (1)
1-119: LGTM! Comprehensive test coverage.The test suite thoroughly validates:
- ✅ ANSI color wrapping in Node environments (all three colors)
- ✅ Plain text output in browser environments
- ✅ Edge cases: empty strings, special characters, Unicode, null process states
- ✅ Long text handling in actual runtime environment
The use of
vi.stubGlobalandvi.unstubAllGlobalscorrectly simulates different execution contexts, and the conditional assertion in the long text test appropriately validates real-world behavior.
- Replaced Node.js `util.styleText` with a custom ANSI color implementation to enhance browser support. - Introduced `lib/style-text.ts` for environment detection and ANSI code usage. - Organized utilities into a `lib/` folder and added a README for clarity. - Comprehensive unit tests added for Node, browser, and edge cases. - Ensured error messages retain colored output in Node while falling back to plain text in browsers.
… with ANSI codes - Replaced Node.js `util.styleText` with a custom ANSI implementation to resolve browser compatibility issues. - Added environment detection to use ANSI codes in Node and plain text in browsers. - Organized utilities into a `lib/` folder and included comprehensive unit tests for various environments.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
.changeset/two-poems-sit.md (2)
5-13: Doc nits: add traceability and runtime notes (optional).
- Consider adding “Fixes #289” in the body for changelog traceability.
- If the new utility respects NO_COLOR/CI/TTY (e.g., process.stdout.isTTY or NO_COLOR), call that out; otherwise consider adding it in a follow‑up.
Here’s a minimal diff to append after the “Changes” list:
- Organized utilities into `lib/` folder with comprehensive tests + +Notes: +- Fixes #289. See PR #290 for details. +- In Node, ANSI colors are emitted; in browsers, plain text is used. +- If your tooling requires disabling colors, set `NO_COLOR=1` (and/or rely on CI/TTY detection if implemented).
5-13: Link concrete runtime examples for quick verification.Per prior repo guidance, add links to Node, Bun, and Vite examples to help users validate the fix quickly. Based on learnings.
**Changes:** @@ - Organized utilities into `lib/` folder with comprehensive tests + +Example runtimes: +- Node.js: [examples/basic](../examples/basic) +- Bun: [examples/with-bun](../examples/with-bun) +- Vite (React + TS): [examples/with-vite-react-ts](../examples/with-vite-react-ts)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
.changeset/two-poems-sit.md(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-09T17:37:19.650Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 132
File: packages/arkenv/README.md:13-14
Timestamp: 2025-09-09T17:37:19.650Z
Learning: For yamcodes/arkenv project: Runtime support documentation should link to specific examples: Node.js (examples/basic), Bun (examples/with-bun), Vite (examples/with-vite-react-ts).
Applied to files:
.changeset/two-poems-sit.md
📚 Learning: 2025-09-10T19:35:18.179Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 136
File: .changeset/vast-bananas-win.md:2-3
Timestamp: 2025-09-10T19:35:18.179Z
Learning: The arkenv package is currently in v0.x.x (pre-1.0) development phase, where breaking changes are acceptable in minor version bumps according to semantic versioning conventions.
Applied to files:
.changeset/two-poems-sit.md
🔇 Additional comments (2)
.changeset/two-poems-sit.md (2)
1-3: Semver bump looks right as a patch.This reads as a non‑breaking behavior fix; patch is appropriate. No changes requested.
15-23: LGTM on the example snippet.Clear and minimal; it illustrates that importing from
arkenvno longer triggers the browser externalization error.
- Updated the styleText implementation to respect NO_COLOR and CI environment variables, as well as TTY detection, ensuring colors are only applied when appropriate. - Added comprehensive tests to verify color behavior under various conditions, including disabling colors when specified. - Improved documentation within the code to clarify the functionality and conditions for color application.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
.changeset/two-poems-sit.md (1)
16-23: Code example demonstrates the resolution but could be more explicit about cross-platform behavior.The example effectively shows that
createEnvno longer throws the "node:util has been externalized" error in browser environments. However, adding a brief comment explaining that this now works in both Node and browser contexts (e.g.,// Works in Node, Vite, Bun, and browsers) would strengthen clarity for users unfamiliar with the fix.Consider this enhancement:
```ts // No longer throws "node:util has been externalized" error +// Works in Node.js, Vite, Bun, and browser environments import { createEnv } from "arkenv";
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/two-poems-sit.md(1 hunks)packages/arkenv/src/lib/style-text.test.ts(1 hunks)packages/arkenv/src/lib/style-text.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/arkenv/src/lib/style-text.ts
- packages/arkenv/src/lib/style-text.test.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-10T19:35:18.179Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 136
File: .changeset/vast-bananas-win.md:2-3
Timestamp: 2025-09-10T19:35:18.179Z
Learning: The arkenv package is currently in v0.x.x (pre-1.0) development phase, where breaking changes are acceptable in minor version bumps according to semantic versioning conventions.
Applied to files:
.changeset/two-poems-sit.md
📚 Learning: 2025-09-09T17:37:19.650Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 132
File: packages/arkenv/README.md:13-14
Timestamp: 2025-09-09T17:37:19.650Z
Learning: For yamcodes/arkenv project: Runtime support documentation should link to specific examples: Node.js (examples/basic), Bun (examples/with-bun), Vite (examples/with-vite-react-ts).
Applied to files:
.changeset/two-poems-sit.md
🧬 Code graph analysis (1)
.changeset/two-poems-sit.md (4)
packages/arkenv/src/index.test.ts (1)
vi(65-81)packages/arkenv/src/create-env.test.ts (4)
env(88-99)error(19-23)errors(12-26)process(29-37)packages/arkenv/src/errors.ts (1)
ArkEnvError(30-38)packages/arkenv/src/error.integration.test.ts (1)
it(11-177)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test-e2e (a11y)
- GitHub Check: test-e2e (e2e)
🔇 Additional comments (2)
.changeset/two-poems-sit.md (2)
1-3: Version bump is semantically correct.Patch bump appropriately reflects a bug fix (browser compatibility) without introducing new features or breaking changes. Based on learnings, this aligns with arkenv's v0.x.x pre-release phase conventions.
5-14: Clear, well-structured description that accurately documents the fix.The title, problem statement, and bullet points effectively communicate:
- The root cause (Node-specific module import)
- The solution approach (cross-platform ANSI codes)
- Key implementation details (environment detection, zero dependencies maintained)
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## arkenv@0.7.4 ### Patch Changes - #### Enable minification to reduce bundle size _[`#336`](#336) [`7236cb2`](7236cb2) [@yamcodes](https://github.com/yamcodes)_ Enable minification in build output. Reduces bundle size from 711 B to 708 B. Comments are removed from the bundle but remain in source files. - #### Fix browser compatibility by replacing `util.styleText` with cross-platform ANSI codes _[`#290`](#290) [`bf465de`](bf465de) [@yamcodes](https://github.com/yamcodes)_ Replace Node.js `util.styleText` with cross-platform ANSI color codes to fix the "Module 'node:util' has been externalized for browser compatibility" error in browser environments. The library still maintains zero dependencies! **Changes:** - Replaced `node:util.styleText` with custom ANSI implementation - Added environment detection (uses ANSI in Node, plain text in browsers) - Respects `NO_COLOR`, `CI` environment variables, and TTY detection - Organized utilities into `lib/` folder with comprehensive tests ```ts // No longer throws "node:util has been externalized" error import { createEnv } from "arkenv"; const env = createEnv({ VITE_API_URL: "string", VITE_PORT: "number.port", }); ``` ## @arkenv/vite-plugin@0.0.15 ### Patch Changes <details><summary>Updated 1 dependency</summary> <small> [`7236cb2`](7236cb2) [`bf465de`](bf465de) </small> - `arkenv@0.7.4` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR contains the following updates: | Package | Change | Age | Confidence | |---|---|---|---| | [arkenv](https://arkenv.js.org) ([source](https://redirect.github.com/yamcodes/arkenv)) | [`0.7.3` -> `0.7.4`](https://renovatebot.com/diffs/npm/arkenv/0.7.3/0.7.4) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>yamcodes/arkenv (arkenv)</summary> ### [`v0.7.4`](https://redirect.github.com/yamcodes/arkenv/releases/tag/arkenv%400.7.4) [Compare Source](https://redirect.github.com/yamcodes/arkenv/compare/arkenv@0.7.3...arkenv@0.7.4) ##### Patch Changes - #### Enable minification to reduce bundle size *[`#336`](https://redirect.github.com/yamcodes/arkenv/pull/336) [`7236cb2`](https://redirect.github.com/yamcodes/arkenv/commit/7236cb25de07f7afcc571dd3364b1507544de523) [@​yamcodes](https://redirect.github.com/yamcodes)* Enable minification in build output. Reduces bundle size from 711 B to 708 B. Comments are removed from the bundle but remain in source files. - #### Fix browser compatibility by replacing `util.styleText` with cross-platform ANSI codes *[`#290`](https://redirect.github.com/yamcodes/arkenv/pull/290) [`bf465de`](https://redirect.github.com/yamcodes/arkenv/commit/bf465dee26cd20619455bcc77f66424ca48da0fe) [@​yamcodes](https://redirect.github.com/yamcodes)* Replace Node.js `util.styleText` with cross-platform ANSI color codes to fix the "Module 'node:util' has been externalized for browser compatibility" error in browser environments. The library still maintains zero dependencies! **Changes:** - Replaced `node:util.styleText` with custom ANSI implementation - Added environment detection (uses ANSI in Node, plain text in browsers) - Respects `NO_COLOR`, `CI` environment variables, and TTY detection - Organized utilities into `lib/` folder with comprehensive tests ```ts // No longer throws "node:util has been externalized" error import { createEnv } from "arkenv"; const env = createEnv({ VITE_API_URL: "string", VITE_PORT: "number.port", }); ``` </details> --- ### Configuration 📅 **Schedule**: Branch creation - "on friday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/yamcodes/arkenv). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNzMuMSIsInVwZGF0ZWRJblZlciI6IjQxLjE3My4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Fixes #289
Problem
arkenvwas usingnode:util.styleTextfor error formatting, which broke browser compatibility in Vite, Bun, and other frontend environments.Solution
node:util.styleTextwith cross-platform ANSI color codesstyle-text.tsutility that detects Node vs browser environmentsChanges
Testing
Tested in:
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation