@@ -7,8 +7,8 @@ import { performance } from 'node:perf_hooks'
7
7
import { builtinModules , createRequire } from 'node:module'
8
8
import colors from 'picocolors'
9
9
import 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'
12
12
import picomatch from 'picomatch'
13
13
import type { AnymatchFn } from '../types/anymatch'
14
14
import { withTrailingSlash } from '../shared/utils'
@@ -1858,73 +1858,67 @@ async function bundleConfigFile(
1858
1858
const dirnameVarName = '__vite_injected_original_dirname'
1859
1859
const filenameVarName = '__vite_injected_original_filename'
1860
1860
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}`],
1866
1865
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
+ } ,
1872
1869
define : {
1873
1870
__dirname : dirnameVarName ,
1874
1871
__filename : filenameVarName ,
1875
1872
'import.meta.url' : importMetaUrlVarName ,
1876
1873
'import.meta.dirname' : dirnameVarName ,
1877
1874
'import.meta.filename' : filenameVarName ,
1878
1875
} ,
1876
+ // disable treeshake to include files that is not sideeffectful to `moduleIds`
1877
+ treeshake : false ,
1879
1878
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 ) ) {
1920
1914
return
1921
1915
}
1922
1916
1923
1917
// With the `isNodeBuiltin` check above, this check captures if the builtin is a
1924
1918
// non-node built-in, which esbuild doesn't know how to handle. In that case, we
1925
1919
// externalize it so the non-node runtime handles it instead.
1926
1920
if ( isBuiltin ( id ) ) {
1927
- return { external : true }
1921
+ return { id , external : true }
1928
1922
}
1929
1923
1930
1924
const isImport = isESM || kind === 'dynamic-import'
@@ -1951,44 +1945,80 @@ async function bundleConfigFile(
1951
1945
}
1952
1946
throw e
1953
1947
}
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
+
1954
1954
if ( idFsPath && isImport ) {
1955
1955
idFsPath = pathToFileURL ( idFsPath ) . href
1956
1956
}
1957
- return {
1958
- path : idFsPath ,
1959
- external : true ,
1960
- }
1957
+ return { id : idFsPath , external : true }
1961
1958
} ,
1962
- )
1963
- } ,
1964
- } ,
1959
+ } ,
1960
+ }
1961
+ } ) ( ) ,
1965
1962
{
1966
1963
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 ) {
1970
1967
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 ) } ;` +
1975
1970
`const ${ importMetaUrlVarName } = ${ JSON . stringify (
1976
- pathToFileURL ( args . path ) . href ,
1971
+ pathToFileURL ( id ) . href ,
1977
1972
) } ;`
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
+ } ,
1984
1975
} ,
1985
1976
} ,
1986
1977
] ,
1987
1978
} )
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
+
1989
1996
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 )
1992
2022
}
1993
2023
}
1994
2024
0 commit comments