Skip to content

Commit

Permalink
fix(vite-node): correctly resolve virtual modules (#3544)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jun 15, 2023
1 parent 02196f9 commit 0cbb07b
Show file tree
Hide file tree
Showing 17 changed files with 475 additions and 47 deletions.
10 changes: 10 additions & 0 deletions examples/sveltekit/.gitignore
@@ -0,0 +1,10 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
28 changes: 28 additions & 0 deletions examples/sveltekit/package.json
@@ -0,0 +1,28 @@
{
"name": "vitest-0.32.0-sveltekit",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test:unit": "vitest",
"lint": "prettier --plugin-search-dir . --check .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.1.0",
"@sveltejs/kit": "^1.20.2",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^3.59.1",
"svelte-check": "^3.4.3",
"tslib": "^2.5.3",
"typescript": "^5.1.3",
"vite": "^4.3.9",
"vitest": "latest"
}
}
12 changes: 12 additions & 0 deletions examples/sveltekit/src/app.d.ts
@@ -0,0 +1,12 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}

export {};
12 changes: 12 additions & 0 deletions examples/sveltekit/src/app.html
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
8 changes: 8 additions & 0 deletions examples/sveltekit/src/lib/add.test.ts
@@ -0,0 +1,8 @@
import { describe, expect, it } from 'vitest'
import { add } from './add'

describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3)
})
})
8 changes: 8 additions & 0 deletions examples/sveltekit/src/lib/add.ts
@@ -0,0 +1,8 @@
import { dev } from '$app/environment'

export function add(a: number, b: number) {
if (dev)
console.warn(`Adding ${a} and ${b}`)

return a + b
}
2 changes: 2 additions & 0 deletions examples/sveltekit/src/routes/+page.svelte
@@ -0,0 +1,2 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
Binary file added examples/sveltekit/static/favicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions examples/sveltekit/svelte.config.js
@@ -0,0 +1,18 @@
import adapter from '@sveltejs/adapter-auto'
import { vitePreprocess } from '@sveltejs/kit/vite'

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
},
}

export default config
17 changes: 17 additions & 0 deletions examples/sveltekit/tsconfig.json
@@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}
6 changes: 6 additions & 0 deletions examples/sveltekit/vite.config.ts
@@ -0,0 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vitest/config'

export default defineConfig({
plugins: [sveltekit()],
})
38 changes: 20 additions & 18 deletions packages/vite-node/src/client.ts
Expand Up @@ -234,26 +234,28 @@ export class ViteNodeRunner {
private async _resolveUrl(id: string, importer?: string): Promise<[url: string, fsPath: string]> {
// we don't pass down importee here, because otherwise Vite doesn't resolve it correctly
// should be checked before normalization, because it removes this prefix
// TODO: this is a hack, we should find a better way to handle this
if (importer && id.startsWith(VALID_ID_PREFIX))
importer = undefined
id = normalizeRequestId(id, this.options.base)
if (!this.shouldResolveId(id))
return [id, id]
const { path, exists } = toFilePath(id, this.root)
const dep = normalizeRequestId(id, this.options.base)
if (!this.shouldResolveId(dep))
return [dep, dep]
const { path, exists } = toFilePath(dep, this.root)
if (!this.options.resolveId || exists)
return [id, path]
const resolved = await this.options.resolveId(id, importer)
if (!resolved) {
const error = new Error(
`Cannot find module '${id}'${importer ? ` imported from '${importer}'` : ''}.`
+ '\n\n- If you rely on tsconfig.json to resolve modules, please install "vite-tsconfig-paths" plugin to handle module resolution.'
+ '\n - Make sure you don\'t have relative aliases in your Vitest config. Use absolute paths instead. Read more: https://vitest.dev/guide/common-errors',
)
Object.defineProperty(error, 'code', { value: 'ERR_MODULE_NOT_FOUND', enumerable: true })
Object.defineProperty(error, Symbol.for('vitest.error.not_found.data'), { value: { id, importer }, enumerable: false })
throw error
}
const resolvedId = normalizeRequestId(resolved.id, this.options.base)
return [dep, path]
const resolved = await this.options.resolveId(dep, importer)
// TODO: we need to better handle module resolution when different urls point to the same module
// if (!resolved) {
// const error = new Error(
// `Cannot find module '${id}'${importer ? ` imported from '${importer}'` : ''}.`
// + '\n\n- If you rely on tsconfig.json\'s "paths" to resolve modules, please install "vite-tsconfig-paths" plugin to handle module resolution.'
// + '\n- Make sure you don\'t have relative aliases in your Vitest config. Use absolute paths instead. Read more: https://vitest.dev/guide/common-errors',
// )
// Object.defineProperty(error, 'code', { value: 'ERR_MODULE_NOT_FOUND', enumerable: true })
// Object.defineProperty(error, Symbol.for('vitest.error.not_found.data'), { value: { id: dep, importer }, enumerable: false })
// throw error
// }
const resolvedId = resolved ? normalizeRequestId(resolved.id, this.options.base) : dep
return [resolvedId, resolvedId]
}

Expand Down Expand Up @@ -282,7 +284,7 @@ export class ViteNodeRunner {
const mod = this.moduleCache.getByModuleId(moduleId)

const request = async (dep: string) => {
const [id, depFsPath] = await this.resolveUrl(`${dep}`, fsPath)
const [id, depFsPath] = await this.resolveUrl(String(dep), fsPath)
const depMod = this.moduleCache.getByModuleId(depFsPath)
depMod.importers.add(moduleId)
mod.imports.add(depFsPath)
Expand Down

0 comments on commit 0cbb07b

Please sign in to comment.