11import path from 'node:path'
22import fs from 'node:fs/promises'
3+ import cp from 'node:child_process'
34import { createRequire , isBuiltin } from 'node:module'
45import type { Plugin } from 'rollup'
56
@@ -98,7 +99,7 @@ const { name, version } = createRequire(import.meta.url)('#package.json') as Pac
9899// Files that mark the root of a monorepo
99100const workspaceRootFiles = [
100101 'pnpm-workspace.yaml' , // pnpm
101- 'lerna.json' , // Lerna
102+ 'lerna.json' , // Lerna / Lerna Light
102103 // Note: is there any interest in the following?
103104 // 'workspace.jsonc', // Bit
104105 // 'nx.json', // Nx
@@ -126,7 +127,7 @@ const isString = (str: unknown): str is string =>
126127 * A Rollup/Vite plugin that automatically declares NodeJS built-in modules,
127128 * and optionally npm dependencies, as 'external'.
128129 */
129- function nodeExternals ( options : ExternalsOptions = { } ) : Plugin {
130+ async function nodeExternals ( options : ExternalsOptions = { } ) : Promise < Plugin > {
130131
131132 const config : Config = { ...defaults , ...options }
132133
@@ -136,6 +137,13 @@ function nodeExternals(options: ExternalsOptions = {}): Plugin {
136137 const isIncluded = ( id : string ) => include . length > 0 && include . some ( rx => rx . test ( id ) ) ,
137138 isExcluded = ( id : string ) => exclude . length > 0 && exclude . some ( rx => rx . test ( id ) )
138139
140+ // Determine the root of the git repository, if any.
141+ const gitRepository = await new Promise < string | null > ( resolve => {
142+ cp . execFile ( 'git' , [ 'rev-parse' , '--show-toplevel' ] , ( error , stdout ) => {
143+ return resolve ( error ? null : path . normalize ( stdout . trim ( ) ) )
144+ } )
145+ } )
146+
139147 return {
140148 name : name . replace ( / ^ r o l l u p - p l u g i n - / , '' ) ,
141149 version,
@@ -165,29 +173,24 @@ function nodeExternals(options: ExternalsOptions = {}): Plugin {
165173 . concat ( config . packagePath )
166174 . filter ( isString )
167175 . map ( packagePath => path . resolve ( packagePath ) )
176+
168177 if ( packagePaths . length === 0 ) {
169- search: for (
170- let current = process . cwd ( ) , previous : string | undefined = undefined ;
171- previous !== current ;
172- previous = current , current = path . dirname ( current )
173- ) {
178+ search:
179+ for ( let current = process . cwd ( ) , previous : string | undefined = undefined ; previous !== current ; previous = current , current = path . dirname ( current ) ) {
180+
174181 // Gather package.json files.
175182 let name = path . join ( current , 'package.json' )
176183 let stat = await fs . stat ( name ) . catch ( ( ) => null )
177184 if ( stat ?. isFile ( ) )
178185 packagePaths . push ( name )
179186
180187 // Break early if we are at the root of a git repo.
181- name = path . join ( current , '.git' )
182- stat = await fs . stat ( name ) . catch ( ( ) => null )
183- if ( stat ?. isDirectory ( ) )
188+ if ( current === gitRepository )
184189 break
185190
186191 // Break early is there is a known workspace root file.
187192 for ( const file of workspaceRootFiles ) {
188- name = path . join ( current , file )
189- stat = await fs . stat ( name ) . catch ( ( ) => null )
190- if ( stat ?. isFile ( ) )
193+ if ( await fs . stat ( path . join ( current , file ) ) . then ( stat => stat . isFile ( ) ) . catch ( ( ) => false ) )
191194 break search
192195 }
193196 }
0 commit comments