Repository navigation
Tags: privatenumber/pkgroll
Tags
fix: unwrap default exports from external modules in CommonJS output BREAKING CHANGE: CommonJS output now unwraps the default export from external modules marked with `__esModule`, including ES modules loaded via `require()`. Remove `.default` access used to work around the previous behavior.
test(watch): extract waitForOutput helper
## Problem
The two `pkgroll --watch` integration tests (`builds › watch › rebuilds
on package.json change` and `builds › import attributes › watch mode ›
rebuilds when imported text file changes`) intermittently fail on
Windows CI with `AbortError: The operation was aborted due to timeout`
while waiting for the first `Built` message.
The waits used a 15 s `AbortSignal.timeout`. Cold `pkgroll --watch`
startup on Windows runners (Node boot + native type stripping + loading
Rollup/esbuild/plugins off disk + the first Rollup pass) occasionally
exceeds that, and the existing `{ retry: 3 }` on the import-attributes
test runs out of attempts.
Local example timings from a recent failed CI run:
| Test | Timeout | Actual |
|---|---|---|
| `import attributes › watch mode › rebuilds…` | 15 s | 16.1 s ✘ (after
3 retries) |
| `watch › rebuilds on package.json change` | 15 s | 15.6 s ✘ |
## Changes
- Extract `waitForOutput(subprocess, pattern, timeout?)` from
`tests/specs/builds/watch.ts` into the shared `tests/utils.ts`. Both
watch tests now use it.
- Raise the default timeout from 15 s to 30 s. The 30 s budget is
calibrated for the slowest legitimate case (cold Windows CI startup);
macOS local typically finishes in well under a second.
- Warm rebuild waits in `import-attributes.ts` pass `15_000` explicitly
— those should remain tight to catch real regressions.
fix: add .jsx → .ts resolution fallback ## Problem `resolveJsToTs` only produced one TS extension per JS extension (via regex `/js(x?)$/ → ts$1`): - `.js` → `.ts` only (missing `.tsx` fallback) - `.jsx` → `.tsx` only (missing `.ts` fallback) ## Changes - Replace single-rewrite regex with explicit extension map trying all TS candidates (`.js` → `.ts`, `.tsx`; `.jsx` → `.tsx`, `.ts`) - Catch errors from `externalizeDependencies` during bare specifier TS fallback - Remove redundant `console.error` before throw for unresolvable devDeps - Add tests for `.jsx` → `.ts` and `.js` → `.tsx` resolution
fix: resolve bare specifier .js through exports map before trying .ts ## Problem `resolveJsToTs` plugin eagerly transforms bare specifiers (package imports like `dep/file.js`) from `.js` to `.ts` when the importer is outside `node_modules`. This breaks resolution in two ways: 1. **Wildcard exports**: The `.ts` specifier feeds into wildcard patterns (`./*` → `./dist/*.js`), causing the wildcard to capture `.ts` and produce invalid paths like `dist/file.ts.js` (ENOENT) 2. **Preference inversion**: When a package ships both `.js` and `.ts` files, bare specifiers incorrectly resolve to `.ts` instead of preferring the compiled `.js` Both esbuild and TypeScript apply `.js` → `.ts` rewriting as a **last-resort fallback on the resolved filesystem path**, not on the specifier before exports map resolution: - esbuild `resolver.go:2651-2670`: checks file existence after exports map, tries `.ts` only if `.js` missing - TypeScript `moduleNameResolver.ts:2112-2128`: `loadFileNameFromPackageJsonField` applies `.js` → `.ts` on resolved target ## Changes **`src/rollup/plugins/resolve-js-to-ts.ts`**: Add `isBareSpecifier(id)` check so bare specifiers use the `.js`-first resolution path (try `.js` through exports map, fallback to `.ts`). Source code relative imports (`./file.js` → `./file.ts`) still prefer `.ts` first. **`tests/specs/builds/resolve-js-to-ts.ts`**: 6 test cases: - Relative `./file.js` → `./file.ts` in source code (regression guard) - Bare specifier + wildcard exports (was ENOENT, now passes) - Scoped package (`@scope/dep`) + wildcard exports - `.mjs` bare specifier + wildcard exports - Bare specifier + dep ships both `.js` and `.ts` (was wrong preference, now correct) - Bare specifier + dep ships only `.ts` (fallback preserved) ## Test plan - [x] All 6 new resolve-js-to-ts tests pass - [x] Full test suite passes (254 tests) - [x] Lint clean on changed files
feat: add --packagejson flag to filter package.json entry points ## Problem When using `pkgroll -i dist/index.d.mts` to build only types, pkgroll still parses ALL package.json entry points. If exports reference non-JS files (e.g. CSS modules), the dts bundler tries to parse them and fails with "Expression expected". ## Changes - Add `--packagejson` CLI flag to filter which package.json entry points are built, matching against output paths with glob patterns - `--packagejson=false` skips all package.json entry points entirely - Patterns without slashes match against basename (`*.d.ts` matches `dist/index.d.ts`) - Patterns with slashes match against full output path (`dist/utils.*`) ### Usage ```sh # Skip all package.json entries (use with -i) pkgroll --packagejson=false -i dist/index.d.mts # Only build type declarations pkgroll --packagejson='*.d.ts' # Only build ESM outputs pkgroll --packagejson='*.mjs' # Multiple patterns pkgroll --packagejson='*.d.ts' --packagejson='*.mjs' # Match specific files by path pkgroll --packagejson='dist/utils.*' ```
PreviousNext