Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions packages/vite/src/node/optimizer/rolldownDepPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,20 @@ export function rolldownDepPlugin(
const kind = options.kind

if (moduleListContains(external, id)) {
// resolve the excluded dep from its importer and keep the resolved
// path in the bundle, so that the import works even when the dep
// is not hoisted to the root node_modules (#21088). A bare id kept
// in the bundle would be resolved from node_modules/.vite/deps at
// serve time and only works for hoisted layouts.
if (importer) {
const resolved = await resolve(id, importer, kind)
if (resolved && path.isAbsolute(resolved)) {
return {
id: resolved,
external: 'absolute',
}
}
}
return {
id: id,
external: 'absolute',
Expand Down Expand Up @@ -409,10 +423,8 @@ export function rolldownCjsExternalPlugin(
id: cjsExternalFacadeNamespace + id,
}
}
return {
id,
external: 'absolute',
}
// fall through to vite:dep-pre-bundle which resolves the excluded
// dep from its importer (#21088)
},
},
load: {
Expand Down
6 changes: 6 additions & 0 deletions playground/optimize-deps/__tests__/optimize-deps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ test('import optimize-excluded package that imports optimized-included package',
.toBe('nested-include')
})

test('optimized dep importing non-hoisted excluded dep, from a shared chunk', async () => {
await expect
.poll(() => page.textContent('.excluded-not-hoisted'))
.toBe('*A* *B*')
})

test('import aliased package with colon', async () => {
await expect.poll(() => page.textContent('.url')).toBe('vite.dev')
})
Expand Down
2 changes: 2 additions & 0 deletions playground/optimize-deps/dep-importing-excluded/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { wrap } from './util.js'
export const msgA = wrap('A')
13 changes: 13 additions & 0 deletions playground/optimize-deps/dep-importing-excluded/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@vitejs/test-dep-importing-excluded",
"private": true,
"version": "1.0.0",
"type": "module",
"exports": {
".": "./index.js",
"./second": "./second.js"
},
"dependencies": {
"@vitejs/test-excluded-not-hoisted": "file:../excluded-not-hoisted"
}
}
2 changes: 2 additions & 0 deletions playground/optimize-deps/dep-importing-excluded/second.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { wrap } from './util.js'
export const msgB = wrap('B')
2 changes: 2 additions & 0 deletions playground/optimize-deps/dep-importing-excluded/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { tag } from '@vitejs/test-excluded-not-hoisted'
export const wrap = tag
1 change: 1 addition & 0 deletions playground/optimize-deps/excluded-not-hoisted/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const tag = (s) => '*' + s + '*'
7 changes: 7 additions & 0 deletions playground/optimize-deps/excluded-not-hoisted/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@vitejs/test-excluded-not-hoisted",
"private": true,
"version": "1.0.0",
"type": "module",
"main": "index.js"
}
7 changes: 7 additions & 0 deletions playground/optimize-deps/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ <h2>Dep from hidden dir</h2>
<h2>Nested include</h2>
<div>Module path: <span class="nested-include"></span></div>

<h2>Excluded dep resolved from importer</h2>
<div>Should show *A* *B*: <span class="excluded-not-hoisted"></span></div>

<h2>Alias with colon</h2>
<div>URL: <span class="url"></span></div>

Expand Down Expand Up @@ -218,6 +221,10 @@ <h2>Import the CommonJS external package that omits the js suffix</h2>
import { nestedInclude } from '@vitejs/test-nested-exclude'
text('.nested-include', nestedInclude)

import { msgA } from '@vitejs/test-dep-importing-excluded'
import { msgB } from '@vitejs/test-dep-importing-excluded/second'
text('.excluded-not-hoisted', msgA + ' ' + msgB)

import { parse } from 'node:url'
text('.url', parse('https://vite.dev').hostname)

Expand Down
1 change: 1 addition & 0 deletions playground/optimize-deps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@vitejs/test-dep-lodash.clonedeep": "file:./dep-lodash-clonedeep",
"@vitejs/test-dep-lodash-es": "file:./dep-lodash-es",
"@vitejs/test-nested-exclude": "file:./nested-exclude",
"@vitejs/test-dep-importing-excluded": "file:./dep-importing-excluded",
"phoenix": "^1.8.9",
"react": "^19.2.7",
"react-dom": "^19.2.7",
Expand Down
1 change: 1 addition & 0 deletions playground/optimize-deps/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default defineConfig({
],
exclude: [
'@vitejs/test-nested-exclude',
'@vitejs/test-excluded-not-hoisted',
'@vitejs/test-dep-non-optimized',
'@vitejs/test-dep-esm-external',
'stream',
Expand Down
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

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