diff --git a/README.md b/README.md index c31bd56..f5da944 100644 --- a/README.md +++ b/README.md @@ -287,6 +287,17 @@ Or to inline them in the distribution files: pkgroll --sourcemap=inline ``` +## Dev vs Prod config + +In some cases, it makes sense to use different `package.json` field values for the published environment. You can achieve this by using the [`publishConfig`](https://pnpm.io/package_json#publishconfig) field (extended by pnpm). This allows you to override specific fields during publication with a clean separation of concerns. + +The following fields can be overridden using `publishConfig`: +- `bin` +- `main` +- `exports` +- `types` +- `module` + ## FAQ ### Why bundle with Rollup? diff --git a/src/utils/parse-package-json/get-export-entries.ts b/src/utils/parse-package-json/get-export-entries.ts index 5ec6209..1500d17 100644 --- a/src/utils/parse-package-json/get-export-entries.ts +++ b/src/utils/parse-package-json/get-export-entries.ts @@ -142,12 +142,35 @@ const addExportPath = ( } }; -export const getExportEntries = (packageJson: PackageJson) => { +export const getExportEntries = ( + _packageJson: Readonly, +) => { + const packageJson = { ..._packageJson }; + + // Prefer publishConfig when defined + // https://pnpm.io/package_json#publishconfig + const { publishConfig } = packageJson; + if (publishConfig) { + const fields = [ + 'bin', + 'main', + 'exports', + 'types', + 'module', + ]; + + for (const field of fields) { + if (publishConfig[field]) { + packageJson[field] = publishConfig[field]; + } + } + } + const exportEntriesMap: Record = {}; const packageType = packageJson.type ?? 'commonjs'; - if (packageJson.main) { - const mainPath = packageJson.main; + const mainPath = packageJson.main; + if (mainPath) { addExportPath(exportEntriesMap, { outputPath: mainPath, type: getFileType(mainPath) ?? packageType, @@ -174,9 +197,8 @@ export const getExportEntries = (packageJson: PackageJson) => { }); } - if (packageJson.bin) { - const { bin } = packageJson; - + const { bin } = packageJson; + if (bin) { if (typeof bin === 'string') { addExportPath(exportEntriesMap, { outputPath: bin, diff --git a/tests/specs/builds/bin.ts b/tests/specs/builds/bin.ts index 37f363f..a229640 100644 --- a/tests/specs/builds/bin.ts +++ b/tests/specs/builds/bin.ts @@ -79,5 +79,27 @@ export default testSuite(({ describe }, nodePath: string) => { const content = await fixture.readFile('dist/dynamic-require.mjs', 'utf8'); expect(content.startsWith('#!/usr/bin/env node')).toBeTruthy(); }); + + test('publishConfig', async () => { + await using fixture = await createFixture({ + ...packageFixture(), + 'package.json': createPackageJson({ + bin: './dist/invalid.mjs', + publishConfig: { + bin: './dist/index.mjs', + }, + }), + }); + + const pkgrollProcess = await pkgroll([], { + cwd: fixture.path, + nodePath, + }); + + expect(pkgrollProcess.exitCode).toBe(0); + expect(pkgrollProcess.stderr).toBe(''); + + expect(await fixture.exists('dist/index.mjs')).toBe(true); + }); }); }); diff --git a/tests/specs/builds/package-exports.ts b/tests/specs/builds/package-exports.ts index 0a198e9..8e81aa2 100644 --- a/tests/specs/builds/package-exports.ts +++ b/tests/specs/builds/package-exports.ts @@ -207,5 +207,28 @@ export default testSuite(({ describe }, nodePath: string) => { await fixture.exists('dist/nested/index.node.js'); await fixture.exists('dist/nested/index.node.d.ts'); }); + + test('publishConfig', async () => { + await using fixture = await createFixture({ + ...packageFixture(), + 'package.json': createPackageJson({ + exports: './dist/invalid.js', + publishConfig: { + exports: './dist/index.js', + }, + }), + }); + + const pkgrollProcess = await pkgroll([], { + cwd: fixture.path, + nodePath, + }); + + expect(pkgrollProcess.exitCode).toBe(0); + expect(pkgrollProcess.stderr).toBe(''); + + const content = await fixture.readFile('dist/index.js', 'utf8'); + expect(content).toMatch('module.exports ='); + }); }); });