Skip to content

Commit e546e04

Browse files
committed
fix: support cjs globals in default modules evaluator
1 parent fa8f085 commit e546e04

File tree

3 files changed

+92
-60
lines changed

3 files changed

+92
-60
lines changed

packages/vite/src/module-runner/esmEvaluator.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ import {
1111
} from './constants'
1212
import type { ModuleEvaluator, ModuleRunnerContext } from './types'
1313

14+
export interface ESModulesEvaluatorOptions {
15+
cjsGlobals?: boolean
16+
startOffset?: number
17+
}
18+
1419
export class ESModulesEvaluator implements ModuleEvaluator {
15-
startOffset = getAsyncFunctionDeclarationPaddingLineCount()
20+
public readonly startOffset: number
21+
22+
constructor(private options: ESModulesEvaluatorOptions = {}) {
23+
this.startOffset =
24+
options.startOffset ?? getAsyncFunctionDeclarationPaddingLineCount()
25+
}
1626

1727
async runInlinedModule(
1828
context: ModuleRunnerContext,
@@ -25,16 +35,22 @@ export class ESModulesEvaluator implements ModuleEvaluator {
2535
ssrImportKey,
2636
ssrDynamicImportKey,
2737
ssrExportAllKey,
38+
'__filename',
39+
'__dirname',
2840
// source map should already be inlined by Vite
2941
'"use strict";' + code,
3042
)
3143

44+
const meta = context[ssrImportMetaKey]
45+
3246
await initModule(
3347
context[ssrModuleExportsKey],
3448
context[ssrImportMetaKey],
3549
context[ssrImportKey],
3650
context[ssrDynamicImportKey],
3751
context[ssrExportAllKey],
52+
this.options.cjsGlobals ? meta.filename : undefined,
53+
this.options.cjsGlobals ? meta.dirname : undefined,
3854
)
3955

4056
Object.seal(context[ssrModuleExportsKey])

packages/vite/src/module-runner/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
export { EvaluatedModules, type EvaluatedModuleNode } from './evaluatedModules'
44
export { ModuleRunner } from './runner'
5-
export { ESModulesEvaluator } from './esmEvaluator'
5+
export {
6+
ESModulesEvaluator,
7+
type ESModulesEvaluatorOptions,
8+
} from './esmEvaluator'
69

710
export { createWebSocketModuleRunnerTransport } from '../shared/moduleRunnerTransport'
811

packages/vite/src/node/config.ts

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import colors from 'picocolors'
66
import type { Alias, AliasOptions } from 'dep-types/alias'
77
import type { RollupOptions } from 'rollup'
88
import picomatch from 'picomatch'
9+
import { ESModulesEvaluator } from 'vite/module-runner'
910
import type { AnymatchFn } from '../types/anymatch'
1011
import { withTrailingSlash } from '../shared/utils'
1112
import {
@@ -37,7 +38,6 @@ import { resolveBuildEnvironmentOptions, resolveBuilderOptions } from './build'
3738
import type { ResolvedServerOptions, ServerOptions } from './server'
3839
import { resolveServerOptions } from './server'
3940
import { DevEnvironment } from './server/environment'
40-
import type { RunnableDevEnvironment } from './server/environments/runnableEnvironment'
4141
import { createRunnableDevEnvironment } from './server/environments/runnableEnvironment'
4242
import type { WebSocketServer } from './server/ws'
4343
import type { PreviewOptions, ResolvedPreviewOptions } from './preview'
@@ -1529,87 +1529,100 @@ export async function loadConfigFromFile(
15291529
return null
15301530
}
15311531

1532-
let environment: RunnableDevEnvironment | undefined
1533-
15341532
try {
1535-
environment = createRunnableDevEnvironment(
1536-
'config',
1537-
await resolveConfig(
1538-
{
1539-
configFile: false,
1540-
environments: {
1541-
config: {
1542-
consumer: 'server',
1543-
dev: {
1544-
moduleRunnerTransform: true,
1545-
},
1546-
resolve: {
1547-
external: true,
1548-
},
1533+
const { userConfig, dependencies } = await importConfig(resolvedPath)
1534+
debug?.(`config file loaded in ${getTime()}`)
1535+
1536+
const config = await (typeof userConfig === 'function'
1537+
? userConfig(configEnv)
1538+
: userConfig)
1539+
if (!isObject(config)) {
1540+
throw new Error(`config must export or return an object.`)
1541+
}
1542+
return {
1543+
path: normalizePath(resolvedPath),
1544+
config,
1545+
dependencies,
1546+
}
1547+
} catch (e) {
1548+
createLogger(logLevel, { customLogger }).error(
1549+
colors.red(`failed to load config from ${resolvedPath}`),
1550+
{
1551+
error: e,
1552+
},
1553+
)
1554+
throw e
1555+
}
1556+
}
1557+
1558+
async function importConfig(resolvedPath: string) {
1559+
const environment = createRunnableDevEnvironment(
1560+
'config',
1561+
// TODO: provide a dummy config?
1562+
await resolveConfig(
1563+
{
1564+
configFile: false,
1565+
environments: {
1566+
config: {
1567+
consumer: 'server',
1568+
dev: {
1569+
moduleRunnerTransform: true,
1570+
},
1571+
resolve: {
1572+
external: true,
15491573
},
15501574
},
15511575
},
1552-
'serve',
1553-
),
1554-
{
1555-
// options: {
1556-
// consumer: 'server',
1557-
// dev: {
1558-
// moduleRunnerTransform: true,
1559-
// },
1560-
// TODO for some reason this doesn't work, only setting it the config works
1561-
// resolve: {
1562-
// external: true,
1563-
// },
1564-
// },
1565-
runnerOptions: {
1566-
hmr: {
1567-
logger: false,
1568-
},
1576+
},
1577+
'serve',
1578+
),
1579+
{
1580+
// options: {
1581+
// consumer: 'server',
1582+
// dev: {
1583+
// moduleRunnerTransform: true,
1584+
// },
1585+
// TODO for some reason this doesn't work, only setting it the config works
1586+
// resolve: {
1587+
// external: true,
1588+
// },
1589+
// },
1590+
runnerOptions: {
1591+
hmr: {
1592+
logger: false,
15691593
},
1570-
hot: false,
1594+
evaluator: new ESModulesEvaluator({
1595+
cjsGlobals: true,
1596+
}),
15711597
},
1572-
)
1573-
await environment.init()
1598+
hot: false,
1599+
},
1600+
)
1601+
await environment.init()
1602+
try {
15741603
const { default: userConfig } = (await environment.runner.import(
15751604
resolvedPath,
15761605
)) as {
15771606
default: UserConfigExport
15781607
}
1579-
debug?.(`config file loaded in ${getTime()}`)
1580-
1581-
const config = await (typeof userConfig === 'function'
1582-
? userConfig(configEnv)
1583-
: userConfig)
1584-
if (!isObject(config)) {
1585-
throw new Error(`config must export or return an object.`)
1586-
}
15871608
const modules = [
15881609
...environment.runner.evaluatedModules.fileToModulesMap.entries(),
15891610
]
1590-
await environment.runner.close()
15911611
const dependencies = modules
15921612
.filter(([file, modules]) => {
1593-
const isExternal = [...modules].some(
1613+
const isExternal = [...modules].every(
15941614
(m) => !m.meta || 'externalize' in m.meta,
15951615
)
15961616
return !isExternal && file !== resolvedPath
15971617
})
15981618
.map(([file]) => file)
15991619
return {
1600-
path: normalizePath(resolvedPath),
1601-
config,
1620+
userConfig,
16021621
dependencies,
16031622
}
1604-
} catch (e) {
1605-
await environment?.runner.close()
1606-
createLogger(logLevel, { customLogger }).error(
1607-
colors.red(`failed to load config from ${resolvedPath}`),
1608-
{
1609-
error: e,
1610-
},
1611-
)
1612-
throw e
1623+
} catch (err) {
1624+
await environment.close()
1625+
throw err
16131626
}
16141627
}
16151628

0 commit comments

Comments
 (0)