Skip to content

Commit

Permalink
feat(optimizer): show a friendly warning with 404 instead of 504 outd…
Browse files Browse the repository at this point in the history
…ated optimize dep (#16080)

Co-authored-by: Bjorn Lu <[email protected]>
  • Loading branch information
sapphi-red and bluwy authored Mar 13, 2024
1 parent 1d5eec4 commit 7ee4261
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 2 deletions.
22 changes: 20 additions & 2 deletions packages/vite/src/node/plugins/optimizedDeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down Expand Up @@ -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)
}
}
},
Expand Down Expand Up @@ -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
}
10 changes: 10 additions & 0 deletions packages/vite/src/node/server/middlewares/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions playground/optimize-deps/__tests__/optimize-deps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.',
),
)
})
3 changes: 3 additions & 0 deletions playground/optimize-deps/dep-incompatible/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const subUrl = new URL('./sub.js', import.meta.url)

export default () => import(subUrl)
7 changes: 7 additions & 0 deletions playground/optimize-deps/dep-incompatible/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@vitejs/test-dep-incompatible",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "index.js"
}
1 change: 1 addition & 0 deletions playground/optimize-deps/dep-incompatible/sub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'sub'
5 changes: 5 additions & 0 deletions playground/optimize-deps/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,8 @@ <h2>Long file name import works</h2>
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>
1 change: 1 addition & 0 deletions playground/optimize-deps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ee4261

Please sign in to comment.