Skip to content

Commit

Permalink
fix: needs es interop check for newly discovered deps (#7243)
Browse files Browse the repository at this point in the history
  • Loading branch information
patak-dev committed Mar 10, 2022
1 parent 2d7ba72 commit ba3047d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 44 deletions.
41 changes: 37 additions & 4 deletions packages/vite/src/node/optimizer/index.ts
Expand Up @@ -300,10 +300,7 @@ export async function createOptimizeDepsRun(
// server is running
deps = depsFromOptimizedDepInfo(newDeps)

// Clone optimized info objects, fileHash, browserHash may be changed for them
for (const o of Object.keys(newDeps)) {
metadata.optimized[o] = { ...newDeps[o] }
}
metadata.optimized = newDeps

// update global browser hash, but keep newDeps individual hashs until we know
// if files are stable so we can avoid a full page reload
Expand Down Expand Up @@ -738,3 +735,39 @@ function getDepHash(root: string, config: ResolvedConfig): string {
)
return createHash('sha256').update(content).digest('hex').substring(0, 8)
}

export function optimizeDepInfoFromFile(
metadata: DepOptimizationMetadata,
file: string
): OptimizedDepInfo | undefined {
return (
findFileInfo(metadata.optimized, file) ||
findFileInfo(metadata.discovered, file)
)
}

function findFileInfo(
dependenciesInfo: Record<string, OptimizedDepInfo>,
file: string
): OptimizedDepInfo | undefined {
for (const o of Object.keys(dependenciesInfo)) {
const info = dependenciesInfo[o]
if (info.file === file) {
return info
}
}
}

export async function optimizedDepNeedsInterop(
metadata: DepOptimizationMetadata,
file: string
): Promise<boolean | undefined> {
const depInfo = optimizeDepInfoFromFile(metadata, file)

if (!depInfo) return undefined

// Wait until the dependency has been pre-bundled
await depInfo.processing

return depInfo?.needsInterop
}
12 changes: 9 additions & 3 deletions packages/vite/src/node/optimizer/registerMissing.ts
Expand Up @@ -79,7 +79,14 @@ export function createMissingImporterRegisterFn(

// All deps, previous known and newly discovered are rebundled,
// respect insertion order to keep the metadata file stable
const newDeps = { ...metadata.optimized, ...metadata.discovered }

// Clone optimized info objects, fileHash, browserHash may be changed for them
const clonedOptimizedDeps: Record<string, OptimizedDepInfo> = {}
for (const o of Object.keys(metadata.optimized)) {
clonedOptimizedDeps[o] = { ...metadata.optimized[o] }
}

const newDeps = { ...clonedOptimizedDeps, ...metadata.discovered }
const thisDepOptimizationProcessing = depOptimizationProcessing

// Other rerun will await until this run is finished
Expand Down Expand Up @@ -119,9 +126,8 @@ export function createMissingImporterRegisterFn(
// While optimizeDeps is running, new missing deps may be discovered,
// in which case they will keep being added to metadata.discovered
for (const o of Object.keys(metadata.discovered)) {
if (!newData.optimized[o] && !newData.discovered[o]) {
if (!newData.optimized[o]) {
newData.discovered[o] = metadata.discovered[o]
delete metadata.discovered[o]
}
}
newData.processing = thisDepOptimizationProcessing.promise
Expand Down
33 changes: 20 additions & 13 deletions packages/vite/src/node/plugins/importAnalysis.ts
Expand Up @@ -49,7 +49,8 @@ import { transformRequest } from '../server/transformRequest'
import {
isOptimizedDepFile,
createIsOptimizedDepUrl,
getDepsCacheDir
getDepsCacheDir,
optimizedDepNeedsInterop
} from '../optimizer'

const isDebug = !!process.env.DEBUG
Expand Down Expand Up @@ -433,24 +434,30 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
// rewrite
if (url !== specifier) {
let rewriteDone = false
if (isOptimizedDepFile(resolvedId, config)) {
// for optimized cjs deps, support named imports by rewriting named
// imports to const assignments.
const optimizeDepsMetadata = server._optimizeDepsMetadata!
const { optimized } = optimizeDepsMetadata
if (
isOptimizedDepFile(resolvedId, config) &&
!resolvedId.match(optimizedDepChunkRE)
) {
// for optimized cjs deps, support named imports by rewriting named imports to const assignments.
// internal optimized chunks don't need es interop and are excluded

// The browserHash in resolvedId could be stale in which case there will be a full
// page reload. We could return a 404 in that case but it is safe to return the request
const file = cleanUrl(resolvedId) // Remove ?v={hash}
const dep = Object.keys(optimized).find(
(k) => optimized[k].file === file
)

// Wait until the dependency has been pre-bundled
dep && (await optimized[dep].processing)
const needsInterop = await optimizedDepNeedsInterop(
server._optimizeDepsMetadata!,
file
)

if (dep && optimized[dep].needsInterop) {
debug(`${dep} needs interop`)
if (needsInterop === undefined) {
config.logger.error(
colors.red(
`Vite Error, ${url} optimized info should be defined`
)
)
} else if (needsInterop) {
debug(`${url} needs interop`)
if (isDynamicImport) {
// rewrite `import('package')` to expose the default directly
str().overwrite(
Expand Down
27 changes: 3 additions & 24 deletions packages/vite/src/node/plugins/optimizedDeps.ts
Expand Up @@ -3,8 +3,7 @@ import type { Plugin } from '../plugin'
import colors from 'picocolors'
import { DEP_VERSION_RE } from '../constants'
import { cleanUrl, createDebugger } from '../utils'
import { isOptimizedDepFile } from '../optimizer'
import type { DepOptimizationMetadata, OptimizedDepInfo } from '../optimizer'
import { isOptimizedDepFile, optimizeDepInfoFromFile } from '../optimizer'
import type { ViteDevServer } from '..'

export const ERR_OPTIMIZE_DEPS_PROCESSING_ERROR =
Expand Down Expand Up @@ -33,6 +32,8 @@ export function optimizedDepsPlugin(): Plugin {
const browserHash = versionMatch
? versionMatch[1].split('=')[1]
: undefined

// Search in both the currently optimized and newly discovered deps
const info = optimizeDepInfoFromFile(metadata, file)
if (info) {
if (browserHash && info.browserHash !== browserHash) {
Expand Down Expand Up @@ -93,25 +94,3 @@ function throwOutdatedRequest(id: string) {
// send a 504 status code request timeout
throw err
}

function optimizeDepInfoFromFile(
metadata: DepOptimizationMetadata,
file: string
): OptimizedDepInfo | undefined {
return (
findFileInfo(metadata.optimized, file) ||
findFileInfo(metadata.discovered, file)
)
}

function findFileInfo(
dependenciesInfo: Record<string, OptimizedDepInfo>,
file: string
): OptimizedDepInfo | undefined {
for (const o of Object.keys(dependenciesInfo)) {
const info = dependenciesInfo[o]
if (info.file === file) {
return info
}
}
}

0 comments on commit ba3047d

Please sign in to comment.