Skip to content

Commit 101f326

Browse files
committed
Support multiple dist configurations
1 parent be4283d commit 101f326

File tree

4 files changed

+79
-43
lines changed

4 files changed

+79
-43
lines changed

action/commands/build.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export declare const buildCommand: import("../command").CommandFactory<{}, {
22
single?: boolean | undefined;
33
}>;
4-
export declare function readPackageJson(baseDir: string): Promise<any>;
54
export declare function validatePackageJson(pkg: any): void;
65
//# sourceMappingURL=build.d.ts.map

action/config.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export interface BobConfig {
1414
commands?: {
1515
[cmdName: string]: Command;
1616
};
17+
dists?: {
18+
distDir: string;
19+
distPath?: string;
20+
}[];
1721
}
1822
interface UseConfigOptions {
1923
config?: string;

src/commands/build.ts

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ interface BuildOptions {
2020
bin?: Record<string, { input: string; sourcemap?: boolean }>;
2121
}
2222

23-
const distDir = "dist";
23+
const DIST_DIR = "dist";
24+
25+
interface PackageInfo {
26+
packagePath: string;
27+
cwd: string;
28+
pkg: any;
29+
fullName: string;
30+
}
2431

2532
export const buildCommand = createCommand<
2633
{},
@@ -42,31 +49,48 @@ export const buildCommand = createCommand<
4249
});
4350
},
4451
async handler(args) {
52+
config.dists = config.dists || [
53+
{
54+
distDir: DIST_DIR,
55+
distPath: ''
56+
}
57+
];
4558
if (args.single) {
46-
await buildSingle();
59+
await buildSingle({ distDir: DIST_DIR });
4760
return;
4861
}
4962

5063
const limit = pLimit(4);
5164
const packages = await globby("packages/**/package.json", {
5265
cwd: process.cwd(),
5366
absolute: true,
54-
ignore: ["**/node_modules/**", `**/${distDir}/**`],
67+
ignore: ["**/node_modules/**", ...config.dists.map(({ distDir }) => `**/${distDir}/**`)],
5568
});
5669

57-
await Promise.all(
58-
packages.map((packagePath) =>
59-
limit(() => build(packagePath, config, reporter))
60-
)
70+
const packageInfoList: PackageInfo[] = await Promise.all(
71+
packages.map(packagePath => limit(async () => {
72+
const cwd = packagePath.replace("/package.json", "");
73+
const pkg = await fs.readJSON(resolve(cwd, 'package.json'));
74+
const fullName: string = pkg.name;
75+
return { packagePath, cwd, pkg, fullName };
76+
}))
6177
);
78+
79+
for (const { distDir, distPath } of config.dists) {
80+
await Promise.all(
81+
packageInfoList.map(({ packagePath, cwd, pkg, fullName }) =>
82+
limit(() => build({ packagePath, cwd, pkg, fullName, config, reporter, distDir, distPath, packageInfoList }))
83+
)
84+
);
85+
}
6286
},
6387
};
6488
});
6589

66-
async function buildSingle() {
90+
async function buildSingle({ distDir, distPath = '' }: { distDir: string; distPath?: string; }) {
6791
const cwd = process.cwd();
6892
const packagePath = join(process.cwd(), "package.json");
69-
const pkg = await readPackageJson(cwd);
93+
const pkg = await fs.readJSON(packagePath);
7094

7195
validatePackageJson(pkg);
7296

@@ -90,7 +114,7 @@ async function buildSingle() {
90114
}),
91115
typescript(),
92116
generatePackageJson({
93-
baseContents: rewritePackageJson(pkg),
117+
baseContents: rewritePackageJson(pkg, distPath),
94118
additionalDependencies: Object.keys(pkg.dependencies || {}),
95119
}),
96120
],
@@ -138,26 +162,22 @@ async function buildSingle() {
138162
// move README.md and LICENSE
139163
await copyToDist(
140164
cwd,
141-
["README.md", "LICENSE"].concat(buildOptions?.copy || [])
165+
["README.md", "LICENSE"].concat(buildOptions?.copy || []),
166+
DIST_DIR + distPath
142167
);
143168
}
144169

