Skip to content

Commit

Permalink
feat!: apply Vite resolving algorithm to node_modules libraries (#1673)
Browse files Browse the repository at this point in the history
* fix: apply Vite resolving algorithm to node_modules libraries

* chore: remove inlining solid-js

* chore: skip builtin

* refactor: cleanup

* chore: suppress loader warnings

* chore: add max limit to cpu  when running rollup
  • Loading branch information
sheremet-va committed Jul 26, 2022
1 parent 409aa45 commit b971ede
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 5 deletions.
3 changes: 0 additions & 3 deletions examples/solid/vite.config.mjs
Expand Up @@ -10,9 +10,6 @@ export default defineConfig({
transformMode: {
web: [/.[jt]sx?/],
},
deps: {
inline: [/solid-js/],
},
threads: false,
isolate: false,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/package.json
Expand Up @@ -62,7 +62,7 @@
},
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "rollup -c --watch -m inline",
"dev": "NODE_OPTIONS=\"--max-old-space-size=8192\" rollup -c --watch -m inline",
"prepublishOnly": "nr build"
},
"peerDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/rollup.config.js
Expand Up @@ -20,6 +20,7 @@ const entries = [
'src/node/cli.ts',
'src/node.ts',
'src/runtime/worker.ts',
'src/runtime/loader.ts',
'src/runtime/entry.ts',
'src/runtime/suite.ts',
'src/integrations/spy.ts',
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/constants.ts
@@ -1,6 +1,7 @@
import url from 'url'
import { resolve } from 'pathe'

export const rootDir = resolve(url.fileURLToPath(import.meta.url), '../../')
export const distDir = resolve(url.fileURLToPath(import.meta.url), '../../dist')

// if changed, update also jsdocs and docs
Expand Down
15 changes: 14 additions & 1 deletion packages/vitest/src/node/pool.ts
Expand Up @@ -7,7 +7,7 @@ import { Tinypool } from 'tinypool'
import { createBirpc } from 'birpc'
import type { RawSourceMap } from 'vite-node'
import type { ResolvedConfig, WorkerContext, WorkerRPC } from '../types'
import { distDir } from '../constants'
import { distDir, rootDir } from '../constants'
import { AggregateError } from '../utils'
import type { Vitest } from './core'

Expand All @@ -19,6 +19,9 @@ export interface WorkerPool {
}

const workerPath = _url.pathToFileURL(resolve(distDir, './worker.mjs')).href
const loaderPath = _url.pathToFileURL(resolve(distDir, './loader.mjs')).href

const suppressLoaderWarningsPath = resolve(rootDir, './suppress-warnings.cjs')

export function createPool(ctx: Vitest): WorkerPool {
const threadsCount = ctx.config.watch
Expand All @@ -28,6 +31,8 @@ export function createPool(ctx: Vitest): WorkerPool {
const maxThreads = ctx.config.maxThreads ?? threadsCount
const minThreads = ctx.config.minThreads ?? threadsCount

const conditions = ctx.server.config.resolve.conditions?.flatMap(c => ['-C', c])

const options: TinypoolOptions = {
filename: workerPath,
// TODO: investigate further
Expand All @@ -36,6 +41,14 @@ export function createPool(ctx: Vitest): WorkerPool {

maxThreads,
minThreads,

execArgv: [
'--require',
suppressLoaderWarningsPath,
'--experimental-loader',
loaderPath,
...conditions || [],
],
}

if (ctx.config.isolate) {
Expand Down
31 changes: 31 additions & 0 deletions packages/vitest/src/runtime/loader.ts
@@ -0,0 +1,31 @@
import { pathToFileURL } from 'url'
import { isNodeBuiltin } from 'mlly'
import { normalizeModuleId } from 'vite-node/utils'
import { getWorkerState } from '../utils'
import type { Loader, Resolver } from '../types/loader'

// apply transformations only to libraries
// inline code preccessed by vite-node
export const resolve: Resolver = async (url, context, next) => {
const { parentURL } = context
if (!parentURL || !parentURL.includes('node_modules') || isNodeBuiltin(url))
return next(url, context, next)

const id = normalizeModuleId(url)
const importer = normalizeModuleId(parentURL)
const state = getWorkerState()
const resolver = state?.rpc.resolveId
if (resolver) {
const resolved = await resolver(id, importer)
if (resolved) {
return {
url: pathToFileURL(resolved.id).toString(),
}
}
}
return next(url, context, next)
}

export const load: Loader = (url, context, next) => {
return next(url, context, next)
}
37 changes: 37 additions & 0 deletions packages/vitest/src/types/loader.ts
@@ -0,0 +1,37 @@
import type { Awaitable } from './general'

interface ModuleContext {
conditions: string[]
parentURL?: string
}

enum ModuleFormat {
Builtin = 'builtin',
Commonjs = 'commonjs',
Json = 'json',
Module = 'module',
Wasm = 'wasm',
}

interface ResolveResult {
url: string
format?: ModuleFormat
}

export interface Resolver {
(url: string, context: ModuleContext, next: Resolver): Awaitable<ResolveResult>
}

interface LoaderContext {
format: ModuleFormat
importAssertions: Record<string, string>
}

interface LoaderResult {
format: ModuleFormat
source: string | ArrayBuffer | SharedArrayBuffer | Uint8Array
}

export interface Loader {
(url: string, context: LoaderContext, next: Loader): Awaitable<LoaderResult>
}
20 changes: 20 additions & 0 deletions packages/vitest/suppress-warnings.cjs
@@ -0,0 +1,20 @@
// borrowed from tsx implementation:
// https://github.com/esbuild-kit/tsx

const ignoreWarnings = new Set([
'--experimental-loader is an experimental feature. This feature could change at any time',
'Custom ESM Loaders is an experimental feature. This feature could change at any time',
])

const { emit } = process

process.emit = function (event, warning) {
if (
event === 'warning'
&& ignoreWarnings.has(warning.message)
)
return

// eslint-disable-next-line prefer-rest-params
return Reflect.apply(emit, this, arguments)
}

0 comments on commit b971ede

Please sign in to comment.