@@ -73,7 +73,7 @@ async function safeCopyFile(
7373}
7474
7575/**
76- * Updates package.json paths by removing the dist/ prefix
76+ * Updates package.json paths by removing the dist/ and src/ prefixes
7777 */
7878function updatePackageJsonPaths (
7979 packageJson : Record < string , any > ,
@@ -84,7 +84,9 @@ function updatePackageJsonPaths(
8484
8585 for ( const field of pathFields ) {
8686 if ( packageJson [ field ] ) {
87- packageJson [ field ] = packageJson [ field ] . replace ( / ^ d i s t \/ / , '' ) ;
87+ packageJson [ field ] = packageJson [ field ]
88+ . replace ( / ^ ( \. \/ ) ? d i s t \/ / , './' )
89+ . replace ( / ^ ( \. \/ ) ? s r c \/ / , './' ) ;
8890 // Only adjust main to .cjs for CJS-only builds
8991 if ( field === 'main' && hasCjs && ! hasEsm ) {
9092 packageJson [ field ] = packageJson [ field ] . replace ( / \. j s $ / , '.cjs' ) ;
@@ -94,7 +96,7 @@ function updatePackageJsonPaths(
9496}
9597
9698/**
97- * Updates bin field with correct extensions
99+ * Updates bin field with correct extensions and paths
98100 */
99101function updateBinField (
100102 packageJson : Record < string , any > ,
@@ -104,14 +106,16 @@ function updateBinField(
104106
105107 if ( typeof packageJson . bin === 'string' ) {
106108 packageJson . bin = packageJson . bin
107- . replace ( / ^ d i s t \/ / , '' )
109+ . replace ( / ^ ( \. \/ ) ? d i s t \/ / , './' )
110+ . replace ( / ^ ( \. \/ ) ? s r c \/ / , './' )
108111 . replace ( / \. j s $ / , hasEsm ? '.js' : '.cjs' ) ;
109112 } else {
110113 packageJson . bin = Object . fromEntries (
111114 Object . entries ( packageJson . bin ) . map ( ( [ name , path ] ) => [
112115 name ,
113116 ( path as string )
114- . replace ( / ^ d i s t \/ / , '' )
117+ . replace ( / ^ ( \. \/ ) ? d i s t \/ / , './' )
118+ . replace ( / ^ ( \. \/ ) ? s r c \/ / , './' )
115119 . replace ( / \. j s $ / , hasEsm ? '.js' : '.cjs' ) ,
116120 ] ) ,
117121 ) ;
@@ -147,10 +151,10 @@ function generateExportsField(
147151 hasCjs : boolean ,
148152) : Record < string , any > {
149153 const exportPatterns = {
150- '.' : './src/ index.js' ,
151- './*' : './src/ */index.js' ,
152- './*/' : './src/ */index.js' ,
153- './*.js' : './src/ *.js' ,
154+ '.' : './index.js' ,
155+ './*' : './*/index.js' ,
156+ './*/' : './*/index.js' ,
157+ './*.js' : './*.js' ,
154158 } ;
155159
156160 return Object . fromEntries (
@@ -175,7 +179,7 @@ export interface BaseConfigOptions {
175179 preserveModulesRoot ?: string ;
176180 /**
177181 * Output directory
178- * @default `${projectRoot}/dist/src `
182+ * @default `${projectRoot}/dist`
179183 */
180184 outDir ?: string ;
181185 /**
@@ -200,7 +204,7 @@ export function baseConfig(options: BaseConfigOptions): RolldownOptions {
200204 projectRoot,
201205 entry = `${ projectRoot } /src/index.ts` ,
202206 preserveModulesRoot = 'src' ,
203- outDir = `${ projectRoot } /dist/src ` ,
207+ outDir = `${ projectRoot } /dist` ,
204208 additionalExternals = [ ] ,
205209 formats = [ 'es' ] ,
206210 sourcemap = true ,
@@ -240,32 +244,48 @@ export function baseConfig(options: BaseConfigOptions): RolldownOptions {
240244 output : outputs . length > 0 ? outputs : undefined ,
241245 external,
242246 plugins : [
247+ // Plugin to transform relative paths to package.json
248+ {
249+ name : 'transform-package-json-paths' ,
250+ transform ( code , id ) {
251+ // Transform relative paths to package.json by removing one ../ level
252+ // This is needed because we build to dist/ instead of dist/src/
253+ if ( code . includes ( 'package.json' ) ) {
254+ // Match any number of ../ and reduce by one level
255+ return code . replace (
256+ / ( [ ' " ` ] ) ( (?: \. \. \/ ) + ) ( p a c k a g e \. j s o n ) \1/ g,
257+ ( match , quote , dots , file ) => {
258+ // Remove one ../ from the path
259+ const newDots = dots . replace ( / \. \. \/ / , '' ) ;
260+ return `${ quote } ${ newDots } ${ file } ${ quote } ` ;
261+ } ,
262+ ) ;
263+ }
264+ return null ;
265+ } ,
266+ } ,
243267 // Custom plugin to copy files and modify package.json after build
244268 {
245269 name : 'copy-files-and-update-package-json' ,
246270 async closeBundle ( ) {
247- const distRoot = join ( projectRoot , 'dist' ) ;
248-
249- // Ensure output directories exist
271+ // Ensure output directory exists
250272 await mkdir ( outDir , { recursive : true } ) ;
251- await mkdir ( distRoot , { recursive : true } ) ;
252273
253- // Copy standard files and additional files
254- // For package.json, copy to the dist root for npm publishing compatibility
274+ // Copy standard files and additional files to dist root
255275 const filesToCopy = [
256- { file : 'package.json' , dest : distRoot } ,
257- { file : 'README.md' , dest : distRoot } ,
258- ...additionalCopyFiles . map ( file => ( { file , dest : distRoot } ) ) ,
276+ 'package.json' ,
277+ 'README.md' ,
278+ ...additionalCopyFiles ,
259279 ] ;
260280
261281 await Promise . all (
262- filesToCopy . map ( ( { file, dest } ) =>
263- safeCopyFile ( join ( projectRoot , file ) , join ( dest , file ) , file ) ,
282+ filesToCopy . map ( file =>
283+ safeCopyFile ( join ( projectRoot , file ) , join ( outDir , file ) , file ) ,
264284 ) ,
265285 ) ;
266286
267- // Update package.json in dist root
268- const distPackageJsonPath = join ( distRoot , 'package.json' ) ;
287+ // Update package.json in dist
288+ const distPackageJsonPath = join ( outDir , 'package.json' ) ;
269289 try {
270290 const packageJson = JSON . parse (
271291 await readFile ( distPackageJsonPath , 'utf8' ) ,
@@ -279,12 +299,9 @@ export function baseConfig(options: BaseConfigOptions): RolldownOptions {
279299 ] as const ;
280300 fieldsToRemove . forEach ( field => delete packageJson [ field ] ) ;
281301
282- // Update files field to include built output
283- if ( packageJson . files ) {
284- packageJson . files = packageJson . files . map ( ( file : string ) =>
285- file === 'src' ? 'src' : file ,
286- ) ;
287- }
302+ // Remove files field to include all built output
303+ // (npm will include everything in dist except what's in .npmignore)
304+ delete packageJson . files ;
288305
289306 // Detect which formats were built
290307 const hasEsm = formats . includes ( 'es' ) ;
0 commit comments