diff --git a/.vscodeignore b/.vscodeignore index c54bc512..ffffc55a 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -21,3 +21,8 @@ vite.config.ts tsconfig.json tsconfig.base.json .github/** +.eslintcache +.vscode-test.mjs +eslint.config.mjs +scripts/** +test-results/** \ No newline at end of file diff --git a/src/api.ts b/src/api.ts index b415c7a1..51de7ea4 100644 --- a/src/api.ts +++ b/src/api.ts @@ -286,7 +286,7 @@ async function createChildVitestProcess(pkg: VitestPackage) { log.error('[API]', errorMsg) throw new Error(errorMsg) } - log.info('[API]', `Running ${formapPkg(pkg)} with Node.js: ${execPath}`) + log.info('[API]', `Running ${formapPkg(pkg)} with Node.js: ${execPath} ${execArgv ? execArgv.join(' ') : ''}`) const logLevel = getConfig(pkg.folder).logLevel const vitest = fork( // to support pnp, we need to spawn `yarn node` instead of `node` @@ -363,10 +363,11 @@ async function createChildVitestProcess(pkg: VitestPackage) { arguments: pkg.arguments, workspaceFile: pkg.workspaceFile, id: pkg.id, + pnpApi: pnp, + pnpLoader: pnpLoader && gte(process.version, '18.19.0') + ? pathToFileURL(pnpLoader).toString() + : undefined, }, - loader: pnpLoader && gte(process.version, '18.19.0') - ? pathToFileURL(pnpLoader).toString() - : undefined, } vitest.send(runnerOptions) diff --git a/src/api/resolve.ts b/src/api/resolve.ts index 6d34b0dd..3fecff3a 100644 --- a/src/api/resolve.ts +++ b/src/api/resolve.ts @@ -3,6 +3,8 @@ import type * as vscode from 'vscode' import { dirname, resolve } from 'pathe' import { getConfig } from '../config' +const _require = require + export interface VitestResolution { vitestPackageJsonPath: string vitestNodePath: string @@ -24,8 +26,13 @@ export function resolveVitestPackage(cwd: string, folder: vscode.WorkspaceFolder const pnp = resolveVitestPnpPackagePath(folder?.uri.fsPath || cwd) if (!pnp) return null + const pnpApi = _require(pnp.pnpPath) + const vitestNodePath = pnpApi.resolveRequest('vitest/node', cwd) + if (!vitestNodePath) { + return null + } return { - vitestNodePath: 'vitest/node', + vitestNodePath, vitestPackageJsonPath: 'vitest/package.json', pnp: { loaderPath: pnp.pnpLoader, diff --git a/src/debug/api.ts b/src/debug/api.ts index 6db2293a..ec6816ff 100644 --- a/src/debug/api.ts +++ b/src/debug/api.ts @@ -1,7 +1,9 @@ import { createServer } from 'node:http' +import { pathToFileURL } from 'node:url' import * as vscode from 'vscode' import WebSocket, { WebSocketServer } from 'ws' import getPort from 'get-port' +import { gte } from 'semver' import type { ResolvedMeta } from '../api' import { VitestFolderAPI } from '../api' import type { VitestPackage } from '../api/pkg' @@ -185,6 +187,9 @@ function startWebsocketServer(wss: WebSocketServer, pkg: VitestPackage) { ws.on('message', onMessage) ws.on('close', onExit) + const pnpLoader = pkg.loader + const pnp = pkg.pnp + const runnerOptions: WorkerRunnerOptions = { type: 'init', meta: { @@ -195,6 +200,10 @@ function startWebsocketServer(wss: WebSocketServer, pkg: VitestPackage) { arguments: pkg.arguments, workspaceFile: pkg.workspaceFile, id: pkg.id, + pnpApi: pnp, + pnpLoader: pnpLoader && gte(process.version, '18.19.0') + ? pathToFileURL(pnpLoader).toString() + : undefined, }, } diff --git a/src/testTree.ts b/src/testTree.ts index 0219337e..cf674bda 100644 --- a/src/testTree.ts +++ b/src/testTree.ts @@ -300,7 +300,7 @@ export class TestTree extends vscode.Disposable { testItem.range = new vscode.Range(position, position) } else { - log.error(`Cannot find location for ${testItem.label}. Using "id" to sort instead.`) + log.error(`Cannot find location for "${testItem.label}". Using "id" to sort instead.`) testItem.sortText = task.id } if (task.type === 'suite') diff --git a/src/worker/debug.ts b/src/worker/debug.ts index 7324bf12..1cd9c6a0 100644 --- a/src/worker/debug.ts +++ b/src/worker/debug.ts @@ -1,4 +1,5 @@ import v8 from 'node:v8' +import { register } from 'node:module' import { WebSocket } from 'ws' import type { WorkerRunnerOptions } from './types' import { initVitest } from './init' @@ -6,6 +7,8 @@ import { Vitest } from './vitest' import { createWorkerRPC } from './rpc' import { WorkerWSEventEmitter } from './emitter' +const _require = require + const ws = new WebSocket(process.env.VITEST_WS_ADDRESS!) const emitter = new WorkerWSEventEmitter(ws) @@ -19,6 +22,14 @@ ws.on('message', async function onMessage(_data) { const data = message as WorkerRunnerOptions try { + if (data.meta.pnpApi) { + _require(data.meta.pnpApi).setup() + } + + if (data.meta.pnpLoader) { + register(data.meta.pnpLoader) + } + const pkg = data.meta const vitest = await initVitest(pkg, { diff --git a/src/worker/init.ts b/src/worker/init.ts index a97f9e67..c822e035 100644 --- a/src/worker/init.ts +++ b/src/worker/init.ts @@ -5,6 +5,14 @@ import type { WorkerMeta } from './types' export async function initVitest(meta: WorkerMeta, options?: UserConfig) { const vitestModule = await import(meta.vitestNodePath) as typeof import('vitest/node') const reporter = new VSCodeReporter() + const pnpExecArgv = meta.pnpApi && meta.pnpLoader + ? [ + '--require', + meta.pnpApi, + '--experimental-loader', + meta.pnpLoader, + ] + : undefined const vitest = await vitestModule.createVitest( 'test', { @@ -19,6 +27,22 @@ export async function initVitest(meta: WorkerMeta, options?: UserConfig) { reporters: [reporter], ui: false, includeTaskLocation: true, + poolOptions: meta.pnpApi && meta.pnpLoader + ? { + threads: { + execArgv: pnpExecArgv, + }, + forks: { + execArgv: pnpExecArgv, + }, + vmForks: { + execArgv: pnpExecArgv, + }, + vmThreads: { + execArgv: pnpExecArgv, + }, + } + : undefined, }, { server: { diff --git a/src/worker/types.ts b/src/worker/types.ts index d7c5f575..ebbd4f00 100644 --- a/src/worker/types.ts +++ b/src/worker/types.ts @@ -6,12 +6,13 @@ export interface WorkerMeta { configFile?: string workspaceFile?: string env: Record | undefined + pnpApi?: string + pnpLoader?: string } export interface WorkerRunnerOptions { type: 'init' meta: WorkerMeta - loader?: string } export interface EventReady { diff --git a/src/worker/worker.ts b/src/worker/worker.ts index 1bf82a3b..e413f77b 100644 --- a/src/worker/worker.ts +++ b/src/worker/worker.ts @@ -6,6 +6,7 @@ import { Vitest } from './vitest' import { initVitest } from './init' import { WorkerProcessEmitter } from './emitter' +const _require = require const emitter = new WorkerProcessEmitter() process.on('message', async function onMessage(message: any) { @@ -14,8 +15,13 @@ process.on('message', async function onMessage(message: any) { const data = message as WorkerRunnerOptions try { - if (data.loader) - register(data.loader) + if (data.meta.pnpApi) { + _require(data.meta.pnpApi).setup() + } + + if (data.meta.pnpLoader) { + register(data.meta.pnpLoader) + } const { reporter, vitest } = await initVitest(data.meta)