diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 4c0d3ea09a5b8a..e8467022132981 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -250,11 +250,12 @@ export async function optimizeDeps( await init for (const output in meta.outputs) { + if (/chunk\.\w+\.js$/.test(output)) continue const absolute = normalizePath(path.resolve(output)) const relative = normalizePath(path.relative(cacheDir, absolute)) for (const id in qualified) { const entry = qualified[id] - if (entry.endsWith(relative)) { + if (entry.replace(/\.mjs$/, '.js').endsWith(relative)) { // check if this is a cjs dep. const [imports, exports] = parse(fs.readFileSync(entry, 'utf-8')) data.optimized[id] = { diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 6b9f036276111c..d4371d7eba697e 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -25,11 +25,10 @@ import { PartialResolvedId } from 'rollup' import { isCSSRequest } from './css' import { resolve as _resolveExports } from 'resolve.exports' -const mainFields = [ +const altMainFields = [ 'module', 'jsnext:main', // moment still uses this... - 'jsnext', - 'main' + 'jsnext' ] function resolveExports( @@ -455,7 +454,11 @@ export function resolvePackageEntry( entryPoint = resolveExports(data, '.', isProduction) } - if (!entryPoint) { + // if exports resolved to .mjs, still resolve other fields. + // This is because .mjs files can technically import .cjs files which would + // make them invalid for pure ESM environments - so if other module/browser + // fields are present, prioritize those instead. + if (!entryPoint || entryPoint.endsWith('.mjs')) { // check browser field // https://github.com/defunctzombie/package-browser-field-spec const browserEntry = @@ -492,8 +495,8 @@ export function resolvePackageEntry( } } - if (!entryPoint) { - for (const field of mainFields) { + if (!entryPoint || entryPoint.endsWith('.mjs')) { + for (const field of altMainFields) { if (typeof data[field] === 'string') { entryPoint = data[field] break @@ -501,7 +504,7 @@ export function resolvePackageEntry( } } - entryPoint = entryPoint || 'index.js' + entryPoint = entryPoint || data.main || 'index.js' // resolve object browser field in package.json const { browser: browserField } = data