Skip to content

Commit 227a048

Browse files
committed
Support multiple dist configurations
1 parent 4e66477 commit 227a048

File tree

4 files changed

+80
-44
lines changed

4 files changed

+80
-44
lines changed

action/commands/build.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ export declare const distDir = "dist";
22
export declare const buildCommand: import("../command").CommandFactory<{}, {
33
single?: boolean | undefined;
44
}>;
5-
export declare function readPackageJson(baseDir: string): Promise<any>;
65
export declare function validatePackageJson(pkg: any): void;
76
//# 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: 72 additions & 43 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-
export 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

@@ -87,7 +111,7 @@ async function buildSingle() {
87111
}),
88112
typescript(),
89113
generatePackageJson({
90-
baseContents: rewritePackageJson(pkg),
114+
baseContents: rewritePackageJson(pkg, distPath),
91115
additionalDependencies: Object.keys(pkg.dependencies || {}),
92116
}),
93117
],
@@ -135,26 +159,22 @@ async function buildSingle() {
135159
// move README.md and LICENSE
136160
await copyToDist(
137161
cwd,
138-
["README.md", "LICENSE"].concat(buildOptions?.copy || [])
162+
["README.md", "LICENSE"].concat(buildOptions?.copy || []),
163+
DIST_DIR + distPath
139164
);
140165
}
141166

142167
async function build(
143-
packagePath: string,
144-
config: BobConfig,
145-
reporter: Consola
168+
{ 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[] },
146169
) {
147170
const scope = config.scope;
148-
const cwd = packagePath.replace("/package.json", "");
149-
const pkg = await readPackageJson(cwd);
150-
const fullName: string = pkg.name;
151171

152172
if ((config.ignore || []).includes(fullName)) {
153173
reporter.warn(`Ignored ${fullName}`);
154174
return;
155175
}
156176

157-
const name = fullName.replace(`${scope}/`, "");
177+
const name = fullName.replace(`${scope}/`, distPath);
158178

159179
validatePackageJson(pkg);
160180

@@ -184,7 +204,7 @@ async function build(
184204
packageJSONPath: packagePath,
185205
}),
186206
generatePackageJson({
187-
baseContents: rewritePackageJson(pkg),
207+
baseContents: rewritePackageJson(pkg, distPath),
188208
additionalDependencies: Object.keys(pkg.dependencies || {}),
189209
}),
190210
],
@@ -218,7 +238,7 @@ async function build(
218238
if (pkg.exports) {
219239
generates.push({
220240
...commonOutputOptions,
221-
file: join(distDir, "index.mjs"),
241+
file: join(bobProjectDir, "index.mjs"),
222242
format: "esm" as const,
223243
});
224244
}
@@ -269,37 +289,45 @@ async function build(
269289
banner: `#!/usr/bin/env node`,
270290
preferConst: true,
271291
sourcemap: options.sourcemap,
272-
file: join(bobProjectDir, pkg.bin[alias].replace(`${distDir}/`, "")),
292+
file: join(bobProjectDir, pkg.bin[alias].replace(`${DIST_DIR}/`, "")),
273293
format: "cjs",
274294
});
275295
})
276296
);
277297
}
278298

279299
// remove <project>/dist
280-
await fs.remove(join(cwd, distDir));
300+
await fs.remove(join(cwd, DIST_DIR + distPath));
301+
302+
// fix distPath import in extra dists
303+
function replaceAll(str: string, from: string, to: string) {
304+
return str.split(from).join(to);
305+
}
306+
if (distPath) {
307+
await Promise.all(
308+
generates.map(({ file }) => limit(async () => {
309+
let content = await fs.readFile(file, 'utf8');
310+
for (const { fullName } of packageInfoList) {
311+
content = replaceAll(content, `'${fullName}'`, `'${fullName}${distPath}'`);
312+
}
313+
await fs.writeFile(file, content, { encoding: 'utf8', flag: 'w' });
314+
}))
315+
)
316+
}
317+
281318
// move bob/<project-name> to <project>/dist
282-
await fs.move(bobProjectDir, join(cwd, distDir));
319+
await fs.move(bobProjectDir, join(cwd, DIST_DIR + distPath));
283320
// move README.md and LICENSE
284321
await copyToDist(
285322
cwd,
286-
["README.md", "LICENSE"].concat(pkg.buildOptions?.copy || [])
323+
["README.md", "LICENSE"].concat(pkg.buildOptions?.copy || []),
324+
DIST_DIR + distPath
287325
);
288326

289327
reporter.success(`Built ${pkg.name}`);
290328
}
291329

292-
//
293-
294-
export async function readPackageJson(baseDir: string) {
295-
return JSON.parse(
296-
await fs.readFile(resolve(baseDir, "package.json"), {
297-
encoding: "utf-8",
298-
})
299-
);
300-
}
301-
302-
function rewritePackageJson(pkg: Record<string, any>) {
330+
function rewritePackageJson(pkg: Record<string, any>, distPath: string) {
303331
const newPkg: Record<string, any> = {};
304332
const fields = [
305333
"name",
@@ -323,6 +351,7 @@ function rewritePackageJson(pkg: Record<string, any>) {
323351
}
324352
});
325353

354+
newPkg.name += distPath;
326355
newPkg.main = "index.cjs.js";
327356
newPkg.module = "index.esm.js";
328357
newPkg.typings = "index.d.ts";
@@ -334,7 +363,7 @@ function rewritePackageJson(pkg: Record<string, any>) {
334363
newPkg.bin = {};
335364

336365
for (const alias in pkg.bin) {
337-
newPkg.bin[alias] = pkg.bin[alias].replace(`${distDir}/`, "");
366+
newPkg.bin[alias] = pkg.bin[alias].replace(`${DIST_DIR}/`, "");
338367
}
339368
}
340369

@@ -352,18 +381,18 @@ export function validatePackageJson(pkg: any) {
352381
}
353382
}
354383

355-
expect("main", `${distDir}/index.cjs.js`);
356-
expect("module", `${distDir}/index.esm.js`);
357-
expect("typings", `${distDir}/index.d.ts`);
358-
expect("typescript.definition", `${distDir}/index.d.ts`);
384+
expect("main", `${DIST_DIR}/index.cjs.js`);
385+
expect("module", `${DIST_DIR}/index.esm.js`);
386+
expect("typings", `${DIST_DIR}/index.d.ts`);
387+
expect("typescript.definition", `${DIST_DIR}/index.d.ts`);
359388

360389
if (pkg.exports) {
361-
expect("exports.require", `./${pkg.main}`);
362-
expect("exports.default", `./${distDir}/index.mjs`);
390+
expect("exports.require", pkg.main);
391+
expect("exports.default", `${DIST_DIR}/index.mjs`);
363392
}
364393
}
365394

366-
async function copyToDist(cwd: string, files: string[]) {
395+
async function copyToDist(cwd: string, files: string[], distDir: string) {
367396
const allFiles = await globby(files, { cwd });
368397

369398
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)