diff --git a/package.json b/package.json index 7d47662a2525c1..9fcde84dc9704c 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "prompts": "^2.4.1", "rimraf": "^3.0.2", "semver": "^7.3.5", - "sirv": "^1.0.14", + "sirv": "^1.0.17", "ts-jest": "^27.0.4", "ts-node": "^10.1.0", "typescript": "^4.3.5", diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index 083148c59aff89..3e361e6e33acc4 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -183,6 +183,19 @@ test('?url import', async () => { ) }) +describe('unicode url', () => { + test('from js import', async () => { + const src = readFile('テスト-測試-white space.js') + expect(await page.textContent('.unicode-url')).toMatch( + isBuild + ? `data:application/javascript;base64,${Buffer.from(src).toString( + 'base64' + )}` + : `/foo/テスト-測試-white space.js` + ) + }) +}) + test('new URL(..., import.meta.url)', async () => { expect(await page.textContent('.import-meta-url')).toMatch(assetMatch) }) diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index 8668fa03b4f483..9755cf40470e03 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -1,5 +1,9 @@ + + + + @@ -14,9 +18,6 @@

Raw References from publicDir

  • Raw CSS from publicDir should load (this should be red)
  • -
  • - -
  • Asset Imports from JS

    @@ -70,6 +71,12 @@

    CSS url references

    CSS background (aliased) +

    Unicode URL

    +
    + + +
    +

    Image Src Set

    new URL(`./${dynamic}`, import.meta.url) import fooUrl from './foo.js?url' text('.url', fooUrl) + import unicodeUrl from './テスト-測試-white space.js?url' + text('.unicode-url', unicodeUrl) + const metaUrl = new URL('./nested/asset.png', import.meta.url) text('.import-meta-url', metaUrl) document.querySelector('.import-meta-url-img').src = metaUrl diff --git a/packages/playground/assets/static/white space.png "b/packages/playground/assets/nested/\343\203\206\343\202\271\343\203\210-\346\270\254\350\251\246-white space.png" similarity index 100% rename from packages/playground/assets/static/white space.png rename to "packages/playground/assets/nested/\343\203\206\343\202\271\343\203\210-\346\270\254\350\251\246-white space.png" diff --git "a/packages/playground/assets/\343\203\206\343\202\271\343\203\210-\346\270\254\350\251\246-white space.js" "b/packages/playground/assets/\343\203\206\343\202\271\343\203\210-\346\270\254\350\251\246-white space.js" new file mode 100644 index 00000000000000..506a726f7f3d63 --- /dev/null +++ "b/packages/playground/assets/\343\203\206\343\202\271\343\203\210-\346\270\254\350\251\246-white space.js" @@ -0,0 +1 @@ +console.log('test unicode') diff --git a/packages/vite/package.json b/packages/vite/package.json index 6e82ac3a70c110..8cd2fd2538ed0f 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -113,7 +113,7 @@ "resolve.exports": "^1.0.2", "rollup-plugin-license": "^2.5.0", "selfsigned": "^1.10.11", - "sirv": "^1.0.14", + "sirv": "^1.0.17", "source-map": "^0.6.1", "source-map-support": "^0.5.19", "strip-ansi": "^6.0.0", diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index d630fa815821d1..8bff43a1f1ab69 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -8,6 +8,7 @@ import { ensureLeadingSlash, fsPathFromId, isImportRequest, + isInternalRequest, isWindows, slash } from '../../utils' @@ -34,8 +35,8 @@ export function servePublicMiddleware(dir: string): Connect.NextHandleFunction { // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` return function viteServePublicMiddleware(req, res, next) { - // skip import request - if (isImportRequest(req.url!)) { + // skip import request and internal requests `/@fs/ /@vite-client` etc... + if (isImportRequest(req.url!) || isInternalRequest(req.url!)) { return next() } serve(req, res, next) @@ -50,15 +51,19 @@ export function serveStaticMiddleware( // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` return function viteServeStaticMiddleware(req, res, next) { - const url = req.url! - // only serve the file if it's not an html request // so that html requests can fallthrough to our html middleware for // special processing - if (path.extname(cleanUrl(url)) === '.html') { + // also skip internal requests `/@fs/ /@vite-client` etc... + if ( + path.extname(cleanUrl(req.url!)) === '.html' || + isInternalRequest(req.url!) + ) { return next() } + const url = decodeURI(req.url!) + // apply aliases to static requests as well let redirected: string | undefined for (const { find, replacement } of config.resolve.alias) { diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index 204c9c8c360c4a..26fb1a0a6793cd 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -93,7 +93,7 @@ export function transformMiddleware( return } - let url = removeTimestampQuery(req.url!).replace( + let url = decodeURI(removeTimestampQuery(req.url!)).replace( NULL_BYTE_PLACEHOLDER, '\0' ) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 56baeedb884f8a..3e350e5051c221 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -4,7 +4,13 @@ import fs from 'fs' import os from 'os' import path from 'path' import { pathToFileURL, URL } from 'url' -import { FS_PREFIX, DEFAULT_EXTENSIONS, VALID_ID_PREFIX } from './constants' +import { + FS_PREFIX, + DEFAULT_EXTENSIONS, + VALID_ID_PREFIX, + CLIENT_PUBLIC_PATH, + ENV_PUBLIC_PATH +} from './constants' import resolve from 'resolve' import builtins from 'builtin-modules' import { FSWatcher } from 'chokidar' @@ -122,8 +128,17 @@ export const isJSRequest = (url: string): boolean => { } const importQueryRE = /(\?|&)import=?(?:&|$)/ +const internalPrefixes = [ + FS_PREFIX, + VALID_ID_PREFIX, + CLIENT_PUBLIC_PATH, + ENV_PUBLIC_PATH +] +const InternalPrefixRE = new RegExp(`^(?:${internalPrefixes.join('|')})`) const trailingSeparatorRE = /[\?&]$/ export const isImportRequest = (url: string): boolean => importQueryRE.test(url) +export const isInternalRequest = (url: string): boolean => + InternalPrefixRE.test(url) export function removeImportQuery(url: string): string { return url.replace(importQueryRE, '$1').replace(trailingSeparatorRE, '') diff --git a/yarn.lock b/yarn.lock index 6d3f4de600ec5b..5e661a8f64859a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -877,6 +877,11 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.17.tgz#25fdbdfd282c2f86ddf3fcefbd98be99cd2627e2" integrity sha512-0p1rCgM3LLbAdwBnc7gqgnvjHg9KpbhcSphergHShlkWz8EdPawoMJ3/VbezI0mGC5eKCDzMaPgF9Yca6cKvrg== +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.20" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.20.tgz#111b5db0f501aa89b05076fa31f0ea0e0c292cd3" + integrity sha512-88p7+M0QGxKpmnkfXjS4V26AnoC/eiqZutE8GLdaI5X12NY75bXSdTY9NkmYb2Xyk1O+MmkuO6Frmsj84V6I8Q== + "@rollup/plugin-alias@^3.1.5": version "3.1.5" resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-3.1.5.tgz#73356a3a1eab2e1e2fd952f9f53cd89fc740d952" @@ -6972,7 +6977,7 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -sirv@^1.0.12, sirv@^1.0.14: +sirv@^1.0.12: version "1.0.14" resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.14.tgz#b826343f573e12653c5b3c3080a3a2a6a06595cd" integrity sha512-czTFDFjK9lXj0u9mJ3OmJoXFztoilYS+NdRPcJoT182w44wSEkHSiO7A2517GLJ8wKM4GjCm2OXE66Dhngbzjg== @@ -6981,6 +6986,15 @@ sirv@^1.0.12, sirv@^1.0.14: mime "^2.3.1" totalist "^1.0.0" +sirv@^1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.17.tgz#86e2c63c612da5a1dace1c16c46f524aaa26ac45" + integrity sha512-qx9go5yraB7ekT7bCMqUHJ5jEaOC/GXBxUWv+jeWnb7WzHUFdcQPGWk7YmAwFBaQBrogpuSqd/azbC2lZRqqmw== + dependencies: + "@polka/url" "^1.0.0-next.20" + mime "^2.3.1" + totalist "^1.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"