@@ -2,45 +2,65 @@ import esbuild from 'esbuild'
22import fs from 'node:fs/promises'
33import zlib from 'node:zlib'
44
5+ /** @typedef {{ [name: string]: string } } Exports */
6+ /** @typedef {{ extension: string, transform(code: string, exports: Exports): string } } Variant */
7+ /** @type {{ [name: string]: Variant } } */
58const variants = {
69 esm : {
710 extension : 'mjs' ,
811 transform ( code , exports ) {
12+ /** @type {string[] } */
913 const esmExports = [ ]
1014 for ( const name in exports ) esmExports . push ( `${ exports [ name ] } as ${ name } ` )
11- return `${ code } export{${ esmExports . join ( ',' ) } }`
15+ return (
16+ esmExports . length
17+ ? `${ code } export{${ esmExports . join ( ',' ) } }`
18+ : code
19+ )
1220 } ,
1321 } ,
1422 cjs : {
1523 extension : 'cjs' ,
1624 transform ( code , exports ) {
17- const cjsExports = [ '__esModule:!0' ]
25+ /** @type {string[] } */
26+ const cjsExports = [ ]
1827 for ( const name in exports ) cjsExports . push ( `${ name } :${ exports [ name ] } ` )
19- return `${ code } module.exports={${ cjsExports . join ( ',' ) } }`
28+ return (
29+ cjsExports . length
30+ ? 'default' in exports
31+ ? `${ code } module.exports=Object.assign(${ exports . default } ,{${ cjsExports . join ( ',' ) } })`
32+ : `${ code } module.exports={${ cjsExports . join ( ',' ) } }`
33+ : code
34+ )
2035 } ,
2136 } ,
2237}
2338
24- async function buildPackage ( src ) {
25- const packageUrl = src
26- const initPackageUrl = new URL ( ' src/' , packageUrl )
27- const distPackageUrl = new URL ( 'dist/' , packageUrl )
39+ /** @type { (pkgUrl: URL, name: string) => Promise<void> } */
40+ async function buildPackage ( pkgUrl , base ) {
41+ const srcDirUrl = new URL ( ` src/` , pkgUrl )
42+ const outDirUrl = new URL ( ` ${ base } /` , pkgUrl )
2843
29- const packageJsonUrl = new URL ( `package.json` , packageUrl )
30- const packageName = JSON . parse ( await fs . readFile ( packageJsonUrl , 'utf8' ) ) . name
44+ /** @type {{ name: string } } */
45+ const { name } = JSON . parse (
46+ await fs . readFile (
47+ new URL ( 'package.json' , pkgUrl ) ,
48+ 'utf8'
49+ )
50+ )
3151
32- console . log ( packageName )
52+ console . log ( base )
3353 console . log ( )
3454
35- const targetPathname = new URL ( 'index .js' , initPackageUrl ) . pathname
36- const outputPathname = new URL ( 'index .js' , distPackageUrl ) . pathname
55+ const srcPath = new URL ( ` ${ base } .js` , srcDirUrl ) . pathname
56+ const outPath = new URL ( ` ${ base } .js` , outDirUrl ) . pathname
3757
3858 // Build ESM version
3959 const {
4060 outputFiles : [ cmapResult , codeResult ] ,
4161 } = await esbuild . build ( {
42- entryPoints : [ targetPathname ] ,
43- outfile : outputPathname ,
62+ entryPoints : [ srcPath ] ,
63+ outfile : outPath ,
4464 bundle : true ,
4565 format : 'esm' ,
4666 sourcemap : 'external' ,
@@ -52,28 +72,53 @@ async function buildPackage(src) {
5272 const map = cmapResult . text
5373
5474 // ensure empty dist directory
55- await fs . mkdir ( distPackageUrl , { recursive : true } )
75+ await fs . mkdir ( outDirUrl , { recursive : true } )
5676
5777 // write map
58- fs . writeFile ( new URL ( `index .map` , distPackageUrl ) , map )
78+ await fs . writeFile ( new URL ( `${ name } .map` , outDirUrl ) , map )
5979
6080 // prepare variations
81+ /** @type {(code: string, index?: number) => [string, string] } */
6182 const splitByExport = ( code , index = code . indexOf ( 'export' ) ) => [ code . slice ( 0 , index ) , code . slice ( index ) ]
6283 const [ lead , tail ] = splitByExport ( code )
6384
85+ /** @type {{ [name: string]: string } } */
6486 const exports = Array . from ( tail . matchAll ( / ( [ $ \w ] + ) a s ( \w + ) / g) ) . reduce ( ( exports , each ) => Object . assign ( exports , { [ each [ 2 ] ] : each [ 1 ] } ) , Object . create ( null ) )
6587
6688 // write variation builds
6789 for ( const variant in variants ) {
90+ /** @type {Variant } */
6891 const variantInfo = variants [ variant ]
69- const variantPath = new URL ( `dist/index .${ variantInfo . extension } ` , packageUrl ) . pathname
92+ const variantPath = new URL ( `${ base } / ${ name } .${ variantInfo . extension } ` , pkgUrl ) . pathname
7093 const variantCode = variantInfo . transform ( lead , exports )
7194 const variantSize = ( Buffer . byteLength ( variantCode , 'utf8' ) / 1000 ) . toFixed ( )
7295 const variantGzip = Number ( ( zlib . gzipSync ( variantCode , { level : 9 } ) . length / 1000 ) . toFixed ( 2 ) )
7396
7497 console . log ( ' ' , `\x1b[33m${ variantSize } kB\x1b[0m \x1b[2m/\x1b[0m \x1b[33m${ variantGzip } kB\x1b[0m` , `\x1b[2m(${ variant } )\x1b[0m` )
7598
7699 await fs . writeFile ( variantPath , variantCode + `\n//# sourceMappingUrl=index.map` )
100+
101+ const packageJSON = JSON . stringify ( {
102+ private : true ,
103+ type : 'module' ,
104+ main : `${ name } .cjs` ,
105+ module : `${ name } .mjs` ,
106+ jsdelivr : `${ name } .mjs` ,
107+ unpkg : `${ name } .mjs` ,
108+ files : [
109+ `${ name } .cjs` ,
110+ `${ name } .mjs`
111+ ] ,
112+ exports : {
113+ '.' : {
114+ import : `./${ name } .mjs` ,
115+ require : `./${ name } .cjs` ,
116+ default : `./${ name } .mjs`
117+ }
118+ }
119+ } , null , ' ' )
120+
121+ await fs . writeFile ( new URL ( 'package.json' , outDirUrl ) , packageJSON )
77122 }
78123}
79124
@@ -84,9 +129,11 @@ const argvUrl = new URL(process.argv[1], 'file:')
84129
85130if ( metaUrl . href === argvUrl . href ) {
86131 /** Root directory. */
87- const rootUrl = new URL ( '../' , metaUrl )
132+ const pkgUrl = new URL ( '../' , metaUrl )
88133
89134 console . log ( )
135+ await buildPackage ( pkgUrl , 'postcss-8-nesting' )
90136
91- await buildPackage ( rootUrl )
137+ console . log ( )
138+ await buildPackage ( pkgUrl , 'postcss-7-nesting' )
92139}
0 commit comments