Fix npm publish to ship compiled dist binary - #152
Merged
Conversation
package.json declared bin markpost=./dist/index.js but dist/ is gitignored with no files allowlist and no build hook before publish, so npm publish packed src/ and tests/ instead of dist/, shipping a package with no working binary. - Add a files field allowlisting dist so it's the only source included in the published tarball (verified with npm pack: 76 files / 190.2kB before, 54 files / 81.1kB after, now containing dist/* including dist/index.js instead of src/tests). - Add prepack: clean dist/ (portable node fs.rmSync, no new dependency) then npm run build, so a stale file from a deleted/renamed source module never survives into the tarball. prepack (not prepublishOnly) so it also covers npm pack, the exact command used to verify this. - Add postpack: assert dist/index.js exists, so a skipped-scripts publish fails loudly instead of shipping an empty package. - Add tests/package.test.ts asserting package.json keeps every bin target's directory in files, and a prepack/prepublishOnly hook that cleans that directory before running the build, so this can't silently regress. Derives the checks from bin/files entries (handles bin as a map or string, and files entries like dist/, /dist, dist/**) rather than hardcoding 'dist', so the guard still holds if the output directory or files syntax ever changes. Closes #146
Collaborator
Author
Independent code review trail (3 rounds)Round 1 — flagged:
Round 2 — flagged:
Round 3 — flagged:
Unresolved after 3 rounds: none outstanding — every actionable finding from round 3 was fixed or has a stated reason above. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
package.jsondeclaredbin.markpostas./dist/index.js, butdist/is gitignored, there was nofilesallowlist, no.npmignore, and noprepublishOnly/prepackbuild step.npm publishtherefore packed the repo's source tree (src/,tests/) instead ofdist/, shipping a package whose declared binary doesn't exist.files: ["dist"]so the published tarball only containsdist/(plus npm's always-includedpackage.json/README.md).prepack: cleandist/(portablenode:fsrmSync, no new dependency needed) thennpm run build. Usedprepackrather thanprepublishOnlybecauseprepackalso fires on plainnpm pack— the exact command used to verify this fix — and on git-based installs;prepublishOnlyonly fires onnpm publish.postpack: assertdist/index.jsexists on disk after packing, so a skipped-scripts publish fails loudly instead of silently shipping an empty package.tests/package.test.tswith three tests:package.json'sfilesfield allowlists everybintarget's top-level directory (handlesbinas a map or string, andfilesentries likedist/,/dist,dist/**).prepack/prepublishOnlyhook actually removes that directory (rm -rf,rimraf, orrmSync) before rebuilding — not just mentioning the directory name.npm pack --dry-run --json(which triggers the realprepack/build lifecycle) and asserts everybintarget is actually present in the packed file list.Verification
npm run buildproducesdist/index.js.npm pack(not dry-run) produces a tarball containingpackage/dist/index.js.npm pack --dry-run→ 76 files, 190.2 kB, nodist/. After: 54 files, 81.0 kB,dist/*only (nosrc//tests/).npm run lint,npm run typecheck, andnpm run test:ci(840 tests, 29 files) all pass.Where to view
package.json(root)tests/package.test.tsNo new env vars, services, or external setup required.
Closes #146