Skip to content

Commit

Permalink
feat: add polyfill of URL.canParse for browser compatibility (#70228)
Browse files Browse the repository at this point in the history
### Why?

Since `URL.canParse` is incompatible with older browsers like Safari 16,
we added `canParseUrl` util at
#70215.
x-ref: https://caniuse.com/?search=URL.canParse

To improve maintenance, we decided to add polyfill for `URL.canParse`.
x-ref: [slack
thread](https://vercel.slack.com/archives/C07BVA6HM17/p1726664071636899?thread_ts=1726620161.450109&cid=C07BVA6HM17)

Closes NDX-302

---------

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
  • Loading branch information
devjiwonchoi and huozhi authored Sep 18, 2024
1 parent f3e3bcb commit 5b0b68a
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 28 deletions.
20 changes: 20 additions & 0 deletions packages/next-polyfill-module/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,23 @@ if (!Object.hasOwn) {
return Object.prototype.hasOwnProperty.call(Object(object), property)
}
}

/**
* Available in:
* Edge: 120
* Firefox: 115
* Chrome: 120
* Safari: 17.0
*
* https://caniuse.com/mdn-api_url_canparse_static
*/
// Modified from https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.can-parse.js
if (!('canParse' in URL)) {
URL.canParse = function (url, base) {
try {
return !!new URL(url, base)
} catch {
return false
}
}
}
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"prepublishOnly": "cd ../../ && turbo run build"
},
"devDependencies": {
"core-js": "3.6.5",
"core-js": "3.38.1",
"microbundle": "0.15.0",
"object-assign": "4.1.1",
"whatwg-fetch": "3.0.0"
Expand Down
1 change: 1 addition & 0 deletions packages/next-polyfill-nomodule/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import 'core-js/features/string/trim-left'
import 'core-js/features/string/trim-right'
import 'core-js/features/url'
import 'core-js/features/url/to-json'
import 'core-js/features/url/can-parse'
import 'core-js/features/url-search-params'
import 'core-js/features/weak-map'
import 'core-js/features/weak-set'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { canParseUrl } from '../../../../../lib/url'
import { normalizedAssetPrefix } from '../../../../../shared/lib/normalized-asset-prefix'

function getSocketProtocol(assetPrefix: string): string {
Expand All @@ -16,7 +15,7 @@ export function getSocketUrl(assetPrefix: string | undefined): string {
const prefix = normalizedAssetPrefix(assetPrefix)
const protocol = getSocketProtocol(assetPrefix || '')

if (canParseUrl(prefix)) {
if (URL.canParse(prefix)) {
// since normalized asset prefix is ensured to be a URL format,
// we can safely replace the protocol
return prefix.replace(/^http/, 'ws')
Expand Down
12 changes: 0 additions & 12 deletions packages/next/src/lib/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,3 @@ export function stripNextRscUnionQuery(relativeUrl: string): string {

return urlInstance.pathname + urlInstance.search
}

export function canParseUrl(url: string): boolean {
if (typeof URL.canParse === 'function') {
return URL.canParse(url)
}
try {
new URL(url)
return true
} catch {}

return false
}
3 changes: 1 addition & 2 deletions packages/next/src/server/lib/router-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import {
} from '../dev/hot-reloader-types'
import { normalizedAssetPrefix } from '../../shared/lib/normalized-asset-prefix'
import { NEXT_PATCH_SYMBOL } from './patch-fetch'
import { canParseUrl } from '../../lib/url'

const debug = setupDebug('next:router-server:main')
const isNextFont = (pathname: string | null) =>
Expand Down Expand Up @@ -677,7 +676,7 @@ export async function initialize(opts: {
if (assetPrefix) {
hmrPrefix = normalizedAssetPrefix(assetPrefix)

if (canParseUrl(hmrPrefix)) {
if (URL.canParse(hmrPrefix)) {
// remove trailing slash from pathname
// return empty string if pathname is '/'
// to avoid conflicts with '/_next' below
Expand Down
4 changes: 1 addition & 3 deletions packages/next/src/shared/lib/normalized-asset-prefix.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { canParseUrl } from '../../lib/url'

export function normalizedAssetPrefix(assetPrefix: string | undefined): string {
// remove all leading slashes and trailing slashes
const escapedAssetPrefix = assetPrefix?.replace(/^\/+|\/+$/g, '') || false
Expand All @@ -10,7 +8,7 @@ export function normalizedAssetPrefix(assetPrefix: string | undefined): string {
return ''
}

if (canParseUrl(escapedAssetPrefix)) {
if (URL.canParse(escapedAssetPrefix)) {
const url = new URL(escapedAssetPrefix).toString()
return url.endsWith('/') ? url.slice(0, -1) : url
}
Expand Down
21 changes: 13 additions & 8 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 5b0b68a

Please sign in to comment.