PR: ESM Migration, Vite 8 Upgrade, and Dependency Overhaul#1649
PR: ESM Migration, Vite 8 Upgrade, and Dependency Overhaul#1649raineorshine merged 36 commits intoraineorshine:mainfrom
Conversation
- update vite config - use lodash-es instead of lodash - use memoize instead of old fast-memoize
ES Modules cannot be stubbed To allow stubbing of npm functions in tests, we export the functions that need to be stubbed as properties of an object (npmApi, pnpmApi, yarnApi) that can be imported and stubbed in tests without affecting the rest of the module. (+1 squashed commits) use tsx instead of ts-node with mocha
…rning: `url.parse()` in node 24
…ch is a built-in module in node
- Update major devDependencies to latest. - Remove `legacy-peer-deps=true` to ensure strict, modern resolution. - Implement surgical `overrides` to resolve peer dependency conflicts across the ESLint, Microsoft, and Verdaccio toolchains. - Fix hoisting issue where `ajv/dist/core` was missing in nested node_modules under Node 25.
- Remove legacy __dirname in favor of getDirname(import.meta.url). - Enable Mocha --exit to ensure clean termination on Node 25. - Clean up listener guards and diagnostic hooks. - Successfully verified 530+ tests across modern Node environments.
update vite config remove unused nodeExternals, we see ssr.noExternal=true so we don't want to exclude node modules from the bundle
update export use tsx instead of vite-node
…ation warning: `url.parse()` in node 24" The issue was fixed in parse-github-url v1.0.4 This reverts commit 02e99e4.
- Replace custom 'test/bun-install.sh' with 'oven-sh/setup-bun@v2' action. - Add 'check-environment' before-hook to provide helpful install links. - Fix TypeScript 'Property does not exist' errors via namespace imports. - Resolve ESLint 'Parsing error' in VS Code using tsconfigRootDir. - Update test logic to use node:child_process for better cross-platform compatibility.
Update resolveConfig to use a file path instead of a directory to correctly load .prettierrc.json in ESM.
Re-generate src/types/RunOptions.json with correct project formatting.
Fixes pre-push hook failures caused by formatting mismatches.
Update mocha configuration to ignore test/bun/* during unit tests. This prevents CI failures in environments where Bun is not yet installed.
Build: Update Vite config to use explicit output arrays for es and cjs formats.
Build: Force .cjs extensions for CommonJS chunks to prevent Node.js from parsing them as ESM in "type: module" projects.
E2E: Fix TypeError in ESM E2E tests by aligning namespace imports with the new build output.
E2E: Add Windows fallback for lsof in test/e2e.sh using netstat and taskkill to allow local registry cleanup on Windows 11.
|
let me know if there are any documentation that need update |
- Update CONTRIBUTING.md with source map documentation - Add Development section with Node.js requirements and test instructions - Update Executable Stack Trace section to reflect generated source maps - Add v21.0.0 entry to CHANGELOG.md documenting breaking changes - Add Requirements section to README.md with Node.js and npm version constraints
|
check the updates in ab34e63 |
| { | ||
| /** | ||
| * Because this function depends on both the first object AND the options object, | ||
| * we must provide a cacheKey. Modern memoize provides both args in an array. | ||
| */ | ||
| cacheKey: ([configs, options]) => { | ||
| return JSON.stringify([configs, options.packageFile, options.cwd, options.registry, options.timeout]) | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Explicit cache keys are going to be fragile and hard to maintain. If the function changes to use additional options in the future, there is no compile-time check to ensure these cache keys stay in sync, resulting in hard-to-catch caching bugs.
Instead, we should use a default serializer like fast-memoize did. Perhaps JSON.stringify would suffice?
There was a problem hiding this comment.
You also use JSON.stringify in fetchUpgradedPackumentMemo
do you want to modify both
by Perhaps JSON.stringify would suffice did you mean JSON.stringify([configs, options])
There was a problem hiding this comment.
Just cacheKey: JSON.stringify I believe. You can use this same pattern in all the memoize calls to preserve the existing behavior and avoid explicitly listing the inputs.
There was a problem hiding this comment.
see 5251ef2
I have based it on memoize docs
I have just noticed that memoize V11.0.0 use node >= 22
currently we have "node": "^20.19.0 || ^22.12.0 || >=24.0.0" in package.json
There was a problem hiding this comment.
I don't like how much this is veering from fast-memoize unfortunately. This was supposed to just be an esm upgrade, and switching from fast-memoize to memoize with a different cache key approach is out of scope/too much risk for this PR.
I think the safest move would be to switch back to fast-memoize. I would be happy to discuss alternative memoization strategies in a separate PR.
…n filtering This change refactors the caching and memoization logic across package managers to be more robust, performant, and maintainable: - Introduces `getCacheableOptions` in `src/lib/cache.ts` to prepare a flattened array of options suitable for cache keys, automatically excluding non-serializable fields like `packageData` and `cacher`. - Migrates memoized functions in `npm.ts`, `yarn.ts`, and `pnpm.ts` to use `many-keys-map`. This allows the use of arrays as keys and supports referential equality for functional predicates and objects, eliminating the overhead and potential fragility of `JSON.stringify`. - Refines `staticRegistry.ts` to use a surgical cache key (the registry path) to ensure the registry is only parsed once per command execution, regardless of changes to unrelated options. - Updates documentation and comments to clarify caching strategies, specifically regarding workspace-aware key exclusions like `packageFile`.
|
I think this is ready Don't forget to update |
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [npm-check-updates](https://github.com/raineorshine/npm-check-updates) | [`^19.6.6` → `^21.0.0`](https://renovatebot.com/diffs/npm/npm-check-updates/19.6.6/21.0.3) |  |  | --- ### Release Notes <details> <summary>raineorshine/npm-check-updates (npm-check-updates)</summary> ### [`v21.0.3`](https://github.com/raineorshine/npm-check-updates/releases/tag/v21.0.3) [Compare Source](raineorshine/npm-check-updates@v21.0.2...v21.0.3) #### What's Changed - fix: chmod build/cli.js executable after vite build by [@​raineorshine](https://github.com/raineorshine) in [#​1678](raineorshine/npm-check-updates#1678) - fix: migrate from rc-config-loader to cosmiconfig for ESM config support (closes [#​1674](raineorshine/npm-check-updates#1674)) by [@​onemen](https://github.com/onemen) in [#​1676](raineorshine/npm-check-updates#1676) **Full Changelog**: <raineorshine/npm-check-updates@v21.0.2...v21.0.3> ### [`v21.0.2`](https://github.com/raineorshine/npm-check-updates/releases/tag/v21.0.2) [Compare Source](raineorshine/npm-check-updates@v21.0.1...v21.0.2) #### What's Changed - fix: skip intersects() for non-semver specs like catalog: in peer dep checks by [@​terminalchai](https://github.com/terminalchai) in [#​1675](raineorshine/npm-check-updates#1675) **Full Changelog**: <raineorshine/npm-check-updates@v21.0.1...v21.0.2> ### [`v21.0.1`](https://github.com/raineorshine/npm-check-updates/releases/tag/v21.0.1) [Compare Source](raineorshine/npm-check-updates@v21.0.0...v21.0.1) #### What's Changed - fix: seeing catalog when inside workspaces by [@​Zamiell](https://github.com/Zamiell) in [#​1656](raineorshine/npm-check-updates#1656) - Bump [@​types/bun](https://github.com/types/bun) from 1.3.11 to 1.3.12 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1663](raineorshine/npm-check-updates#1663) - Bump globals from 17.4.0 to 17.5.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1664](raineorshine/npm-check-updates#1664) - Bump [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) from 8.58.1 to 8.58.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1665](raineorshine/npm-check-updates#1665) - Bump prettier from 3.8.1 to 3.8.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1667](raineorshine/npm-check-updates#1667) - Bump verdaccio from 6.4.0 to 6.5.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1669](raineorshine/npm-check-updates#1669) - Bump sinon from 21.0.3 to 21.1.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1668](raineorshine/npm-check-updates#1668) - Skip CI on PRs with no file changes by [@​Copilot](https://github.com/Copilot) in [#​1672](raineorshine/npm-check-updates#1672) - Bump [@​typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/eslint-plugin) from 8.58.1 to 8.58.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1666](raineorshine/npm-check-updates#1666) - Fix wrong message when all packages are within cooldown window by [@​Copilot](https://github.com/Copilot) in [#​1671](raineorshine/npm-check-updates#1671) **Full Changelog**: <raineorshine/npm-check-updates@v21.0.0...v21.0.1> ### [`v21.0.0`](https://github.com/raineorshine/npm-check-updates/blob/HEAD/CHANGELOG.md#2100---2026-04-14) [Compare Source](raineorshine/npm-check-updates@v20.0.2...v21.0.0) #####⚠️ Breaking Changes This is a **major breaking change** with significant architectural updates. ##### ESM Migration & Module System - **Pure ESM:** Converted to pure ESM with dual-build support (ESM/CJS) via Vite 8. - **Import Syntax:** Programmatic usage now requires named imports or namespace imports. - **Old:** `import ncu from 'npm-check-updates'` - **New:** `import * as ncu from 'npm-check-updates'` or `import { run } from 'npm-check-updates'` - **Node.js Requirements:** Now requires `^20.19.0 || ^22.12.0 || >=24.0.0`. This is required for native `require(esm)` support and the Rolldown engine. - **npm Requirements:** Minimum version increased to `>=10.0.0`. ##### Configuration Files (`.ncurc.js`) - Files named `.ncurc.js` that use `module.exports` will now fail in projects that are `"type": "module"`. - **Fix:** Rename these files to `.ncurc.cjs` or convert them to use `export default`. ##### Dependency Updates (Pure ESM versions) | Package | Old Version | New Version | | :----------------- | :---------- | :---------- | | `camelcase` | `^6.3.0` | `^9.0.0` | | `chai` | `^4.3.10` | `^6.2.2` | | `chai-as-promised` | `^7.1.2` | `^8.0.2` | | `find-up` | `5.0.0` | `8.0.0` | | `p-map` | `^4.0.0` | `^7.0.4` | | `untildify` | `^4.0.0` | `^6.0.0` | ##### Tooling & Build Changes - **Vite 8 Upgrade:** Migrated to Vite 8 with the new Rust-based **Rolldown** bundler (10-30x faster builds). - **TypeScript 6.0:** Adopted latest type-system features and performance improvements. - **Strip ANSI:** Replaced `strip-ansi` with Node.js built-in `util.stripVTControlCharacters`. - **Test Runner:** Replaced `vite-node` with `tsx` for TypeScript support in ESM context. *** ##### Migration Guide If you are upgrading to v21 from earlier versions: ##### 1. Environment Check - Ensure you meet the new Node.js requirement: `^20.19.0 || ^22.12.0 || >=24.0.0`. - Update npm to at least `10.0.0`. ##### 2. Update Configuration Files If you have a `.ncurc.js` file: - **Option A:** Rename it to `.ncurc.cjs`. - **Option B:** Convert it to ESM: ```js import { defineConfig } from 'npm-check-updates' export default defineConfig({ upgrade: true, filter: name => name.startsWith('@​myorg/'), }) ``` ##### 3. Update Programmatic Usage If you import `npm-check-updates` in your scripts: - **ESM:** Change `import ncu from ...` to `import * as ncu from 'npm-check-updates'`. - **CommonJS:** Ensure you are destructuring the named exports or using the full object: ```js const ncu = require('npm-check-updates') // Use ncu.run(...) ``` *** ##### Testing Tests now use `tsx` for module loading. When running tests manually: ```sh mocha --node-option import=tsx 'test/**/*.test.ts' ``` Or use the npm script: ```sh npm test ``` ##### Related Issues & PRs [PR 1649](raineorshine/npm-check-updates#1649) *** ### [`v20.0.2`](https://github.com/raineorshine/npm-check-updates/releases/tag/v20.0.2) [Compare Source](raineorshine/npm-check-updates@v20.0.1...v20.0.2) #### What's Changed - Show auto-detected cooldown source at normal log level; fix test isolation by [@​bayraak](https://github.com/bayraak) in [#​1662](raineorshine/npm-check-updates#1662) #### New Contributors - [@​bayraak](https://github.com/bayraak) made their first contribution in [#​1662](raineorshine/npm-check-updates#1662) **Full Changelog**: <raineorshine/npm-check-updates@v20.0.1...v20.0.2> ### [`v20.0.1`](https://github.com/raineorshine/npm-check-updates/releases/tag/v20.0.1) [Compare Source](raineorshine/npm-check-updates@v20.0.0...v20.0.1) #### What's Changed - Add CI workflow to verify build output is committed by [@​Copilot](https://github.com/Copilot) in [#​1645](raineorshine/npm-check-updates#1645) - Bump lodash-es from 4.17.23 to 4.18.1 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1647](raineorshine/npm-check-updates#1647) - Add Node v24 to test workflow by [@​Copilot](https://github.com/Copilot) in [#​1608](raineorshine/npm-check-updates#1608) - feat: remove pre-push git hook by [@​Zamiell](https://github.com/Zamiell) in [#​1658](raineorshine/npm-check-updates#1658) - feat: add verbose output when packages are skipped due to cooldown by [@​Copilot](https://github.com/Copilot) in [#​1659](raineorshine/npm-check-updates#1659) **Full Changelog**: <raineorshine/npm-check-updates@v20.0.0...v20.0.1> ### [`v20.0.0`](https://github.com/raineorshine/npm-check-updates/blob/HEAD/CHANGELOG.md#2000---2026-03-31) [Compare Source](raineorshine/npm-check-updates@v19.6.6...v20.0.0) ##### Auto Cooldown The cooldown option is now automatically applied from the respective package manager's config: - **npm** - `min-release-age` ([#​1632](raineorshine/npm-check-updates#1632)) - **yarn** - `npmMinimalAgeGate` (excluding `npmPreapprovedPackages`) ([#​1643](raineorshine/npm-check-updates#1643)) - **pnpm** - `minimumReleaseAge` (excluding `minimumReleaseAgeExclude`) ([#​1639](raineorshine/npm-check-updates#1639)) Why is this a breaking change? - If you use any of the above configs, npm-check-updates will automatically exclude releases that do not exceed the specified minimum age as described in <https://github.com/raineorshine/npm-check-updates#cooldown>. - Otherwise, you don't need to do anything. ##### Other changes - Bump strip-ansi from 7.1.2 to 7.2.0 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1620](raineorshine/npm-check-updates#1620) - Bump lodash and [@​types/lodash](https://github.com/types/lodash) by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1615](raineorshine/npm-check-updates#1615) - Bump [@​typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/eslint-plugin) from 8.44.1 to 8.57.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1619](raineorshine/npm-check-updates#1619) - Bump hosted-git-info from 9.0.0 to 9.0.2 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1622](raineorshine/npm-check-updates#1622) - Bump glob and markdownlint-cli by [@​dependabot](https://github.com/dependabot)\[bot] in [#​1625](raineorshine/npm-check-updates#1625) - update dependencies; fix vulnerabilities by [@​onemen](https://github.com/onemen) in [#​1630](raineorshine/npm-check-updates#1630) - Potential fix for code scanning alert no. 13: Incomplete string escaping or encoding by [@​raineorshine](https://github.com/raineorshine) in [#​1640](raineorshine/npm-check-updates#1640) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - 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 has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjEuMCIsInVwZGF0ZWRJblZlciI6IjQzLjEzNy4wIiwidGFyZ2V0QnJhbmNoIjoibmV4dCIsImxhYmVscyI6W119--> Reviewed-on: https://git.valverde.cloud/Thilawyn/effect-fc/pulls/46 Co-authored-by: Renovate Bot <renovate-bot@valverde.cloud> Co-committed-by: Renovate Bot <renovate-bot@valverde.cloud>
Description
This PR transitions the project to a native ESM architecture while maintaining dual-build support (ESM/CJS) via Vite. It includes a major overhaul of the development toolchain, upgrading core dependencies to their 2026 standards, and significantly modernizing the internal logic.
Key Changes
tsxfor module loading (e.g., via--import tsx), ensuring seamless TypeScript support in an ESM context.ts-json-schema-generatorand implemented in-process Prettier formatting.vite buildand replacedvite-nodewithtsx.strip-ansiwith the Node.js built-innode:util/stripVTControlCharacters.typechecktopre-pushhooks and the linting action.This is a major breaking change and requires a major version bump:
require(esm)support and the Rolldown engine.camelcase^6.3.0^9.0.0chai^4.3.10^6.2.2chai-as-promised^7.1.2^8.0.2find-up5.0.08.0.0p-map^4.0.0^7.0.4untildify^4.0.0^6.0.0Note on Mocha +
tsxSince the project is now ESM, we are using
tsxto handle the TypeScript transformation during test execution. If you are running tests manually, ensure you are using the new command structure:mocha --node-option import=tsx 'test/**/*.test.ts'(or your defined script inpackage.json).