11import fs from 'node:fs/promises'
22import { defineBuildConfig } from 'unbuild'
3+ import colors from 'picocolors'
34
45export default defineBuildConfig ( {
56 entries : [ 'src/index' ] ,
@@ -20,21 +21,81 @@ export default defineBuildConfig({
2021 } ,
2122 hooks : {
2223 async 'build:done' ( ctx ) {
23- // Remove duplicated `dist/chunks/certificate.{cjs,mjs}` chunks
24- // as both are only dynamically imported by the entrypoints. The
25- // dynamic import can use the `.mjs` chunk only instead.
26- await fs . rm ( 'dist/chunks/certificate.cjs' )
27- const indexCjs = await fs . readFile ( 'dist/index.cjs' , 'utf8' )
28- const editedIndexCjs = indexCjs . replace (
29- 'chunks/certificate.cjs' ,
30- 'chunks/certificate.mjs' ,
31- )
32- if ( indexCjs === editedIndexCjs ) {
33- throw new Error (
34- 'Failed to find `dist/chunks/certificate.cjs` in `dist/index.cjs`' ,
35- )
24+ const isBuild = ctx . options . stub === false
25+ if ( isBuild ) {
26+ await dedupeCertificateChunk ( )
27+ await patchCJS ( )
3628 }
37- await fs . writeFile ( 'dist/index.cjs' , editedIndexCjs )
3829 } ,
3930 } ,
4031} )
32+
33+ // Remove duplicated `dist/chunks/certificate.{cjs,mjs}` chunks
34+ // as both are only dynamically imported by the entrypoints. The
35+ // dynamic import can use the `.mjs` chunk only instead.
36+ async function dedupeCertificateChunk ( ) {
37+ await fs . rm ( 'dist/chunks/certificate.cjs' )
38+ const indexCjs = await fs . readFile ( 'dist/index.cjs' , 'utf8' )
39+ const editedIndexCjs = indexCjs . replace (
40+ 'chunks/certificate.cjs' ,
41+ 'chunks/certificate.mjs' ,
42+ )
43+ if ( indexCjs === editedIndexCjs ) {
44+ throw new Error (
45+ 'Failed to find `dist/chunks/certificate.cjs` in `dist/index.cjs`' ,
46+ )
47+ }
48+ await fs . writeFile ( 'dist/index.cjs' , editedIndexCjs )
49+ }
50+
51+ /**
52+
53+ It converts
54+
55+ ```ts
56+ exports["default"] = viteBasicSslPlugin;
57+ ```
58+
59+ to
60+
61+ ```ts
62+ module.exports = viteBasicSslPlugin;
63+ module.exports["default"] = viteBasicSslPlugin;
64+ ```
65+ */
66+ async function patchCJS ( ) {
67+ const indexPath = 'dist/index.cjs'
68+ let code = await fs . readFile ( indexPath , 'utf-8' )
69+
70+ const matchMixed = code . match ( / \n e x p o r t s \[ " d e f a u l t " \] = ( \w + ) ; / )
71+ if ( matchMixed ) {
72+ const name = matchMixed [ 1 ]
73+
74+ const lines = code . trimEnd ( ) . split ( '\n' )
75+
76+ // search from the end to prepend `modules.` to `export[xxx]`
77+ for ( let i = lines . length - 1 ; i > 0 ; i -- ) {
78+ if ( lines [ i ] . startsWith ( 'exports' ) ) lines [ i ] = 'module.' + lines [ i ]
79+ else {
80+ // at the beginning of exports, export the default function
81+ lines [ i ] += `\nmodule.exports = ${ name } ;`
82+ break
83+ }
84+ }
85+
86+ await fs . writeFile ( indexPath , lines . join ( '\n' ) )
87+
88+ console . log ( colors . bold ( `${ indexPath } CJS patched` ) )
89+ } else {
90+ const matchDefault = code . match ( / \n m o d u l e .e x p o r t s = ( \w + ) ; / )
91+
92+ if ( matchDefault ) {
93+ code += `module.exports["default"] = ${ matchDefault [ 1 ] } ;\n`
94+ await fs . writeFile ( indexPath , code )
95+ console . log ( colors . bold ( `${ indexPath } CJS patched` ) )
96+ } else {
97+ console . error ( colors . red ( `${ indexPath } CJS patch failed` ) )
98+ process . exit ( 1 )
99+ }
100+ }
101+ }
0 commit comments