diff --git a/source/npm/util.js b/source/npm/util.js index 4dfdc675..f537e517 100644 --- a/source/npm/util.js +++ b/source/npm/util.js @@ -210,6 +210,7 @@ export const getFilesToBePacked = async rootDirectory => { '--dry-run', '--json', '--silent', + '--ignore-scripts', // TODO: Remove this once [npm/cli#7354](https://github.com/npm/cli/issues/7354) is resolved. '--foreground-scripts=false', ], {cwd: rootDirectory}); @@ -226,6 +227,21 @@ export const getFilesToBePacked = async rootDirectory => { } }; +const hasPackLifecycleScript = package_ => { + const {scripts} = package_; + + if (typeof scripts !== 'object' || scripts === null) { + return false; + } + + return [ + 'prepare', + 'prepack', + 'prepublish', + 'prepublishOnly', + ].some(scriptName => typeof scripts[scriptName] === 'string'); +}; + const isValidEntryPoint = value => typeof value === 'string' && !value.includes('*'); const getExportsFiles = exports => { @@ -295,6 +311,10 @@ export const verifyPackageEntryPoints = async (package_, rootDirectory) => { } if (missingEntryPoints.length > 0) { + if (hasPackLifecycleScript(package_)) { + return; + } + const missing = missingEntryPoints.map(({field, path: entryPath}) => ` "${field}": ${entryPath}`).join('\n'); throw new Error(`Missing entry points in published files:\n${missing}\n\nEnsure these files exist and are included in the "files" field.`); } diff --git a/test/fixtures/files/failing-prepack-script/index.js b/test/fixtures/files/failing-prepack-script/index.js new file mode 100644 index 00000000..81afa315 --- /dev/null +++ b/test/fixtures/files/failing-prepack-script/index.js @@ -0,0 +1 @@ +console.log('foo'); diff --git a/test/fixtures/files/failing-prepack-script/package.json b/test/fixtures/files/failing-prepack-script/package.json new file mode 100644 index 00000000..7e1ab4f5 --- /dev/null +++ b/test/fixtures/files/failing-prepack-script/package.json @@ -0,0 +1,8 @@ +{ + "name": "foo", + "version": "0.0.0", + "files": ["index.js"], + "scripts": { + "prepack": "exit 1" + } +} diff --git a/test/fixtures/files/prepack-generated-entry-point/package.json b/test/fixtures/files/prepack-generated-entry-point/package.json new file mode 100644 index 00000000..56ea4562 --- /dev/null +++ b/test/fixtures/files/prepack-generated-entry-point/package.json @@ -0,0 +1,9 @@ +{ + "name": "prepack-generated-entry-point", + "version": "0.0.0", + "main": "dist/index.js", + "files": ["dist"], + "scripts": { + "prepack": "node --input-type=module -e \"import fs from 'node:fs'; fs.mkdirSync('dist', {recursive: true}); fs.writeFileSync('dist/index.js', 'export default 1;\\n');\"" + } +} diff --git a/test/fixtures/files/prepare-script/package.json b/test/fixtures/files/prepare-script/package.json index 5a121c9b..d4140564 100644 --- a/test/fixtures/files/prepare-script/package.json +++ b/test/fixtures/files/prepare-script/package.json @@ -3,6 +3,6 @@ "version": "0.0.0", "files": ["index.js"], "scripts": { - "prepare": "echo '> foo@0.0.0 prepare' && echo '> test prepare script'" + "prepare": "echo '[build] compiling'" } } diff --git a/test/npm/util/entry-points.js b/test/npm/util/entry-points.js index 478a765d..f80347c3 100644 --- a/test/npm/util/entry-points.js +++ b/test/npm/util/entry-points.js @@ -191,3 +191,14 @@ test('verifyPackageEntryPoints - valid entry points', async t => { await t.notThrowsAsync(npm.verifyPackageEntryPoints({main: 'index.js'}, fixtureDirectory)); }); + +test('verifyPackageEntryPoints - skipped when prepack script may generate files', async t => { + const fixtureDirectory = getFixture('prepack-generated-entry-point'); + + await t.notThrowsAsync(npm.verifyPackageEntryPoints({ + main: 'dist/index.js', + scripts: { + prepack: 'build', + }, + }, fixtureDirectory)); +}); diff --git a/test/npm/util/packed-files.js b/test/npm/util/packed-files.js index 8ef1e72c..5924a69b 100644 --- a/test/npm/util/packed-files.js +++ b/test/npm/util/packed-files.js @@ -74,3 +74,7 @@ test('doesn\'t show files in .github', verifyPackedFiles, 'dot-github', [ test('handles prepare script output (e.g., Husky)', verifyPackedFiles, 'prepare-script', [ 'index.js', ]); + +test('ignores failing prepack script', verifyPackedFiles, 'failing-prepack-script', [ + 'index.js', +]);