Skip to content

Commit

Permalink
fix(vitest): support assets in new URL in Vite 5 (#4258)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Oct 6, 2023
1 parent e7e8c3c commit d280f48
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Expand Up @@ -14,7 +14,8 @@
"paths": ["path"]
}
],
"import/no-named-as-default": "off"
"import/no-named-as-default": "off",
"no-cond-assign": "off"
},
"overrides": [
{
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/node/plugins/index.ts
Expand Up @@ -14,6 +14,7 @@ import { MocksPlugin } from './mocks'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow } from './utils'
import { VitestResolver } from './vitestResolver'
import { VitestOptimizer } from './optimizer'
import { NormalizeURLPlugin } from './normalizeURL'

export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('test')): Promise<VitePlugin[]> {
const userConfig = deepMerge({}, options) as UserConfig
Expand Down Expand Up @@ -185,6 +186,7 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
MocksPlugin(),
VitestResolver(ctx),
VitestOptimizer(),
NormalizeURLPlugin(),
]
.filter(notNullish)
}
38 changes: 38 additions & 0 deletions packages/vitest/src/node/plugins/normalizeURL.ts
@@ -0,0 +1,38 @@
import { stripLiteral } from 'strip-literal'
import type { Plugin } from 'vite'

const metaUrlLength = 'import.meta.url'.length
const locationString = 'self.location'.padEnd(metaUrlLength, ' ')

// Vite transforms new URL('./path', import.meta.url) to new URL('/path.js', import.meta.url)
// This makes "href" equal to "http://localhost:3000/path.js" in the browser, but if we keep it like this,
// then in tests the URL will become "file:///path.js".
// To battle this, we replace "import.meta.url" with "self.location" in the code to keep the browser behavior.
export function NormalizeURLPlugin(): Plugin {
return {
name: 'vitest:normalize-url',
enforce: 'post',
transform(code, id, options) {
const ssr = options?.ssr === true
if (ssr || !code.includes('new URL') || !code.includes('import.meta.url'))
return

const cleanString = stripLiteral(code)
const assetImportMetaUrlRE
= /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g

let updatedCode = code
let match: RegExpExecArray | null
while ((match = assetImportMetaUrlRE.exec(cleanString))) {
const { 0: exp, index } = match
const metaUrlIndex = index + exp.indexOf('import.meta.url')
updatedCode = updatedCode.slice(0, metaUrlIndex) + locationString + updatedCode.slice(metaUrlIndex + metaUrlLength)
}

return {
code: updatedCode,
map: null,
}
},
}
}
2 changes: 1 addition & 1 deletion packages/vitest/src/node/plugins/ssrReplacer.ts
Expand Up @@ -10,7 +10,7 @@ export function SsrReplacerPlugin(): Plugin {
name: 'vitest:ssr-replacer',
enforce: 'pre',
transform(code, id) {
if (!/\bimport\.meta\.env\b/.test(code) && !/\bimport\.meta\.url\b/.test(code))
if (!/\bimport\.meta\.env\b/.test(code))
return null

let s: MagicString | null = null
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/node/plugins/workspace.ts
Expand Up @@ -12,6 +12,7 @@ import { MocksPlugin } from './mocks'
import { deleteDefineConfig, hijackVitePluginInject, resolveFsAllow } from './utils'
import { VitestResolver } from './vitestResolver'
import { VitestOptimizer } from './optimizer'
import { NormalizeURLPlugin } from './normalizeURL'

interface WorkspaceOptions extends UserWorkspaceConfig {
root?: string
Expand Down Expand Up @@ -125,5 +126,6 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
MocksPlugin(),
VitestResolver(project.ctx),
VitestOptimizer(),
NormalizeURLPlugin(),
]
}

0 comments on commit d280f48

Please sign in to comment.