Skip to content

Commit

Permalink
fix(vitest): support network imports in vm pools
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Jan 18, 2024
1 parent 6421c27 commit d74c6cc
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"test:run": "vitest run -r test/core",
"test:all": "CI=true pnpm -r --stream run test --allowOnly",
"test:ci": "CI=true pnpm -r --stream --filter !test-browser --filter !test-esm --filter !test-browser run test --allowOnly",
"test:ci:vm-threads": "CI=true pnpm -r --stream --filter !test-coverage --filter !test-single-thread --filter !test-browser --filter !test-esm --filter !test-network-imports --filter !test-browser --filter !example-react-testing-lib-msw run test --allowOnly --pool vmThreads",
"test:ci:vm-threads": "CI=true pnpm -r --stream --filter !test-coverage --filter !test-single-thread --filter !test-browser --filter !test-esm --filter !test-browser --filter !example-react-testing-lib-msw run test --allowOnly --pool vmThreads",
"test:ci:no-threads": "CI=true pnpm -r --stream --filter !test-vm-threads --filter !test-coverage --filter !test-watch --filter !test-bail --filter !test-esm --filter !test-browser run test --allowOnly --pool forks",
"typecheck": "tsc -p tsconfig.check.json --noEmit",
"typecheck:why": "tsc -p tsconfig.check.json --noEmit --explainFiles > explainTypes.txt",
Expand Down
7 changes: 6 additions & 1 deletion packages/vitest/src/runtime/external-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface ExternalModulesExecutorOptions {
}

interface ModuleInformation {
type: 'data' | 'builtin' | 'vite' | 'module' | 'commonjs'
type: 'data' | 'network' | 'builtin' | 'vite' | 'module' | 'commonjs'
url: string
path: string
}
Expand Down Expand Up @@ -153,6 +153,9 @@ export class ExternalModulesExecutor {
if (identifier.startsWith('data:'))
return { type: 'data', url: identifier, path: identifier }

if (/^(https?:)?\/\//.test(identifier))
return { type: 'network', url: identifier, path: identifier }

const extension = extname(identifier)
if (extension === '.node' || isNodeBuiltin(identifier))
return { type: 'builtin', url: identifier, path: identifier }
Expand Down Expand Up @@ -185,6 +188,8 @@ export class ExternalModulesExecutor {
switch (type) {
case 'data':
return this.esm.createDataModule(identifier)
case 'network':
return this.esm.createNetworkModule(identifier)
case 'builtin': {
const exports = this.require(identifier)
return this.wrapCoreSynteticModule(identifier, exports)
Expand Down
18 changes: 18 additions & 0 deletions packages/vitest/src/runtime/vm/esm-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,22 @@ export class EsmExecutor {

return this.createEsModule(identifier, code)
}

// https://nodejs.org/api/esm.html#https-and-http-imports
// TODO: find reference implementation (node? deno?)
// TODO: default disabled to align with node?
// TODO: mime-type (json, wasm)? share code with `createDataModule` above?
// TODO: dynamic import?
public async createNetworkModule(identifier: string): Promise<VMModule> {
const cached = this.moduleCache.get(identifier)
if (cached)
return cached

const res = await fetch(identifier)
if (!res.ok)
throw new Error(`Fetch failed on network import: '${identifier}'`)

const code = await res.text()
return this.createEsModule(identifier, code)
}
}
3 changes: 3 additions & 0 deletions test/network-imports/test/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { expect, test } from 'vitest'
import slash from 'http://localhost:9602/[email protected]'

// test without local server
// - with internal imports with a relative path '/v135/[email protected]/es2022/slash.mjs'
// import slash from 'https://esm.sh/[email protected]'
// - single file
// import slash from 'https://esm.sh/v135/[email protected]/es2022/slash.mjs'

test('network imports', () => {
expect(slash('foo\\bar')).toBe('foo/bar')
Expand Down
8 changes: 0 additions & 8 deletions test/network-imports/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ export default defineConfig({
forks: {
execArgv: ['--experimental-network-imports'],
},
// not supported?
// FAIL test/basic.test.ts [ test/basic.test.ts ]
// Error: ENOENT: no such file or directory, open 'http://localhost:9602/[email protected]'
// ❯ Object.openSync node:fs:596:3
// ❯ readFileSync node:fs:464:35
vmThreads: {
execArgv: ['--experimental-network-imports'],
},
},
// let vite serve public/[email protected]
api: 9602,
Expand Down

0 comments on commit d74c6cc

Please sign in to comment.