Skip to content

Commit

Permalink
fix(resolve): fix resolve cache to consider conditions and more (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Oct 10, 2024
1 parent af3cddf commit 2017a33
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 31 deletions.
209 changes: 209 additions & 0 deletions packages/vite/src/node/__tests__/environment.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import path from 'node:path'
import { describe, expect, onTestFinished, test } from 'vitest'
import type { RollupOutput } from 'rollup'
import { createServer } from '../server'
import { defineConfig } from '../config'
import { createBuilder } from '../build'
import { createServerModuleRunner } from '../ssr/runtime/serverModuleRunner'

describe('custom environment conditions', () => {
function getConfig() {
return defineConfig({
root: import.meta.dirname,
logLevel: 'error',
server: {
middlewareMode: true,
},
environments: {
// no web / default
ssr: {
resolve: {
noExternal: true,
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/ssr',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
// web / worker
worker: {
webCompatible: true,
resolve: {
noExternal: true,
conditions: ['worker'],
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/worker',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
// web / custom1
custom1: {
webCompatible: true,
resolve: {
noExternal: true,
conditions: ['custom1'],
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/custom1',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
// no web / custom2
custom2: {
webCompatible: false,
resolve: {
noExternal: true,
conditions: ['custom2'],
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/custom2',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
// no web / custom3
custom3: {
webCompatible: false,
resolve: {
noExternal: true,
conditions: ['custom3'],
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/custom3',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
// same as custom3
custom3_2: {
webCompatible: false,
resolve: {
noExternal: true,
conditions: ['custom3'],
},
build: {
outDir: path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist/custom3_2',
),
rollupOptions: {
input: { index: '@vitejs/test-dep-conditions' },
},
},
},
},
})
}

test('dev', async () => {
const server = await createServer(getConfig())
onTestFinished(() => server.close())

const results: Record<string, unknown> = {}
for (const key of [
'ssr',
'worker',
'custom1',
'custom2',
'custom3',
'custom3_2',
]) {
const runner = createServerModuleRunner(server.environments[key], {
hmr: {
logger: false,
},
sourcemapInterceptor: false,
})
const mod = await runner.import('@vitejs/test-dep-conditions')
results[key] = mod.default
}
expect(results).toMatchInlineSnapshot(`
{
"custom1": "index.custom1.js",
"custom2": "index.custom2.js",
"custom3": "index.custom3.js",
"custom3_2": "index.custom3.js",
"ssr": "index.default.js",
"worker": "index.worker.js",
}
`)
})

test('css', async () => {
const server = await createServer(getConfig())
onTestFinished(() => server.close())

const modJs = await server.ssrLoadModule(
'/fixtures/test-dep-conditions-app/entry.js',
)
const modCss = await server.ssrLoadModule(
'/fixtures/test-dep-conditions-app/entry.css?inline',
)
expect([modCss.default.replace(/\s+/g, ' '), modJs.default])
.toMatchInlineSnapshot(`
[
".test-css { color: orange; } ",
"index.default.js",
]
`)
})

test('build', async () => {
const builder = await createBuilder(getConfig())
const results: Record<string, unknown> = {}
for (const key of [
'ssr',
'worker',
'custom1',
'custom2',
'custom3',
'custom3_2',
]) {
const output = await builder.build(builder.environments[key])
const chunk = (output as RollupOutput).output[0]
const mod = await import(
path.join(
import.meta.dirname,
'fixtures/test-dep-conditions/dist',
key,
chunk.fileName,
)
)
results[key] = mod.default
}
expect(results).toMatchInlineSnapshot(`
{
"custom1": "index.custom1.js",
"custom2": "index.custom2.js",
"custom3": "index.custom3.js",
"custom3_2": "index.custom3.js",
"ssr": "index.default.js",
"worker": "index.worker.js",
}
`)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '@vitejs/test-dep-conditions';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import dep from '@vitejs/test-dep-conditions'
export default dep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.browser.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.test-css {
color: orange;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.custom1.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.custom2.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.custom3.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.default.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'index.worker.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@vitejs/test-dep-conditions",
"private": true,
"type": "module",
"exports": {
".": {
"style": "./index.css",
"custom1": "./index.custom1.js",
"custom2": "./index.custom2.js",
"custom3": "./index.custom3.js",
"worker": "./index.worker.js",
"browser": "./index.browser.js",
"default": "./index.default.js"
}
}
}
3 changes: 2 additions & 1 deletion packages/vite/src/node/__tests__/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"private": true,
"version": "0.0.0",
"dependencies": {
"@vitejs/cjs-ssr-dep": "link:./fixtures/cjs-ssr-dep"
"@vitejs/cjs-ssr-dep": "link:./fixtures/cjs-ssr-dep",
"@vitejs/test-dep-conditions": "file:./fixtures/test-dep-conditions"
}
}
46 changes: 28 additions & 18 deletions packages/vite/src/node/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
tryStatSync,
} from './utils'
import type { Plugin } from './plugin'
import type { InternalResolveOptions } from './plugins/resolve'

let pnp: typeof import('pnpapi') | undefined
if (process.versions.pnp) {
Expand All @@ -23,10 +24,15 @@ export type PackageCache = Map<string, PackageData>
export interface PackageData {
dir: string
hasSideEffects: (id: string) => boolean | 'no-treeshake' | null
webResolvedImports: Record<string, string | undefined>
nodeResolvedImports: Record<string, string | undefined>
setResolvedCache: (key: string, entry: string, targetWeb: boolean) => void
getResolvedCache: (key: string, targetWeb: boolean) => string | undefined
setResolvedCache: (
key: string,
entry: string,
options: InternalResolveOptions,
) => void
getResolvedCache: (
key: string,
options: InternalResolveOptions,
) => string | undefined
data: {
[field: string]: any
name: string
Expand Down Expand Up @@ -201,31 +207,35 @@ export function loadPackageData(pkgPath: string): PackageData {
hasSideEffects = () => null
}

const resolvedCache: Record<string, string | undefined> = {}
const pkg: PackageData = {
dir: pkgDir,
data,
hasSideEffects,
webResolvedImports: {},
nodeResolvedImports: {},
setResolvedCache(key: string, entry: string, targetWeb: boolean) {
if (targetWeb) {
pkg.webResolvedImports[key] = entry
} else {
pkg.nodeResolvedImports[key] = entry
}
setResolvedCache(key, entry, options) {
resolvedCache[getResolveCacheKey(key, options)] = entry
},
getResolvedCache(key: string, targetWeb: boolean) {
if (targetWeb) {
return pkg.webResolvedImports[key]
} else {
return pkg.nodeResolvedImports[key]
}
getResolvedCache(key, options) {
return resolvedCache[getResolveCacheKey(key, options)]
},
}

return pkg
}

function getResolveCacheKey(key: string, options: InternalResolveOptions) {
// cache key needs to include options which affect
// `resolvePackageEntry` or `resolveDeepImport`
return [
key,
options.webCompatible ? '1' : '0',
options.isRequire ? '1' : '0',
options.conditions.join('_'),
options.extensions.join('_'),
options.mainFields.join('_'),
].join('|')
}

export function watchPackageDataPlugin(packageCache: PackageCache): Plugin {
// a list of files to watch before the plugin is ready
const watchQueue = new Set<string>()
Expand Down
19 changes: 7 additions & 12 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ export function resolvePackageEntry(
): string | undefined {
const { file: idWithoutPostfix, postfix } = splitFileAndPostfix(id)

const cached = getResolvedCache('.', !!options.webCompatible)
const cached = getResolvedCache('.', options)
if (cached) {
return cached + postfix
}
Expand Down Expand Up @@ -1094,7 +1094,7 @@ export function resolvePackageEntry(
resolvedEntryPoint,
)}${postfix !== '' ? ` (postfix: ${postfix})` : ''}`,
)
setResolvedCache('.', resolvedEntryPoint, !!options.webCompatible)
setResolvedCache('.', resolvedEntryPoint, options)
return resolvedEntryPoint + postfix
}
}
Expand Down Expand Up @@ -1151,16 +1151,10 @@ function resolveExportsOrImports(

function resolveDeepImport(
id: string,
{
webResolvedImports,
setResolvedCache,
getResolvedCache,
dir,
data,
}: PackageData,
{ setResolvedCache, getResolvedCache, dir, data }: PackageData,
options: InternalResolveOptions,
): string | undefined {
const cache = getResolvedCache(id, !!options.webCompatible)
const cache = getResolvedCache(id, options)
if (cache) {
return cache
}
Expand Down Expand Up @@ -1200,7 +1194,8 @@ function resolveDeepImport(
if (mapped) {
relativeId = mapped + postfix
} else if (mapped === false) {
return (webResolvedImports[id] = browserExternalId)
setResolvedCache(id, browserExternalId, options)
return browserExternalId
}
}

Expand All @@ -1214,7 +1209,7 @@ function resolveDeepImport(
debug?.(
`[node/deep-import] ${colors.cyan(id)} -> ${colors.dim(resolved)}`,
)
setResolvedCache(id, resolved, !!options.webCompatible)
setResolvedCache(id, resolved, options)
return resolved
}
}
Expand Down
Loading

0 comments on commit 2017a33

Please sign in to comment.