@@ -7,8 +7,8 @@ import { performance } from 'node:perf_hooks'
77import { builtinModules , createRequire } from 'node:module'
88import colors from 'picocolors'
99import type { Alias , AliasOptions } from 'dep-types/alias'
10- import { build } from 'esbuild '
11- import type { RollupOptions } from 'rolldown'
10+ import { rolldown } from 'rolldown '
11+ import type { OutputChunk , RollupOptions } from 'rolldown'
1212import picomatch from 'picomatch'
1313import type { AnymatchFn } from '../types/anymatch'
1414import { withTrailingSlash } from '../shared/utils'
@@ -1858,73 +1858,67 @@ async function bundleConfigFile(
18581858 const dirnameVarName = '__vite_injected_original_dirname'
18591859 const filenameVarName = '__vite_injected_original_filename'
18601860 const importMetaUrlVarName = '__vite_injected_original_import_meta_url'
1861- const result = await build ( {
1862- absWorkingDir : process . cwd ( ) ,
1863- entryPoints : [ fileName ] ,
1864- write : false ,
1865- target : [ `node${ process . versions . node } ` ] ,
1861+
1862+ const bundle = await rolldown ( {
1863+ input : fileName ,
1864+ // target: [`node${process.versions.node}`],
18661865 platform : 'node' ,
1867- bundle : true ,
1868- format : isESM ? 'esm' : 'cjs' ,
1869- mainFields : [ 'main' ] ,
1870- sourcemap : 'inline' ,
1871- metafile : true ,
1866+ resolve : {
1867+ mainFields : [ 'main' ] ,
1868+ } ,
18721869 define : {
18731870 __dirname : dirnameVarName ,
18741871 __filename : filenameVarName ,
18751872 'import.meta.url' : importMetaUrlVarName ,
18761873 'import.meta.dirname' : dirnameVarName ,
18771874 'import.meta.filename' : filenameVarName ,
18781875 } ,
1876+ // disable treeshake to include files that is not sideeffectful to `moduleIds`
1877+ treeshake : false ,
18791878 plugins : [
1880- {
1881- name : 'externalize-deps' ,
1882- setup ( build ) {
1883- const packageCache = new Map ( )
1884- const resolveByViteResolver = (
1885- id : string ,
1886- importer : string ,
1887- isRequire : boolean ,
1888- ) => {
1889- return tryNodeResolve ( id , importer , {
1890- root : path . dirname ( fileName ) ,
1891- isBuild : true ,
1892- isProduction : true ,
1893- preferRelative : false ,
1894- tryIndex : true ,
1895- mainFields : [ ] ,
1896- conditions : [
1897- 'node' ,
1898- ...( isModuleSyncConditionEnabled ? [ 'module-sync' ] : [ ] ) ,
1899- ] ,
1900- externalConditions : [ ] ,
1901- external : [ ] ,
1902- noExternal : [ ] ,
1903- dedupe : [ ] ,
1904- extensions : configDefaults . resolve . extensions ,
1905- preserveSymlinks : false ,
1906- packageCache,
1907- isRequire,
1908- } ) ?. id
1909- }
1910-
1911- // externalize bare imports
1912- build . onResolve (
1913- { filter : / ^ [ ^ . ] .* / } ,
1914- async ( { path : id , importer, kind } ) => {
1915- if (
1916- kind === 'entry-point' ||
1917- path . isAbsolute ( id ) ||
1918- isNodeBuiltin ( id )
1919- ) {
1879+ ( ( ) => {
1880+ const packageCache = new Map ( )
1881+ const resolveByViteResolver = (
1882+ id : string ,
1883+ importer : string ,
1884+ isRequire : boolean ,
1885+ ) => {
1886+ return tryNodeResolve ( id , importer , {
1887+ root : path . dirname ( fileName ) ,
1888+ isBuild : true ,
1889+ isProduction : true ,
1890+ preferRelative : false ,
1891+ tryIndex : true ,
1892+ mainFields : [ ] ,
1893+ conditions : [
1894+ 'node' ,
1895+ ...( isModuleSyncConditionEnabled ? [ 'module-sync' ] : [ ] ) ,
1896+ ] ,
1897+ externalConditions : [ ] ,
1898+ external : [ ] ,
1899+ noExternal : [ ] ,
1900+ dedupe : [ ] ,
1901+ extensions : configDefaults . resolve . extensions ,
1902+ preserveSymlinks : false ,
1903+ packageCache,
1904+ isRequire,
1905+ } ) ?. id
1906+ }
1907+
1908+ return {
1909+ name : 'externalize-deps' ,
1910+ resolveId : {
1911+ filter : { id : / ^ [ ^ . ] .* / } ,
1912+ async handler ( id , importer , { kind } ) {
1913+ if ( ! importer || path . isAbsolute ( id ) || isNodeBuiltin ( id ) ) {
19201914 return
19211915 }
19221916
19231917 // With the `isNodeBuiltin` check above, this check captures if the builtin is a
19241918 // non-node built-in, which esbuild doesn't know how to handle. In that case, we
19251919 // externalize it so the non-node runtime handles it instead.
19261920 if ( isBuiltin ( id ) ) {
1927- return { external : true }
1921+ return { id , external : true }
19281922 }
19291923
19301924 const isImport = isESM || kind === 'dynamic-import'
@@ -1951,44 +1945,80 @@ async function bundleConfigFile(
19511945 }
19521946 throw e
19531947 }
1948+ if ( ! idFsPath ) return
1949+ // always no-externalize json files as rolldown does not support import attributes
1950+ if ( idFsPath . endsWith ( '.json' ) ) {
1951+ return idFsPath
1952+ }
1953+
19541954 if ( idFsPath && isImport ) {
19551955 idFsPath = pathToFileURL ( idFsPath ) . href
19561956 }
1957- return {
1958- path : idFsPath ,
1959- external : true ,
1960- }
1957+ return { id : idFsPath , external : true }
19611958 } ,
1962- )
1963- } ,
1964- } ,
1959+ } ,
1960+ }
1961+ } ) ( ) ,
19651962 {
19661963 name : 'inject-file-scope-variables' ,
1967- setup ( build ) {
1968- build . onLoad ( { filter : / \. [ c m ] ? [ j t ] s $ / } , async ( args ) => {
1969- const contents = await fsp . readFile ( args . path , 'utf-8' )
1964+ transform : {
1965+ filter : { id : / \. [ c m ] ? [ j t ] s $ / } ,
1966+ async handler ( code , id ) {
19701967 const injectValues =
1971- `const ${ dirnameVarName } = ${ JSON . stringify (
1972- path . dirname ( args . path ) ,
1973- ) } ;` +
1974- `const ${ filenameVarName } = ${ JSON . stringify ( args . path ) } ;` +
1968+ `const ${ dirnameVarName } = ${ JSON . stringify ( path . dirname ( id ) ) } ;` +
1969+ `const ${ filenameVarName } = ${ JSON . stringify ( id ) } ;` +
19751970 `const ${ importMetaUrlVarName } = ${ JSON . stringify (
1976- pathToFileURL ( args . path ) . href ,
1971+ pathToFileURL ( id ) . href ,
19771972 ) } ;`
1978-
1979- return {
1980- loader : args . path . endsWith ( 'ts' ) ? 'ts' : 'js' ,
1981- contents : injectValues + contents ,
1982- }
1983- } )
1973+ return { code : injectValues + code , map : null }
1974+ } ,
19841975 } ,
19851976 } ,
19861977 ] ,
19871978 } )
1988- const { text } = result . outputFiles [ 0 ]
1979+ const result = await bundle . generate ( {
1980+ format : isESM ? 'esm' : 'cjs' ,
1981+ sourcemap : 'inline' ,
1982+ } )
1983+ await bundle . close ( )
1984+
1985+ const entryChunk = result . output . find (
1986+ ( chunk ) : chunk is OutputChunk => chunk . type === 'chunk' && chunk . isEntry ,
1987+ ) !
1988+ const bundleChunks = Object . fromEntries (
1989+ result . output . flatMap ( ( c ) => ( c . type === 'chunk' ? [ [ c . fileName , c ] ] : [ ] ) ) ,
1990+ )
1991+
1992+ const allModules = new Set < string > ( )
1993+ collectAllModules ( bundleChunks , entryChunk . fileName , allModules )
1994+ allModules . delete ( fileName )
1995+
19891996 return {
1990- code : text ,
1991- dependencies : result . metafile ? Object . keys ( result . metafile . inputs ) : [ ] ,
1997+ code : entryChunk . code ,
1998+ dependencies : [ ...allModules ] ,
1999+ }
2000+ }
2001+
2002+ function collectAllModules (
2003+ bundle : Record < string , OutputChunk > ,
2004+ fileName : string ,
2005+ allModules : Set < string > ,
2006+ analyzedModules = new Set < string > ( ) ,
2007+ ) {
2008+ if ( analyzedModules . has ( fileName ) ) return
2009+ analyzedModules . add ( fileName )
2010+
2011+ const chunk = bundle [ fileName ] !
2012+ for ( const mod of chunk . moduleIds ) {
2013+ allModules . add ( mod )
2014+ }
2015+ for ( const i of chunk . imports ) {
2016+ analyzedModules . add ( i )
2017+ collectAllModules ( bundle , i , allModules , analyzedModules )
2018+ }
2019+ for ( const i of chunk . dynamicImports ) {
2020+ analyzedModules . add ( i )
2021+ collectAllModules ( bundle , i , allModules , analyzedModules )
19922022 }
19932023}
19942024
0 commit comments