diff --git a/package.json b/package.json index 5d0fbe75..7e6f4f3f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "main": "out/src/index.js", "types": "out/src/index.d.ts", + "gypfile": false, "scripts": { "build:asan": "node-gyp configure build --jobs=max --address_sanitizer", "build:tsan": "node-gyp configure build --jobs=max --thread_sanitizer", diff --git a/ts/test/test-no-build-scripts.ts b/ts/test/test-no-build-scripts.ts index 4aee2b12..cb7ba35f 100644 --- a/ts/test/test-no-build-scripts.ts +++ b/ts/test/test-no-build-scripts.ts @@ -3,12 +3,23 @@ import * as fs from 'fs'; import * as path from 'path'; describe('package manifest', () => { + const manifest = path.join(__dirname, '..', '..', 'package.json'); + const pkg = JSON.parse(fs.readFileSync(manifest, 'utf8')); + it('declares no npm build lifecycle scripts (Yarn Berry YN0007)', () => { - const manifest = path.join(__dirname, '..', '..', 'package.json'); - const pkg = JSON.parse(fs.readFileSync(manifest, 'utf8')); const scripts = pkg.scripts || {}; const hooks = ['preinstall', 'install', 'postinstall']; const present = hooks.filter(name => scripts[name] !== undefined); assert.deepStrictEqual(present, []); }); + + it('opts out of node-gyp on install via gypfile:false (npm implicit rebuild)', () => { + // binding.gyp lives in the dev tree (excluded from the published tarball). + // Without gypfile:false, npm's publish-time normalization synthesizes + // "gypfile": true and "install": "node-gyp rebuild" into the registry + // manifest, so consumers run node-gyp rebuild against a missing + // binding.gyp and the install fails. Pinning gypfile:false suppresses + // that hook while keeping the manifest free of lifecycle scripts. + assert.strictEqual(pkg.gypfile, false); + }); });