Skip to content

Commit

Permalink
fix(optimizer): browser field bare import (fix #7599) (#10314)
Browse files Browse the repository at this point in the history
Co-authored-by: sapphi-red <green@sapphi.red>
  • Loading branch information
smeng9 and sapphi-red committed Oct 5, 2022
1 parent 65dd88b commit cba13e8
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 1 deletion.
40 changes: 39 additions & 1 deletion packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -1106,7 +1106,8 @@ function tryResolveBrowserMapping(
externalize?: boolean
) {
let res: string | undefined
const pkg = importer && idToPkgMap.get(importer)
const pkg =
importer && (idToPkgMap.get(importer) || resolvePkg(importer, options))
if (pkg && isObject(pkg.data.browser)) {
const mapId = isFilePath ? './' + slash(path.relative(pkg.dir, id)) : id
const browserMappedPath = mapWithBrowserField(mapId, pkg.data.browser)
Expand Down Expand Up @@ -1165,3 +1166,40 @@ function getRealPath(resolved: string, preserveSymlinks?: boolean): string {
}
return normalizePath(resolved)
}

/**
* if importer was not resolved by vite's resolver previously
* (when esbuild resolved it)
* resolve importer's pkg and add to idToPkgMap
*/
function resolvePkg(importer: string, options: InternalResolveOptions) {
const { root, preserveSymlinks, packageCache } = options

if (importer.includes('\x00')) {
return null
}

const possiblePkgIds: string[] = []
for (let prevSlashIndex = -1; ; ) {
const slashIndex = importer.indexOf(isWindows ? '\\' : '/', prevSlashIndex)
if (slashIndex < 0) {
break
}

prevSlashIndex = slashIndex + 1

const possiblePkgId = importer.slice(0, slashIndex)
possiblePkgIds.push(possiblePkgId)
}

let pkg: PackageData | undefined
possiblePkgIds.reverse().find((pkgId) => {
pkg = resolvePackageData(pkgId, root, preserveSymlinks, packageCache)!
return pkg
})!

if (pkg) {
idToPkgMap.set(importer, pkg)
}
return pkg
}
4 changes: 4 additions & 0 deletions playground/optimize-deps/__tests__/optimize-deps.spec.ts
Expand Up @@ -58,6 +58,10 @@ test('cjs browser field (axios)', async () => {
expect(await page.textContent('.cjs-browser-field')).toBe('pong')
})

test('cjs browser field bare', async () => {
expect(await page.textContent('.cjs-browser-field-bare')).toBe('pong')
})

test('dep from linked dep (lodash-es)', async () => {
expect(await page.textContent('.deps-linked')).toBe('fooBarBaz')
})
Expand Down
@@ -0,0 +1,3 @@
module.exports = {
foo: 'foo'
}
5 changes: 5 additions & 0 deletions playground/optimize-deps/dep-cjs-browser-field-bare/index.js
@@ -0,0 +1,5 @@
'use strict'

const internal = require('./internal')

module.exports = internal
@@ -0,0 +1,6 @@
'use strict'

// eslint-disable-next-line import/no-nodejs-modules
const events = require('events')

module.exports = 'foo' in events ? 'pong' : ''
@@ -0,0 +1,9 @@
{
"name": "dep-cjs-browser-field-bare",
"private": true,
"version": "0.0.0",
"main": "index.js",
"browser": {
"events": "./events-shim.js"
}
}
6 changes: 6 additions & 0 deletions playground/optimize-deps/index.html
Expand Up @@ -29,6 +29,9 @@ <h2>Dedupe (dep in linked & optimized package)</h2>
<h2>CommonJS w/ browser field mapping (axios)</h2>
<div>This should show pong: <span class="cjs-browser-field"></span></div>

<h2>CommonJS w/ bare id browser field mapping</h2>
<div>This should show pong: <span class="cjs-browser-field-bare"></span></div>

<h2>Detecting linked src package and optimizing its deps (lodash-es)</h2>
<div>This should show fooBarBaz: <span class="deps-linked"></span></div>

Expand Down Expand Up @@ -100,6 +103,9 @@ <h2>Non Optimized Module isn't duplicated</h2>
// test dep detection in globbed files
const globbed = import.meta.glob('./glob/*.js', { eager: true })

import cjsBrowerFieldBare from 'dep-cjs-browser-field-bare'
text('.cjs-browser-field-bare', cjsBrowerFieldBare)

import { camelCase } from 'dep-linked'
text('.deps-linked', camelCase('foo-bar-baz'))

Expand Down
1 change: 1 addition & 0 deletions playground/optimize-deps/package.json
Expand Up @@ -11,6 +11,7 @@
"dependencies": {
"axios": "^0.27.2",
"clipboard": "^2.0.11",
"dep-cjs-browser-field-bare": "file:./dep-cjs-browser-field-bare",
"dep-cjs-compiled-from-cjs": "file:./dep-cjs-compiled-from-cjs",
"dep-cjs-compiled-from-esm": "file:./dep-cjs-compiled-from-esm",
"dep-cjs-with-assets": "file:./dep-cjs-with-assets",
Expand Down
11 changes: 11 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit cba13e8

Please sign in to comment.