feat(optimizer): show a friendly warning with 404 instead of 504 outdated optimize dep (#16080)

Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
This commit is contained in:
翠 / green 2024-03-13 23:53:50 +09:00 committed by GitHub
parent 1d5eec477e
commit 7ee426194f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 65 additions and 2 deletions

View File

@ -10,6 +10,8 @@ import { cleanUrl } from '../../shared/utils'
export const ERR_OPTIMIZE_DEPS_PROCESSING_ERROR =
'ERR_OPTIMIZE_DEPS_PROCESSING_ERROR'
export const ERR_OUTDATED_OPTIMIZED_DEP = 'ERR_OUTDATED_OPTIMIZED_DEP'
export const ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR =
'ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR'
const debug = createDebugger('vite:optimize-deps')
@ -68,8 +70,12 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin {
try {
return await fsp.readFile(file, 'utf-8')
} catch (e) {
// Outdated non-entry points (CHUNK), loaded after a rerun
throwOutdatedRequest(id)
const newMetadata = depsOptimizer.metadata
if (optimizedDepInfoFromFile(newMetadata, file)) {
// Outdated non-entry points (CHUNK), loaded after a rerun
throwOutdatedRequest(id)
}
throwFileNotFoundInOptimizedDep(id)
}
}
},
@ -97,3 +103,15 @@ export function throwOutdatedRequest(id: string): never {
// send a 504 status code request timeout
throw err
}
export function throwFileNotFoundInOptimizedDep(id: string): never {
const err: any = new Error(
`The file does not exist at "${id}" which is in the optimize deps directory. ` +
`The dependency might be incompatible with the dep optimizer. ` +
`Try adding it to \`optimizeDeps.exclude\`.`,
)
err.code = ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR
// This error will be caught by the transform middleware that will
// send a 404 status code not found
throw err
}

View File

@ -27,6 +27,7 @@ import {
isDirectRequest,
} from '../../plugins/css'
import {
ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR,
ERR_OPTIMIZE_DEPS_PROCESSING_ERROR,
ERR_OUTDATED_OPTIMIZED_DEP,
} from '../../plugins/optimizedDeps'
@ -253,6 +254,15 @@ export function transformMiddleware(
// error but a normal part of the missing deps discovery flow
return
}
if (e?.code === ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR) {
// Skip if response has already been sent
if (!res.writableEnded) {
res.statusCode = 404
res.end()
}
server.config.logger.warn(colors.yellow(e.message))
return
}
if (e?.code === ERR_LOAD_URL) {
// Let other middleware handle if we can't load the url via transformRequest
return next()

View File

@ -319,3 +319,11 @@ test('long file name should work', async () => {
`hello world`,
)
})
test.runIf(isServe)('warn on incompatible dependency', () => {
expect(serverLogs).toContainEqual(
expect.stringContaining(
'The dependency might be incompatible with the dep optimizer.',
),
)
})

View File

@ -0,0 +1,3 @@
const subUrl = new URL('./sub.js', import.meta.url)
export default () => import(subUrl)

View File

@ -0,0 +1,7 @@
{
"name": "@vitejs/test-dep-incompatible",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "index.js"
}

View File

@ -0,0 +1 @@
export default 'sub'

View File

@ -263,3 +263,8 @@
text('.clonedeep-slash', cloneDeepSlash({ name: 'clonedeep-slash' }).name)
text('.clonedeep-dot', cloneDeepDot({ name: 'clonedeep-dot' }).name)
</script>
<script type="module">
import loadSub from '@vitejs/test-dep-incompatible'
loadSub() // should show an error that tells there's an incompatible dep
</script>

View File

@ -20,6 +20,7 @@
"@vitejs/test-dep-cjs-with-assets": "file:./dep-cjs-with-assets",
"@vitejs/test-dep-css-require": "file:./dep-css-require",
"@vitejs/test-dep-esbuild-plugin-transform": "file:./dep-esbuild-plugin-transform",
"@vitejs/test-dep-incompatible": "file:./dep-incompatible",
"@vitejs/test-dep-linked": "link:./dep-linked",
"@vitejs/test-dep-linked-include": "link:./dep-linked-include",
"@vitejs/test-dep-node-env": "file:./dep-node-env",

View File

@ -906,6 +906,9 @@ importers:
'@vitejs/test-dep-esbuild-plugin-transform':
specifier: file:./dep-esbuild-plugin-transform
version: file:playground/optimize-deps/dep-esbuild-plugin-transform
'@vitejs/test-dep-incompatible':
specifier: file:./dep-incompatible
version: file:playground/optimize-deps/dep-incompatible
'@vitejs/test-dep-linked':
specifier: link:./dep-linked
version: link:dep-linked
@ -1019,6 +1022,8 @@ importers:
playground/optimize-deps/dep-esbuild-plugin-transform: {}
playground/optimize-deps/dep-incompatible: {}
playground/optimize-deps/dep-linked:
dependencies:
lodash-es:
@ -9901,6 +9906,11 @@ packages:
name: '@vitejs/test-dep-esbuild-plugin-transform'
dev: false
file:playground/optimize-deps/dep-incompatible:
resolution: {directory: playground/optimize-deps/dep-incompatible, type: directory}
name: '@vitejs/test-dep-incompatible'
dev: false
file:playground/optimize-deps/dep-node-env:
resolution: {directory: playground/optimize-deps/dep-node-env, type: directory}
name: '@vitejs/test-dep-node-env'