145170
async function build(
146-
packagePath: string,
147-
config: BobConfig,
148-
reporter: Consola
171+
{ packagePath, cwd, pkg, fullName, config, reporter, distDir, distPath = '', packageInfoList }: { packagePath: string; cwd: string; pkg: any; fullName: string; config: BobConfig; reporter: Consola; distDir: string; distPath?: string; packageInfoList: PackageInfo[] },
149172
) {
150173
const scope = config.scope;
151-
const cwd = packagePath.replace("/package.json", "");
152-
const pkg = await readPackageJson(cwd);
153-
const fullName: string = pkg.name;
154174

155175
if ((config.ignore || []).includes(fullName)) {
156176
reporter.warn(`Ignored ${fullName}`);
157177
return;
158178
}
159179

160-
const name = fullName.replace(`${scope}/`, "");
180+
const name = fullName.replace(`${scope}/`, distPath);
161181

162182
validatePackageJson(pkg);
163183

@@ -190,7 +210,7 @@ async function build(
190210
peerDependencies: true,
191211
}),
192212
generatePackageJson({
193-
baseContents: rewritePackageJson(pkg),
213+
baseContents: rewritePackageJson(pkg, distPath),
194214
additionalDependencies: Object.keys(pkg.dependencies || {}),
195215
}),
196216
],
@@ -224,7 +244,7 @@ async function build(
224244
if (pkg.exports) {
225245
generates.push({
226246
...commonOutputOptions,
227-
file: join(distDir, "index.mjs"),
247+
file: join(bobProjectDir, "index.mjs"),
228248
format: "esm" as const,
229249
});
230250
}
@@ -278,37 +298,45 @@ async function build(
278298
banner: `#!/usr/bin/env node`,
279299
preferConst: true,
280300
sourcemap: options.sourcemap,
281-
file: join(bobProjectDir, pkg.bin[alias].replace(`${distDir}/`, "")),
301+
file: join(bobProjectDir, pkg.bin[alias].replace(`${DIST_DIR}/`, "")),
282302
format: "cjs",
283303
});
284304
})
285305
);
286306
}
287307

288308
// remove <project>/dist
289-
await fs.remove(join(cwd, distDir));
309+
await fs.remove(join(cwd, DIST_DIR + distPath));
310+
311+
// fix distPath import in extra dists
312+
function replaceAll(str: string, from: string, to: string) {
313+
return str.split(from).join(to);
314+
}
315+
if (distPath) {
316+
await Promise.all(
317+
generates.map(({ file }) => limit(async () => {
318+
let content = await fs.readFile(file, 'utf8');
319+
for (const { fullName } of packageInfoList) {
320+
content = replaceAll(content, `'${fullName}'`, `'${fullName}${distPath}'`);
321+
}
322+
await fs.writeFile(file, content, { encoding: 'utf8', flag: 'w' });
323+
}))
324+
)
325+
}
326+
290327
// move bob/<project-name> to <project>/dist
291-
await fs.move(bobProjectDir, join(cwd, distDir));
328+
await fs.move(bobProjectDir, join(cwd, DIST_DIR + distPath));
292329
// move README.md and LICENSE
293330
await copyToDist(
294331
cwd,
295-
["README.md", "LICENSE"].concat(pkg.buildOptions?.copy || [])
332+
["README.md", "LICENSE"].concat(pkg.buildOptions?.copy || []),
333+
DIST_DIR + distPath
296334
);
297335

298336
reporter.success(`Built ${pkg.name}`);
299337
}
300338

301-
//
302-
303-
export async function readPackageJson(baseDir: string) {
304-
return JSON.parse(
305-
await fs.readFile(resolve(baseDir, "package.json"), {
306-
encoding: "utf-8",
307-
})
308-
);
309-
}
310-
311-
function rewritePackageJson(pkg: Record<string, any>) {
339+
function rewritePackageJson(pkg: Record<string, any>, distPath: string) {
312340
const newPkg: Record<string, any> = {};
313341
const fields = [
314342
"name",
@@ -332,6 +360,7 @@ function rewritePackageJson(pkg: Record<string, any>) {
332360
}
333361
});
334362

363+
newPkg.name += distPath;
335364
newPkg.main = "index.cjs.js";
336365
newPkg.module = "index.esm.js";
337366
newPkg.typings = "index.d.ts";
@@ -343,7 +372,7 @@ function rewritePackageJson(pkg: Record<string, any>) {
343372
newPkg.bin = {};
344373

345374
for (const alias in pkg.bin) {
346-
newPkg.bin[alias] = pkg.bin[alias].replace(`${distDir}/`, "");
375+
newPkg.bin[alias] = pkg.bin[alias].replace(`${DIST_DIR}/`, "");
347376
}
348377
}
349378

@@ -361,18 +390,18 @@ export function validatePackageJson(pkg: any) {
361390
}
362391
}
363392

364-
expect("main", `${distDir}/index.cjs.js`);
365-
expect("module", `${distDir}/index.esm.js`);
366-
expect("typings", `${distDir}/index.d.ts`);
367-
expect("typescript.definition", `${distDir}/index.d.ts`);
393+
expect("main", `${DIST_DIR}/index.cjs.js`);
394+
expect("module", `${DIST_DIR}/index.esm.js`);
395+
expect("typings", `${DIST_DIR}/index.d.ts`);
396+
expect("typescript.definition", `${DIST_DIR}/index.d.ts`);
368397

369398
if (pkg.exports) {
370399
expect("exports.require", pkg.main);
371-
expect("exports.default", `${distDir}/index.mjs`);
400+
expect("exports.default", `${DIST_DIR}/index.mjs`);
372401
}
373402
}
374403

375-
async function copyToDist(cwd: string, files: string[]) {
404+
async function copyToDist(cwd: string, files: string[], distDir: string) {
376405
const allFiles = await globby(files, { cwd });
377406

378407
return Promise.all(

src/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export interface BobConfig {
1919
commands?: {
2020
[cmdName: string]: Command;
2121
};
22+
dists?: {
23+
distDir: string;
24+
distPath?: string;
25+
}[]
2226
}
2327

2428
interface UseConfigOptions {

0 commit comments

Comments
 (0)