Skip to content

Commit

Permalink
fix(ssr): improve missing file error (#10880)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Nov 12, 2022
1 parent 828eeca commit 5451a34
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 14 deletions.
4 changes: 2 additions & 2 deletions packages/vite/src/node/plugins/importAnalysis.ts
Expand Up @@ -9,7 +9,6 @@ import { parse as parseJS } from 'acorn'
import type { Node } from 'estree'
import { findStaticImports, parseStaticImport } from 'mlly'
import { makeLegalIdentifier } from '@rollup/pluginutils'
import { getDepOptimizationConfig } from '..'
import type { ViteDevServer } from '..'
import {
CLIENT_DIR,
Expand Down Expand Up @@ -44,6 +43,7 @@ import {
unwrapId,
wrapId
} from '../utils'
import { getDepOptimizationConfig } from '../config'
import type { ResolvedConfig } from '../config'
import type { Plugin } from '../plugin'
import {
Expand Down Expand Up @@ -712,7 +712,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
// These requests will also be registered in transformRequest to be awaited
// by the deps optimizer
if (config.server.preTransformRequests && staticImportedUrls.size) {
staticImportedUrls.forEach(({ url, id }) => {
staticImportedUrls.forEach(({ url }) => {
url = removeImportQuery(url)
transformRequest(url, server, { ssr }).catch((e) => {
if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) {
Expand Down
6 changes: 5 additions & 1 deletion packages/vite/src/node/server/middlewares/transform.ts
Expand Up @@ -18,7 +18,7 @@ import {
unwrapId
} from '../../utils'
import { send } from '../send'
import { transformRequest } from '../transformRequest'
import { ERR_LOAD_URL, transformRequest } from '../transformRequest'
import { isHTMLProxy } from '../../plugins/html'
import {
DEP_VERSION_RE,
Expand Down Expand Up @@ -224,6 +224,10 @@ export function transformMiddleware(
// error but a normal part of the missing deps discovery flow
return
}
if (e?.code === ERR_LOAD_URL) {
// Let other middleware handle if we can't load the url via transformRequest
return next()
}
return next(e)
}

Expand Down
25 changes: 14 additions & 11 deletions packages/vite/src/node/server/transformRequest.ts
Expand Up @@ -21,6 +21,9 @@ import { getDepsOptimizer } from '../optimizer'
import { injectSourcesContent } from './sourcemap'
import { isFileServingAllowed } from './middlewares/static'

export const ERR_LOAD_URL = 'ERR_LOAD_URL'
export const ERR_LOAD_PUBLIC_URL = 'ERR_LOAD_PUBLIC_URL'

const debugLoad = createDebugger('vite:load')
const debugTransform = createDebugger('vite:transform')
const debugCache = createDebugger('vite:cache')
Expand Down Expand Up @@ -215,18 +218,18 @@ async function loadAndTransform(
}
}
if (code == null) {
if (checkPublicFile(url, config)) {
throw new Error(
`Failed to load url ${url} (resolved id: ${id}). ` +
`This file is in /public and will be copied as-is during build without ` +
`going through the plugin transforms, and therefore should not be ` +
`imported from source code. It can only be referenced via HTML tags.`
)
} else {
return null
}
const isPublicFile = checkPublicFile(url, config)
const msg = isPublicFile
? `This file is in /public and will be copied as-is during build without ` +
`going through the plugin transforms, and therefore should not be ` +
`imported from source code. It can only be referenced via HTML tags.`
: `Does the file exist?`
const err: any = new Error(
`Failed to load url ${url} (resolved id: ${id}). ${msg}`
)
err.code = isPublicFile ? ERR_LOAD_PUBLIC_URL : ERR_LOAD_URL
throw err
}

// ensure module in graph after successful load
const mod = await moduleGraph.ensureEntryFromUrl(url, ssr)
ensureWatchedFile(watcher, mod.file, root)
Expand Down
@@ -0,0 +1,4 @@
// eslint-disable-next-line node/no-missing-import
import { foo } from './non-existent.js'

export const hello = 'world'
23 changes: 23 additions & 0 deletions packages/vite/src/node/ssr/__tests__/ssrLoadModule.spec.ts
@@ -0,0 +1,23 @@
import { fileURLToPath } from 'node:url'
import { expect, test } from 'vitest'
import { createServer } from '../../server'

const root = fileURLToPath(new URL('./', import.meta.url))

async function createDevServer() {
const server = await createServer({ configFile: false, root })
server.pluginContainer.buildStart({})
return server
}

test('ssrLoad', async () => {
expect.assertions(1)
const server = await createDevServer()
try {
await server.ssrLoadModule('/fixtures/modules/has-invalid-import.js')
} catch (e) {
expect(e.message).toBe(
'Failed to load url ./non-existent.js (resolved id: ./non-existent.js). Does the file exist?'
)
}
})

0 comments on commit 5451a34

Please sign in to comment.