Skip to content

Commit 714c911

Browse files
authoredJan 31, 2024
fix(browser): don't exclude node builtins from optimization (#5082)
1 parent 2c5d192 commit 714c911

File tree

10 files changed

+189
-120
lines changed

10 files changed

+189
-120
lines changed
 

‎packages/browser/src/node/esmInjector.ts

+6-15
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
3838

3939
const hoistIndex = 0
4040

41-
let hasInjected = false
42-
4341
// this will transform import statements into dynamic ones, if there are imports
4442
// it will keep the import as is, if we don't need to mock anything
4543
// in browser environment it will wrap the module value with "vitest_wrap_module" function
@@ -76,7 +74,6 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
7674
}
7775

7876
function defineExport(position: number, name: string, local = name) {
79-
hasInjected = true
8077
s.appendLeft(
8178
position,
8279
`\nObject.defineProperty(${viInjectedKey}, "${name}", `
@@ -170,7 +167,6 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
170167
// named hoistable/class exports
171168
// export default function foo() {}
172169
// export default class A {}
173-
hasInjected = true
174170
const { name } = node.declaration.id
175171
s.remove(node.start, node.start + 15 /* 'export default '.length */)
176172
s.append(
@@ -180,7 +176,6 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
180176
}
181177
else {
182178
// anonymous default exports
183-
hasInjected = true
184179
s.update(
185180
node.start,
186181
node.start + 14 /* 'export default'.length */,
@@ -196,13 +191,10 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
196191
s.remove(node.start, node.end)
197192
const importId = defineImportAll(node.source.value as string)
198193
// hoist re-exports near the defined import so they are immediately exported
199-
if (node.exported) {
194+
if (node.exported)
200195
defineExport(hoistIndex, node.exported.name, `${importId}`)
201-
}
202-
else {
203-
hasInjected = true
196+
else
204197
s.appendLeft(hoistIndex, `${viExportAllHelper}(${viInjectedKey}, ${importId});\n`)
205-
}
206198
}
207199
}
208200

@@ -244,11 +236,10 @@ export function injectVitestModule(code: string, id: string, parse: PluginContex
244236
},
245237
})
246238

247-
if (hasInjected) {
248-
// make sure "__vi_injected__" is declared as soon as possible
249-
s.prepend(`const ${viInjectedKey} = { [Symbol.toStringTag]: "Module" };\n`)
250-
s.append(`\nexport { ${viInjectedKey} }`)
251-
}
239+
// make sure "__vi_injected__" is declared as soon as possible
240+
// prepend even if file doesn't export anything
241+
s.prepend(`const ${viInjectedKey} = { [Symbol.toStringTag]: "Module" };\n`)
242+
s.append(`\nexport { ${viInjectedKey} }`)
252243

253244
return {
254245
ast,

‎packages/browser/src/node/index.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { fileURLToPath } from 'node:url'
22

33
import { resolve } from 'node:path'
4-
import { builtinModules } from 'node:module'
54
import sirv from 'sirv'
65
import type { Plugin } from 'vite'
76
import type { WorkspaceProject } from 'vitest/node'
@@ -61,18 +60,19 @@ export default (project: WorkspaceProject, base = '/'): Plugin[] => {
6160
'vitest/runners',
6261
],
6362
exclude: [
64-
...builtinModules,
6563
'vitest',
6664
'vitest/utils',
6765
'vitest/browser',
6866
'vitest/runners',
6967
'@vitest/utils',
68+
69+
// loupe is manually transformed
70+
'loupe',
7071
],
7172
include: [
7273
'vitest > @vitest/utils > pretty-format',
7374
'vitest > @vitest/snapshot > pretty-format',
7475
'vitest > diff-sequences',
75-
'vitest > loupe',
7676
'vitest > pretty-format',
7777
'vitest > pretty-format > ansi-styles',
7878
'vitest > pretty-format > ansi-regex',
@@ -81,6 +81,13 @@ export default (project: WorkspaceProject, base = '/'): Plugin[] => {
8181
},
8282
}
8383
},
84+
transform(code, id) {
85+
if (id.includes('loupe/loupe.js')) {
86+
const exportsList = ['custom', 'inspect', 'registerConstructor', 'registerStringTag']
87+
const codeAppend = exportsList.map(i => `export const ${i} = globalThis.loupe.${i}`).join('\n')
88+
return `${code}\n${codeAppend}\nexport default globalThis.loupe`
89+
}
90+
},
8491
async resolveId(id) {
8592
if (!/\?browserv=\w+$/.test(id))
8693
return

‎packages/utils/src/display.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// since this is already part of Vitest via Chai, we can just reuse it without increasing the size of bundle
22
// @ts-expect-error doesn't have types
3-
import { inspect as loupe } from 'loupe'
3+
import * as loupe from 'loupe'
44

55
interface LoupeOptions {
66
showHidden?: boolean | undefined
@@ -101,7 +101,7 @@ export function format(...args: unknown[]) {
101101
export function inspect(obj: unknown, options: LoupeOptions = {}): string {
102102
if (options.truncate === 0)
103103
options.truncate = Number.POSITIVE_INFINITY
104-
return loupe(obj, options)
104+
return loupe.inspect(obj, options)
105105
}
106106

107107
export function objDisplay(obj: unknown, options: LoupeOptions = {}): string {

‎pnpm-lock.yaml

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

‎test/browser/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@vitest/cjs-lib": "link:./cjs-lib",
1717
"execa": "^7.1.1",
1818
"safaridriver": "^0.0.4",
19+
"url": "^0.11.3",
1920
"vitest": "workspace:*"
2021
}
2122
}

‎test/browser/specs/run-vitest.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default async function runVitest(moreArgs = []) {
2020
const browserResult = await readFile('./browser.json', 'utf-8')
2121
const browserResultJson = JSON.parse(browserResult)
2222

23-
const getPassed = results => results.filter(result => result.status === 'passed')
23+
const getPassed = results => results.filter(result => result.status === 'passed' && !result.mesage)
2424
const getFailed = results => results.filter(result => result.status === 'failed')
2525

2626
const passedTests = getPassed(browserResultJson.testResults)

‎test/browser/specs/runner.test.mjs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ const {
1111
} = await runVitest()
1212

1313
await test('tests are actually running', async () => {
14-
assert.ok(browserResultJson.testResults.length === 12, 'Not all the tests have been run')
15-
assert.ok(passedTests.length === 10, 'Some tests failed')
16-
assert.ok(failedTests.length === 2, 'Some tests have passed but should fail')
14+
assert.equal(browserResultJson.testResults.length, 14, 'Not all the tests have been run')
15+
assert.equal(passedTests.length, 12, 'Some tests failed')
16+
assert.equal(failedTests.length, 2, 'Some tests have passed but should fail')
1717

18+
assert.doesNotMatch(stderr, /has been externalized for browser compatibility/, 'doesn\'t have any externalized modules')
1819
assert.doesNotMatch(stderr, /Unhandled Error/, 'doesn\'t have any unhandled errors')
1920
})
2021

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// eslint-disable-next-line unicorn/prefer-node-protocol
2+
import * as url from 'url'
3+
import { expect, test } from 'vitest'
4+
5+
test('url is polifylled because it\'s installed in dependencies', () => {
6+
expect(url.format).toBeDefined()
7+
})

‎test/browser/test/utils.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { inspect } from 'vitest/utils'
2+
import { expect, it } from 'vitest'
3+
4+
it('utils package correctly uses loupe', async () => {
5+
expect(inspect({ test: 1 })).toBe('{ test: 1 }')
6+
})

‎test/core/test/injector-esm.test.ts

+113-55
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.