Skip to content

Commit 7ee4261

Browse files
sapphi-redbluwy
andauthored
feat(optimizer): show a friendly warning with 404 instead of 504 outdated optimize dep (#16080)
Co-authored-by: Bjorn Lu <[email protected]>
1 parent 1d5eec4 commit 7ee4261

File tree

9 files changed

+65
-2
lines changed

9 files changed

+65
-2
lines changed

packages/vite/src/node/plugins/optimizedDeps.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { cleanUrl } from '../../shared/utils'
1010
export const ERR_OPTIMIZE_DEPS_PROCESSING_ERROR =
1111
'ERR_OPTIMIZE_DEPS_PROCESSING_ERROR'
1212
export const ERR_OUTDATED_OPTIMIZED_DEP = 'ERR_OUTDATED_OPTIMIZED_DEP'
13+
export const ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR =
14+
'ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR'
1315

1416
const debug = createDebugger('vite:optimize-deps')
1517

@@ -68,8 +70,12 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin {
6870
try {
6971
return await fsp.readFile(file, 'utf-8')
7072
} catch (e) {
71-
// Outdated non-entry points (CHUNK), loaded after a rerun
72-
throwOutdatedRequest(id)
73+
const newMetadata = depsOptimizer.metadata
74+
if (optimizedDepInfoFromFile(newMetadata, file)) {
75+
// Outdated non-entry points (CHUNK), loaded after a rerun
76+
throwOutdatedRequest(id)
77+
}
78+
throwFileNotFoundInOptimizedDep(id)
7379
}
7480
}
7581
},
@@ -97,3 +103,15 @@ export function throwOutdatedRequest(id: string): never {
97103
// send a 504 status code request timeout
98104
throw err
99105
}
106+
107+
export function throwFileNotFoundInOptimizedDep(id: string): never {
108+
const err: any = new Error(
109+
`The file does not exist at "${id}" which is in the optimize deps directory. ` +
110+
`The dependency might be incompatible with the dep optimizer. ` +
111+
`Try adding it to \`optimizeDeps.exclude\`.`,
112+
)
113+
err.code = ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR
114+
// This error will be caught by the transform middleware that will
115+
// send a 404 status code not found
116+
throw err
117+
}

packages/vite/src/node/server/middlewares/transform.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
isDirectRequest,
2828
} from '../../plugins/css'
2929
import {
30+
ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR,
3031
ERR_OPTIMIZE_DEPS_PROCESSING_ERROR,
3132
ERR_OUTDATED_OPTIMIZED_DEP,
3233
} from '../../plugins/optimizedDeps'
@@ -253,6 +254,15 @@ export function transformMiddleware(
253254
// error but a normal part of the missing deps discovery flow
254255
return
255256
}
257+
if (e?.code === ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR) {
258+
// Skip if response has already been sent
259+
if (!res.writableEnded) {
260+
res.statusCode = 404
261+
res.end()
262+
}
263+
server.config.logger.warn(colors.yellow(e.message))
264+
return
265+
}
256266
if (e?.code === ERR_LOAD_URL) {
257267
// Let other middleware handle if we can't load the url via transformRequest
258268
return next()

playground/optimize-deps/__tests__/optimize-deps.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,11 @@ test('long file name should work', async () => {
319319
`hello world`,
320320
)
321321
})
322+
323+
test.runIf(isServe)('warn on incompatible dependency', () => {
324+
expect(serverLogs).toContainEqual(
325+
expect.stringContaining(
326+
'The dependency might be incompatible with the dep optimizer.',
327+
),
328+
)
329+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const subUrl = new URL('./sub.js', import.meta.url)
2+
3+
export default () => import(subUrl)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "@vitejs/test-dep-incompatible",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"main": "index.js"
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default 'sub'

playground/optimize-deps/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,8 @@ <h2>Long file name import works</h2>
263263
text('.clonedeep-slash', cloneDeepSlash({ name: 'clonedeep-slash' }).name)
264264
text('.clonedeep-dot', cloneDeepDot({ name: 'clonedeep-dot' }).name)
265265
</script>
266+
267+
<script type="module">
268+
import loadSub from '@vitejs/test-dep-incompatible'
269+
loadSub() // should show an error that tells there's an incompatible dep
270+
</script>

playground/optimize-deps/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@vitejs/test-dep-cjs-with-assets": "file:./dep-cjs-with-assets",
2121
"@vitejs/test-dep-css-require": "file:./dep-css-require",
2222
"@vitejs/test-dep-esbuild-plugin-transform": "file:./dep-esbuild-plugin-transform",
23+
"@vitejs/test-dep-incompatible": "file:./dep-incompatible",
2324
"@vitejs/test-dep-linked": "link:./dep-linked",
2425
"@vitejs/test-dep-linked-include": "link:./dep-linked-include",
2526
"@vitejs/test-dep-node-env": "file:./dep-node-env",

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)