fix(ssr): externalize network imports during ssrLoadModule (#15599)

This commit is contained in:
Hiroshi Ogawa 2024-01-16 01:50:47 +09:00 committed by GitHub
parent e6ebc7bad7
commit af2aa09575
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 4 deletions

View File

@ -9,3 +9,4 @@ playground/tsconfig-json-load-error/has-error/tsconfig.json
playground/html/invalid.html
playground/html/valid.html
playground/external/public/slash@3.0.0.js
playground/ssr-html/public/slash@3.0.0.js

View File

@ -2,7 +2,7 @@ import path from 'node:path'
import { pathToFileURL } from 'node:url'
import colors from 'picocolors'
import type { ViteDevServer } from '../server'
import { isBuiltin, isFilePathESM, unwrapId } from '../utils'
import { isBuiltin, isExternalUrl, isFilePathESM, unwrapId } from '../utils'
import { transformRequest } from '../server/transformRequest'
import type { InternalResolveOptionsWithOverrideConditions } from '../plugins/resolve'
import { tryNodeResolve } from '../plugins/resolve'
@ -292,7 +292,7 @@ async function nodeImport(
) {
let url: string
let filePath: string | undefined
if (id.startsWith('data:') || isBuiltin(id)) {
if (id.startsWith('data:') || isExternalUrl(id) || isBuiltin(id)) {
url = id
} else {
const resolved = tryNodeResolve(

View File

@ -1,6 +1,7 @@
import { execFile } from 'node:child_process'
import { promisify } from 'node:util'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import fetch from 'node-fetch'
import { describe, expect, test } from 'vitest'
import { port } from './serve'
@ -62,9 +63,9 @@ describe.runIf(isServe)('hmr', () => {
})
})
describe.runIf(isServe)('stacktrace', () => {
const execFileAsync = promisify(execFile)
const execFileAsync = promisify(execFile)
describe.runIf(isServe)('stacktrace', () => {
for (const ext of ['js', 'ts']) {
for (const sourcemapsEnabled of [false, true]) {
test(`stacktrace of ${ext} is correct when sourcemaps is${
@ -98,3 +99,13 @@ describe.runIf(isServe)('stacktrace', () => {
}
}
})
test.runIf(isServe)('network-imports', async () => {
await execFileAsync(
'node',
['--experimental-network-imports', 'test-network-imports.js'],
{
cwd: fileURLToPath(new URL('..', import.meta.url)),
},
)
})

View File

@ -0,0 +1,5 @@
/* eslint-disable */
// copied from https://esm.sh/v133/slash@3.0.0/es2022/slash.mjs to reduce network issues in CI
/* esm.sh - esbuild bundle(slash@3.0.0) es2022 production */
var a=Object.create;var d=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var A=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),E=(e,t)=>{for(var r in t)d(e,r,{get:t[r],enumerable:!0})},u=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of x(t))!p.call(e,n)&&n!==r&&d(e,n,{get:()=>t[n],enumerable:!(i=m(t,n))||i.enumerable});return e},o=(e,t,r)=>(u(e,t,"default"),r&&u(r,t,"default")),c=(e,t,r)=>(r=e!=null?a(g(e)):{},u(t||!e||!e.__esModule?d(r,"default",{value:e,enumerable:!0}):r,e));var f=A((h,_)=>{"use strict";_.exports=e=>{let t=/^\\\\\?\\/.test(e),r=/[^\u0000-\u0080]+/.test(e);return t||r?e:e.replace(/\\/g,"/")}});var s={};E(s,{default:()=>P});var L=c(f());o(s,c(f()));var{default:l,...N}=L,P=l!==void 0?l:N;export{P as default};

View File

@ -0,0 +1,7 @@
// same port as `ports["ssr-html"]` in playground/test-utils.ts
import slash from 'http://localhost:9602/slash@3.0.0.js'
// or test without local server
// import slash from 'https://esm.sh/slash@3.0.0'
export { slash }

View File

@ -0,0 +1,18 @@
import assert from 'node:assert'
import { fileURLToPath } from 'node:url'
import { createServer } from 'vite'
async function runTest() {
const server = await createServer({
configFile: false,
root: fileURLToPath(new URL('.', import.meta.url)),
server: {
middlewareMode: true,
},
})
const mod = await server.ssrLoadModule('/src/network-imports.js')
assert.equal(mod.slash('foo\\bar'), 'foo/bar')
await server.close()
}
runTest()