Skip to content

Commit 85e387a

Browse files
authored
fix: use browser field if likely esm (fixes #9652) (#9653)
1 parent c261fe6 commit 85e387a

File tree

8 files changed

+39
-10
lines changed

8 files changed

+39
-10
lines changed

packages/vite/src/node/plugins/resolve.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'node:path'
33
import colors from 'picocolors'
44
import type { PartialResolvedId } from 'rollup'
55
import { resolve as _resolveExports } from 'resolve.exports'
6+
import { hasESMSyntax } from 'mlly'
67
import type { Plugin } from '../plugin'
78
import {
89
DEFAULT_EXTENSIONS,
@@ -850,25 +851,22 @@ export function resolvePackageEntry(
850851
) {
851852
// if both are present, we may have a problem: some package points both
852853
// to ESM, with "module" targeting Node.js, while some packages points
853-
// "module" to browser ESM and "browser" to UMD.
854+
// "module" to browser ESM and "browser" to UMD/IIFE.
854855
// the heuristics here is to actually read the browser entry when
855-
// possible and check for hints of UMD. If it is UMD, prefer "module"
856+
// possible and check for hints of ESM. If it is not ESM, prefer "module"
856857
// instead; Otherwise, assume it's ESM and use it.
857858
const resolvedBrowserEntry = tryFsResolve(
858859
path.join(dir, browserEntry),
859860
options
860861
)
861862
if (resolvedBrowserEntry) {
862863
const content = fs.readFileSync(resolvedBrowserEntry, 'utf-8')
863-
if (
864-
(/typeof exports\s*==/.test(content) &&
865-
/typeof module\s*==/.test(content)) ||
866-
/module\.exports\s*=/.test(content)
867-
) {
868-
// likely UMD or CJS(!!! e.g. firebase 7.x), prefer module
869-
entryPoint = data.module
870-
} else {
864+
if (hasESMSyntax(content)) {
865+
// likely ESM, prefer browser
871866
entryPoint = browserEntry
867+
} else {
868+
// non-ESM, UMD or IIFE or CJS(!!! e.g. firebase 7.x), prefer module
869+
entryPoint = data.module
872870
}
873871
}
874872
} else {

playground/resolve/__tests__/resolve.spec.ts

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ test('Resolve module field if browser field is likely UMD or CJS', async () => {
9696
expect(await page.textContent('.browser-module2')).toMatch('[success]')
9797
})
9898

99+
test('Resolve module field if browser field is likely IIFE', async () => {
100+
expect(await page.textContent('.browser-module3')).toMatch('[success]')
101+
})
102+
99103
test('css entry', async () => {
100104
expect(await page.textContent('.css')).toMatch('[success]')
101105
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default '[success] this should run in browser'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var browserModuleField3 = (function () {
2+
'use strict'
3+
4+
var main = '[fail] this should not run in the browser'
5+
6+
return main
7+
})()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "resolve-browser-module-field3",
3+
"private": true,
4+
"version": "1.0.0",
5+
"module": "index.js",
6+
"browser": "index.web.js"
7+
}

playground/resolve/index.html

+6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ <h2>Resolve browser field even if module field exists</h2>
8282
<h2>Resolve module field if browser field is likely UMD or CJS</h2>
8383
<p class="browser-module2">fail</p>
8484

85+
<h2>Resolve module field if browser field is likely IIFE</h2>
86+
<p class="browser-module3">fail</p>
87+
8588
<h2>Don't resolve to the `module` field if the importer is a `require` call</h2>
8689
<p class="require-pkg-with-module-field">fail</p>
8790

@@ -225,6 +228,9 @@ <h2>resolve package that contains # in path</h2>
225228
import browserModule2 from 'resolve-browser-module-field2'
226229
text('.browser-module2', browserModule2)
227230

231+
import browserModule3 from 'resolve-browser-module-field3'
232+
text('.browser-module3', browserModule3)
233+
228234
import { msg as requireButWithModuleFieldMsg } from 'require-pkg-with-module-field'
229235
text('.require-pkg-with-module-field', requireButWithModuleFieldMsg)
230236

playground/resolve/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"resolve-browser-field": "link:./browser-field",
1717
"resolve-browser-module-field1": "link:./browser-module-field1",
1818
"resolve-browser-module-field2": "link:./browser-module-field2",
19+
"resolve-browser-module-field3": "link:./browser-module-field3",
1920
"resolve-custom-condition": "link:./custom-condition",
2021
"resolve-custom-main-field": "link:./custom-main-field",
2122
"resolve-exports-env": "link:./exports-env",

pnpm-lock.yaml

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)