1
1
import fs from 'node:fs'
2
- import fsp from 'node:fs/promises'
3
2
import path from 'node:path'
4
- import { pathToFileURL } from 'node:url'
5
- import { promisify } from 'node:util'
6
3
import { performance } from 'node:perf_hooks'
7
- import { createRequire } from 'node:module'
8
4
import colors from 'picocolors'
9
5
import type { Alias , AliasOptions } from 'dep-types/alias'
10
- import { build } from 'esbuild'
11
6
import type { RollupOptions } from 'rollup'
12
7
import picomatch from 'picomatch'
13
8
import type { AnymatchFn } from '../types/anymatch'
@@ -52,11 +47,8 @@ import {
52
47
asyncFlatten ,
53
48
createDebugger ,
54
49
createFilter ,
55
- isBuiltin ,
56
50
isExternalUrl ,
57
- isFilePathESM ,
58
51
isInNodeModules ,
59
- isNodeBuiltin ,
60
52
isObject ,
61
53
isParentDirectory ,
62
54
mergeAlias ,
@@ -76,7 +68,6 @@ import type {
76
68
InternalResolveOptions ,
77
69
ResolveOptions ,
78
70
} from './plugins/resolve'
79
- import { tryNodeResolve } from './plugins/resolve'
80
71
import type { LogLevel , Logger } from './logger'
81
72
import { createLogger } from './logger'
82
73
import type { DepOptimizationOptions } from './optimizer'
@@ -88,9 +79,9 @@ import type { ResolvedSSROptions, SSROptions } from './ssr'
88
79
import { resolveSSROptions } from './ssr'
89
80
import { PartialEnvironment } from './baseEnvironment'
90
81
import { createIdResolver } from './idResolver'
82
+ import { createServerModuleRunner } from './ssr/runtime/serverModuleRunner'
91
83
92
84
const debug = createDebugger ( 'vite:config' , { depth : 10 } )
93
- const promisifiedRealpath = promisify ( fs . realpath )
94
85
95
86
export interface ConfigEnv {
96
87
/**
@@ -1502,17 +1493,27 @@ export async function loadConfigFromFile(
1502
1493
return null
1503
1494
}
1504
1495
1505
- const isESM =
1506
- typeof process . versions . deno === 'string' || isFilePathESM ( resolvedPath )
1507
-
1508
1496
try {
1509
- const bundled = await bundleConfigFile ( resolvedPath , isESM )
1510
- const userConfig = await loadConfigFromBundledFile (
1511
- resolvedPath ,
1512
- bundled . code ,
1513
- isESM ,
1497
+ // console.time('config')
1498
+ const environment = new DevEnvironment (
1499
+ 'config' ,
1500
+ await resolveConfig ( { configFile : false } , 'serve' ) ,
1501
+ {
1502
+ options : {
1503
+ consumer : 'server' ,
1504
+ dev : {
1505
+ moduleRunnerTransform : true ,
1506
+ } ,
1507
+ } ,
1508
+ hot : false ,
1509
+ } ,
1514
1510
)
1515
- debug ?.( `bundled config file loaded in ${ getTime ( ) } ` )
1511
+ await environment . init ( )
1512
+ const runner = createServerModuleRunner ( environment )
1513
+ const { default : userConfig } = ( await runner . import ( resolvedPath ) ) as {
1514
+ default : UserConfigExport
1515
+ }
1516
+ debug ?.( `config file loaded in ${ getTime ( ) } ` )
1516
1517
1517
1518
const config = await ( typeof userConfig === 'function'
1518
1519
? userConfig ( configEnv )
@@ -1523,7 +1524,7 @@ export async function loadConfigFromFile(
1523
1524
return {
1524
1525
path : normalizePath ( resolvedPath ) ,
1525
1526
config,
1526
- dependencies : bundled . dependencies ,
1527
+ dependencies : [ ] ,
1527
1528
}
1528
1529
} catch ( e ) {
1529
1530
createLogger ( logLevel , { customLogger } ) . error (
@@ -1533,197 +1534,8 @@ export async function loadConfigFromFile(
1533
1534
} ,
1534
1535
)
1535
1536
throw e
1536
- }
1537
- }
1538
-
1539
- async function bundleConfigFile (
1540
- fileName : string ,
1541
- isESM : boolean ,
1542
- ) : Promise < { code : string ; dependencies : string [ ] } > {
1543
- const dirnameVarName = '__vite_injected_original_dirname'
1544
- const filenameVarName = '__vite_injected_original_filename'
1545
- const importMetaUrlVarName = '__vite_injected_original_import_meta_url'
1546
- const result = await build ( {
1547
- absWorkingDir : process . cwd ( ) ,
1548
- entryPoints : [ fileName ] ,
1549
- write : false ,
1550
- target : [ `node${ process . versions . node } ` ] ,
1551
- platform : 'node' ,
1552
- bundle : true ,
1553
- format : isESM ? 'esm' : 'cjs' ,
1554
- mainFields : [ 'main' ] ,
1555
- sourcemap : 'inline' ,
1556
- metafile : true ,
1557
- define : {
1558
- __dirname : dirnameVarName ,
1559
- __filename : filenameVarName ,
1560
- 'import.meta.url' : importMetaUrlVarName ,
1561
- 'import.meta.dirname' : dirnameVarName ,
1562
- 'import.meta.filename' : filenameVarName ,
1563
- } ,
1564
- plugins : [
1565
- {
1566
- name : 'externalize-deps' ,
1567
- setup ( build ) {
1568
- const packageCache = new Map ( )
1569
- const resolveByViteResolver = (
1570
- id : string ,
1571
- importer : string ,
1572
- isRequire : boolean ,
1573
- ) => {
1574
- return tryNodeResolve ( id , importer , {
1575
- root : path . dirname ( fileName ) ,
1576
- isBuild : true ,
1577
- isProduction : true ,
1578
- preferRelative : false ,
1579
- tryIndex : true ,
1580
- mainFields : [ ] ,
1581
- conditions : [ ] ,
1582
- externalConditions : [ ] ,
1583
- external : [ ] ,
1584
- noExternal : [ ] ,
1585
- overrideConditions : [ 'node' ] ,
1586
- dedupe : [ ] ,
1587
- extensions : DEFAULT_EXTENSIONS ,
1588
- preserveSymlinks : false ,
1589
- packageCache,
1590
- isRequire,
1591
- webCompatible : false ,
1592
- } ) ?. id
1593
- }
1594
-
1595
- // externalize bare imports
1596
- build . onResolve (
1597
- { filter : / ^ [ ^ . ] .* / } ,
1598
- async ( { path : id , importer, kind } ) => {
1599
- if (
1600
- kind === 'entry-point' ||
1601
- path . isAbsolute ( id ) ||
1602
- isNodeBuiltin ( id )
1603
- ) {
1604
- return
1605
- }
1606
-
1607
- // With the `isNodeBuiltin` check above, this check captures if the builtin is a
1608
- // non-node built-in, which esbuild doesn't know how to handle. In that case, we
1609
- // externalize it so the non-node runtime handles it instead.
1610
- if ( isBuiltin ( id ) ) {
1611
- return { external : true }
1612
- }
1613
-
1614
- const isImport = isESM || kind === 'dynamic-import'
1615
- let idFsPath : string | undefined
1616
- try {
1617
- idFsPath = resolveByViteResolver ( id , importer , ! isImport )
1618
- } catch ( e ) {
1619
- if ( ! isImport ) {
1620
- let canResolveWithImport = false
1621
- try {
1622
- canResolveWithImport = ! ! resolveByViteResolver (
1623
- id ,
1624
- importer ,
1625
- false ,
1626
- )
1627
- } catch { }
1628
- if ( canResolveWithImport ) {
1629
- throw new Error (
1630
- `Failed to resolve ${ JSON . stringify (
1631
- id ,
1632
- ) } . This package is ESM only but it was tried to load by \`require\`. See https://vite.dev/guide/troubleshooting.html#this-package-is-esm-only for more details.`,
1633
- )
1634
- }
1635
- }
1636
- throw e
1637
- }
1638
- if ( idFsPath && isImport ) {
1639
- idFsPath = pathToFileURL ( idFsPath ) . href
1640
- }
1641
- return {
1642
- path : idFsPath ,
1643
- external : true ,
1644
- }
1645
- } ,
1646
- )
1647
- } ,
1648
- } ,
1649
- {
1650
- name : 'inject-file-scope-variables' ,
1651
- setup ( build ) {
1652
- build . onLoad ( { filter : / \. [ c m ] ? [ j t ] s $ / } , async ( args ) => {
1653
- const contents = await fsp . readFile ( args . path , 'utf-8' )
1654
- const injectValues =
1655
- `const ${ dirnameVarName } = ${ JSON . stringify (
1656
- path . dirname ( args . path ) ,
1657
- ) } ;` +
1658
- `const ${ filenameVarName } = ${ JSON . stringify ( args . path ) } ;` +
1659
- `const ${ importMetaUrlVarName } = ${ JSON . stringify (
1660
- pathToFileURL ( args . path ) . href ,
1661
- ) } ;`
1662
-
1663
- return {
1664
- loader : args . path . endsWith ( 'ts' ) ? 'ts' : 'js' ,
1665
- contents : injectValues + contents ,
1666
- }
1667
- } )
1668
- } ,
1669
- } ,
1670
- ] ,
1671
- } )
1672
- const { text } = result . outputFiles [ 0 ]
1673
- return {
1674
- code : text ,
1675
- dependencies : result . metafile ? Object . keys ( result . metafile . inputs ) : [ ] ,
1676
- }
1677
- }
1678
-
1679
- interface NodeModuleWithCompile extends NodeModule {
1680
- _compile ( code : string , filename : string ) : any
1681
- }
1682
-
1683
- const _require = createRequire ( import . meta. url )
1684
- async function loadConfigFromBundledFile (
1685
- fileName : string ,
1686
- bundledCode : string ,
1687
- isESM : boolean ,
1688
- ) : Promise < UserConfigExport > {
1689
- // for esm, before we can register loaders without requiring users to run node
1690
- // with --experimental-loader themselves, we have to do a hack here:
1691
- // write it to disk, load it with native Node ESM, then delete the file.
1692
- if ( isESM ) {
1693
- const fileBase = `${ fileName } .timestamp-${ Date . now ( ) } -${ Math . random ( )
1694
- . toString ( 16 )
1695
- . slice ( 2 ) } `
1696
- const fileNameTmp = `${ fileBase } .mjs`
1697
- const fileUrl = `${ pathToFileURL ( fileBase ) } .mjs`
1698
- await fsp . writeFile ( fileNameTmp , bundledCode )
1699
- try {
1700
- return ( await import ( fileUrl ) ) . default
1701
- } finally {
1702
- fs . unlink ( fileNameTmp , ( ) => { } ) // Ignore errors
1703
- }
1704
- }
1705
- // for cjs, we can register a custom loader via `_require.extensions`
1706
- else {
1707
- const extension = path . extname ( fileName )
1708
- // We don't use fsp.realpath() here because it has the same behaviour as
1709
- // fs.realpath.native. On some Windows systems, it returns uppercase volume
1710
- // letters (e.g. "C:\") while the Node.js loader uses lowercase volume letters.
1711
- // See https://github.com/vitejs/vite/issues/12923
1712
- const realFileName = await promisifiedRealpath ( fileName )
1713
- const loaderExt = extension in _require . extensions ? extension : '.js'
1714
- const defaultLoader = _require . extensions [ loaderExt ] !
1715
- _require . extensions [ loaderExt ] = ( module : NodeModule , filename : string ) => {
1716
- if ( filename === realFileName ) {
1717
- ; ( module as NodeModuleWithCompile ) . _compile ( bundledCode , filename )
1718
- } else {
1719
- defaultLoader ( module , filename )
1720
- }
1721
- }
1722
- // clear cache in case of server restart
1723
- delete _require . cache [ _require . resolve ( fileName ) ]
1724
- const raw = _require ( fileName )
1725
- _require . extensions [ loaderExt ] = defaultLoader
1726
- return raw . __esModule ? raw . default : raw
1537
+ } finally {
1538
+ // console.timeEnd('config')
1727
1539
}
1728
1540
}
1729
1541
0 commit comments