@@ -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
2532export 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
145170async 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 (
0 commit comments