Skip to content

Commit 61d6ce6

Browse files
kwaaprivatenumber
andauthored
feat: support pnpm's publishConfig (#120)
* feat: prefer publish config when defined * refactor: apply suggestion Co-authored-by: Hiroki Osame <[email protected]> * fix(lint): remove trailing spaces * readme * tests --------- Co-authored-by: Hiroki Osame <[email protected]>
1 parent 48753d5 commit 61d6ce6

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,17 @@ Or to inline them in the distribution files:
287287
pkgroll --sourcemap=inline
288288
```
289289

290+
## Dev vs Prod config
291+
292+
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.
293+
294+
The following fields can be overridden using `publishConfig`:
295+
- `bin`
296+
- `main`
297+
- `exports`
298+
- `types`
299+
- `module`
300+
290301
## FAQ
291302

292303
### Why bundle with Rollup?

src/utils/parse-package-json/get-export-entries.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,35 @@ const addExportPath = (
142142
}
143143
};
144144

145-
export const getExportEntries = (packageJson: PackageJson) => {
145+
export const getExportEntries = (
146+
_packageJson: Readonly<PackageJson>,
147+
) => {
148+
const packageJson = { ..._packageJson };
149+
150+
// Prefer publishConfig when defined
151+
// https://pnpm.io/package_json#publishconfig
152+
const { publishConfig } = packageJson;
153+
if (publishConfig) {
154+
const fields = [
155+
'bin',
156+
'main',
157+
'exports',
158+
'types',
159+
'module',
160+
];
161+
162+
for (const field of fields) {
163+
if (publishConfig[field]) {
164+
packageJson[field] = publishConfig[field];
165+
}
166+
}
167+
}
168+
146169
const exportEntriesMap: Record<string, ExportEntry> = {};
147170
const packageType = packageJson.type ?? 'commonjs';
148171

149-
if (packageJson.main) {
150-
const mainPath = packageJson.main;
172+
const mainPath = packageJson.main;
173+
if (mainPath) {
151174
addExportPath(exportEntriesMap, {
152175
outputPath: mainPath,
153176
type: getFileType(mainPath) ?? packageType,
@@ -174,9 +197,8 @@ export const getExportEntries = (packageJson: PackageJson) => {
174197
});
175198
}
176199

177-
if (packageJson.bin) {
178-
const { bin } = packageJson;
179-
200+
const { bin } = packageJson;
201+
if (bin) {
180202
if (typeof bin === 'string') {
181203
addExportPath(exportEntriesMap, {
182204
outputPath: bin,

tests/specs/builds/bin.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,27 @@ export default testSuite(({ describe }, nodePath: string) => {
7979
const content = await fixture.readFile('dist/dynamic-require.mjs', 'utf8');
8080
expect(content.startsWith('#!/usr/bin/env node')).toBeTruthy();
8181
});
82+
83+
test('publishConfig', async () => {
84+
await using fixture = await createFixture({
85+
...packageFixture(),
86+
'package.json': createPackageJson({
87+
bin: './dist/invalid.mjs',
88+
publishConfig: {
89+
bin: './dist/index.mjs',
90+
},
91+
}),
92+
});
93+
94+
const pkgrollProcess = await pkgroll([], {
95+
cwd: fixture.path,
96+
nodePath,
97+
});
98+
99+
expect(pkgrollProcess.exitCode).toBe(0);
100+
expect(pkgrollProcess.stderr).toBe('');
101+
102+
expect(await fixture.exists('dist/index.mjs')).toBe(true);
103+
});
82104
});
83105
});

tests/specs/builds/package-exports.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,5 +207,28 @@ export default testSuite(({ describe }, nodePath: string) => {
207207
await fixture.exists('dist/nested/index.node.js');
208208
await fixture.exists('dist/nested/index.node.d.ts');
209209
});
210+
211+
test('publishConfig', async () => {
212+
await using fixture = await createFixture({
213+
...packageFixture(),
214+
'package.json': createPackageJson({
215+
exports: './dist/invalid.js',
216+
publishConfig: {
217+
exports: './dist/index.js',
218+
},
219+
}),
220+
});
221+
222+
const pkgrollProcess = await pkgroll([], {
223+
cwd: fixture.path,
224+
nodePath,
225+
});
226+
227+
expect(pkgrollProcess.exitCode).toBe(0);
228+
expect(pkgrollProcess.stderr).toBe('');
229+
230+
const content = await fixture.readFile('dist/index.js', 'utf8');
231+
expect(content).toMatch('module.exports =');
232+
});
210233
});
211234
});

0 commit comments

Comments
 (0)