Skip to content

Commit

Permalink
fix: use the same primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jul 11, 2023
1 parent f70a95a commit 2153be7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
7 changes: 6 additions & 1 deletion packages/vite-node/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ export class ViteNodeRunner {
const requestStubs = this.options.requestStubs || DEFAULT_REQUEST_STUBS
if (id in requestStubs)
return requestStubs[id]

let { code: transformed, externalize } = await this.options.fetchModule(id)

if (externalize) {
Expand All @@ -294,6 +293,8 @@ export class ViteNodeRunner {
if (transformed == null)
throw new Error(`[vite-node] Failed to load "${id}" imported from ${callstack[callstack.length - 2]}`)

const { Object, Reflect, Symbol } = this.getContextPrimitives()

const modulePath = cleanUrl(moduleId)
// disambiguate the `<UNIT>:/` on windows: see nodejs/node#31710
const href = pathToFileURL(modulePath).href
Expand Down Expand Up @@ -398,6 +399,10 @@ export class ViteNodeRunner {
return exports
}

protected getContextPrimitives() {
return { Object, Reflect, Symbol }
}

protected async runModule(context: Record<string, any>, transformed: string) {
// add 'use strict' since ESM enables it by default
const codeDefinition = `'use strict';async (${Object.keys(context).join(',')})=>{{`
Expand Down
16 changes: 16 additions & 0 deletions packages/vitest/src/runtime/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ export class VitestExecutor extends ViteNodeRunner {
public mocker: VitestMocker
public externalModules?: ExternalModulesExecutor

private primitives: {
Object: typeof Object
Reflect: typeof Reflect
Symbol: typeof Symbol
}

constructor(public options: ExecuteOptions) {
super(options)

Expand All @@ -147,6 +153,11 @@ export class VitestExecutor extends ViteNodeRunner {
'/@vite/client': clientStub,
'@vite/client': clientStub,
}
this.primitives = {
Object,
Reflect,
Symbol,
}
}
else {
this.externalModules = new ExternalModulesExecutor(options.context, options.findNearestPackageData || (() => Promise.resolve({})))
Expand All @@ -155,9 +166,14 @@ export class VitestExecutor extends ViteNodeRunner {
'/@vite/client': clientStub,
'@vite/client': clientStub,
}
this.primitives = vm.runInContext('({ Object, Reflect, Symbol })', options.context)
}
}

protected getContextPrimitives() {
return this.primitives
}

get state() {
return this.options.state
}
Expand Down
15 changes: 9 additions & 6 deletions packages/vitest/src/runtime/external-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ export class ExternalModulesExecutor {
private esmLinkMap = new WeakMap<VMModule, Promise<void>>()

private Module: typeof _Module
private primitives: {
Object: typeof Object
}

constructor(private context: vm.Context, private findNearestPackageData: RuntimeRPC['findNearestPackageData']) {
this.context = context
Expand All @@ -110,7 +113,7 @@ export class ExternalModulesExecutor {
const executor = this

this.Module = class Module {
exports = {}
exports: any
isPreloading = false
require: NodeRequire
id: string
Expand All @@ -119,20 +122,17 @@ export class ExternalModulesExecutor {
parent: null | Module | undefined
children: Module[] = []
path: string
paths: string[]
paths: string[] = []

constructor(id: string, parent?: Module) {
this.exports = {}
this.isPreloading = false
this.exports = executor.primitives.Object.create(Object.prototype)
this.require = Module.createRequire(id)
// in our case the path should always be resolved already
this.path = dirname(id)
this.id = id
this.filename = id
this.loaded = false
this.parent = parent
this.children = []
this.paths = []
}

_compile(code: string, filename: string) {
Expand Down Expand Up @@ -199,6 +199,8 @@ export class ExternalModulesExecutor {

this.extensions['.js'] = this.requireJs
this.extensions['.json'] = this.requireJson

this.primitives = vm.runInContext('({ Object })', context)
}

private requireJs = (m: NodeModule, filename: string) => {
Expand Down Expand Up @@ -226,6 +228,7 @@ export class ExternalModulesExecutor {
}

private async wrapSynteticModule(identifier: string, format: 'esm' | 'builtin' | 'cjs', exports: Record<string, unknown>) {
// TODO: technically module should be parsed to find static exports, implement for #2854
const moduleKeys = Object.keys(exports)
if (format !== 'esm' && !moduleKeys.includes('default'))
moduleKeys.push('default')
Expand Down

0 comments on commit 2153be7

Please sign in to comment.