未验证 提交 a529e673 编写于 作者: J JJ Kasper 提交者: GitHub

Ensure preload works correctly with locale option (#18511)

* Ensure preload works correctly with locale option

* Fix conditional import

* Update size-limit tests

* DCE some code

* Resolve merge error
Co-authored-by: NTim Neutkens <timneutkens@me.com>
上级 ee6b7cab
......@@ -275,6 +275,7 @@ function Link(props: React.PropsWithChildren<LinkProps>) {
}, [pathname, props.href, props.as])
let { children, replace, shallow, scroll, locale } = props
// Deprecated. Warning shown by propType check. If the children provided is a string (<Link>example</Link>) we wrap it in an <a> tag
if (typeof children === 'string') {
children = <a>{children}</a>
......@@ -298,7 +299,12 @@ function Link(props: React.PropsWithChildren<LinkProps>) {
const isPrefetched = prefetched[href + '%' + as]
if (!isPrefetched) {
cleanup.current = listenToIntersections(el, () => {
prefetch(router, href, as)
prefetch(router, href, as, {
locale:
typeof locale !== 'undefined'
? locale
: router && router.locale,
})
})
}
}
......@@ -310,7 +316,7 @@ function Link(props: React.PropsWithChildren<LinkProps>) {
}
}
},
[p, childRef, href, as, router]
[p, childRef, href, as, router, locale]
)
const childProps: {
......
......@@ -203,7 +203,12 @@ export default class PageLoader {
* @param {string} href the route href (file-system path)
* @param {string} asPath the URL as shown in browser (virtual path); used for dynamic routes
*/
getDataHref(href: string, asPath: string, ssg: boolean, locale?: string) {
getDataHref(
href: string,
asPath: string,
ssg: boolean,
locale?: string | false
) {
const { pathname: hrefPathname, query, search } = parseRelativeUrl(href)
const { pathname: asPathname } = parseRelativeUrl(asPath)
const route = normalizeRoute(hrefPathname)
......@@ -229,7 +234,7 @@ export default class PageLoader {
* @param {string} href the route href (file-system path)
* @param {string} asPath the URL as shown in browser (virtual path); used for dynamic routes
*/
prefetchData(href: string, asPath: string, locale?: string) {
prefetchData(href: string, asPath: string, locale?: string | false) {
const { pathname: hrefPathname } = parseRelativeUrl(href)
const route = normalizeRoute(hrefPathname)
return this.promisedSsgManifest!.then(
......
......@@ -269,6 +269,7 @@ export type NextRouter = BaseRouter &
export type PrefetchOptions = {
priority?: boolean
locale?: string | false
}
export type PrivateRouteInfo = {
......@@ -1171,6 +1172,26 @@ export default class Router implements BaseRouter {
let { pathname } = parsed
if (process.env.__NEXT_I18N_SUPPORT) {
const normalizeLocalePath = require('../i18n/normalize-locale-path')
.normalizeLocalePath as typeof import('../i18n/normalize-locale-path').normalizeLocalePath
if (options.locale === false) {
pathname = normalizeLocalePath!(pathname, this.locales).pathname
parsed.pathname = pathname
url = formatWithValidation(parsed)
let parsedAs = parseRelativeUrl(asPath)
const localePathResult = normalizeLocalePath!(
parsedAs.pathname,
this.locales
)
parsedAs.pathname = localePathResult.pathname
options.locale = localePathResult.detectedLocale || options.locale
asPath = formatWithValidation(parsedAs)
}
}
const pages = await this.pageLoader.getPageList()
parsed = this._resolveHref(parsed, pages) as typeof parsed
......@@ -1190,7 +1211,7 @@ export default class Router implements BaseRouter {
this.pageLoader.prefetchData(
url,
asPath,
this.locale,
typeof options.locale !== 'undefined' ? options.locale : this.locale,
this.defaultLocale
),
this.pageLoader[options.priority ? 'loadPage' : 'prefetch'](route),
......
......@@ -95,16 +95,16 @@ describe('Build Output', () => {
expect(indexSize.endsWith('B')).toBe(true)
// should be no bigger than 60.8 kb
expect(parseFloat(indexFirstLoad) - 61.2).toBeLessThanOrEqual(0)
expect(parseFloat(indexFirstLoad) - 61.3).toBeLessThanOrEqual(0)
expect(indexFirstLoad.endsWith('kB')).toBe(true)
expect(parseFloat(err404Size) - 3.5).toBeLessThanOrEqual(0)
expect(err404Size.endsWith('kB')).toBe(true)
expect(parseFloat(err404FirstLoad) - 64.4).toBeLessThanOrEqual(0)
expect(parseFloat(err404FirstLoad) - 64.5).toBeLessThanOrEqual(0)
expect(err404FirstLoad.endsWith('kB')).toBe(true)
expect(parseFloat(sharedByAll) - 61).toBeLessThanOrEqual(0)
expect(parseFloat(sharedByAll) - 61.1).toBeLessThanOrEqual(0)
expect(sharedByAll.endsWith('kB')).toBe(true)
if (_appSize.endsWith('kB')) {
......
......@@ -255,6 +255,32 @@ function runTests(isDev) {
await addDefaultLocaleCookie(browser)
await browser.eval('window.beforeNav = 1')
if (!isDev) {
await browser.eval(`(function() {
document.querySelector('#to-gsp').scrollIntoView()
document.querySelector('#to-fallback-first').scrollIntoView()
document.querySelector('#to-no-fallback-first').scrollIntoView()
})()`)
for (const dataPath of [
'/fr/gsp.json',
'/fr/gsp/fallback/first.json',
'/fr/gsp/fallback/hello.json',
]) {
const found = await browser.eval(`(function() {
const links = [].slice.call(document.querySelectorAll('link'))
for (var i = 0; i < links.length; i++) {
if (links[i].href.indexOf("${dataPath}") > -1) {
return true
}
}
return false
})()`)
expect(found).toBe(true)
}
}
expect(await browser.elementByCss('#router-pathname').text()).toBe('/links')
expect(await browser.elementByCss('#router-as-path').text()).toBe(
'/links?nextLocale=fr'
......@@ -413,6 +439,32 @@ function runTests(isDev) {
await addDefaultLocaleCookie(browser)
await browser.eval('window.beforeNav = 1')
if (!isDev) {
await browser.eval(`(function() {
document.querySelector('#to-gsp').scrollIntoView()
document.querySelector('#to-fallback-first').scrollIntoView()
document.querySelector('#to-no-fallback-first').scrollIntoView()
})()`)
for (const dataPath of [
'/fr/gsp.json',
'/fr/gsp/fallback/first.json',
'/fr/gsp/fallback/hello.json',
]) {
const found = await browser.eval(`(function() {
const links = [].slice.call(document.querySelectorAll('link'))
for (var i = 0; i < links.length; i++) {
if (links[i].href.indexOf("${dataPath}") > -1) {
return true
}
}
return false
})()`)
expect(found).toBe(true)
}
}
expect(await browser.elementByCss('#router-pathname').text()).toBe(
'/locale-false'
)
......
......@@ -100,7 +100,7 @@ describe('Production response size', () => {
)
// These numbers are without gzip compression!
const delta = responseSizesBytes - 171 * 1024
const delta = responseSizesBytes - 172 * 1024
expect(delta).toBeLessThanOrEqual(1024) // don't increase size more than 1kb
expect(delta).toBeGreaterThanOrEqual(-1024) // don't decrease size more than 1kb without updating target
})
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册