Skip to content

Commit

Permalink
refactor(next): client/index.tsx (#20806)
Browse files Browse the repository at this point in the history
## summary
- add return types
- move `locale` variable const from let
- ~use [strict equality](https://github.com/vercel/next.js/pull/20806/files#diff-2433946f9a058f1b070138d12c20f10a9128e46408033629181f9f7fc3b9b9b2R275)~
  • Loading branch information
tarunama authored Jan 7, 2021
1 parent b442acb commit 629a7e8
Showing 1 changed file with 56 additions and 45 deletions.
101 changes: 56 additions & 45 deletions packages/next/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import '@next/polyfill-module'
import React from 'react'
import ReactDOM from 'react-dom'
import { HeadManagerContext } from '../next-server/lib/head-manager-context'
import mitt from '../next-server/lib/mitt'
import mitt, { MittEmitter } from '../next-server/lib/mitt'
import { RouterContext } from '../next-server/lib/router-context'
import Router, {
AppComponent,
Expand Down Expand Up @@ -68,13 +68,14 @@ const {
runtimeConfig,
dynamicIds,
isFallback,
locale,
locales,
domainLocales,
} = data

let { locale, defaultLocale } = data
let { defaultLocale } = data

const prefix = assetPrefix || ''
const prefix: string = assetPrefix || ''

// With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
// So, this is how we do it in the client side at runtime
Expand All @@ -85,7 +86,7 @@ envConfig.setConfig({
publicRuntimeConfig: runtimeConfig || {},
})

let asPath = getURL()
let asPath: string = getURL()

// make sure not to attempt stripping basePath for 404s
if (hasBasePath(asPath)) {
Expand Down Expand Up @@ -139,7 +140,7 @@ if (process.env.__NEXT_I18N_SUPPORT) {

type RegisterFn = (input: [string, () => void]) => void

const pageLoader = new PageLoader(buildId, prefix)
const pageLoader: PageLoader = new PageLoader(buildId, prefix)
const register: RegisterFn = ([r, f]) =>
pageLoader.routeLoader.onEntrypoint(r, f)
if (window.__NEXT_P) {
Expand All @@ -150,14 +151,15 @@ if (window.__NEXT_P) {
window.__NEXT_P = []
;(window.__NEXT_P as any).push = register

const headManager = initHeadManager()
const appElement = document.getElementById('__next')
const headManager: {
mountedInstances: Set<unknown>
updateHead: (head: JSX.Element[]) => void
} = initHeadManager()
const appElement: HTMLElement | null = document.getElementById('__next')

let lastAppProps: AppProps
let lastRenderReject: (() => void) | null
let webpackHMR: any
export let router: Router
let CachedComponent: React.ComponentType
let CachedApp: AppComponent, onPerfEntry: (metric: any) => void

class Container extends React.Component<{
Expand Down Expand Up @@ -217,7 +219,7 @@ class Container extends React.Component<{
hash = hash && hash.substring(1)
if (!hash) return

const el = document.getElementById(hash)
const el: HTMLElement | null = document.getElementById(hash)
if (!el) return

// If we call scrollIntoView() in here without a setTimeout
Expand All @@ -235,7 +237,8 @@ class Container extends React.Component<{
}
}

export const emitter = mitt()
export const emitter: MittEmitter = mitt()
let CachedComponent: React.ComponentType

export default async (opts: { webpackHMR?: any } = {}) => {
// This makes sure this specific lines are removed in production
Expand All @@ -260,12 +263,12 @@ export default async (opts: { webpackHMR?: any } = {}) => {
duration,
entryType,
entries,
}) => {
}): void => {
// Combines timestamp with random number for unique ID
const uniqueID = `${Date.now()}-${
const uniqueID: string = `${Date.now()}-${
Math.floor(Math.random() * (9e12 - 1)) + 1e12
}`
let perfStartEntry
let perfStartEntry: string | undefined

if (entries && entries.length) {
perfStartEntry = entries[0].startTime
Expand Down Expand Up @@ -403,7 +406,7 @@ export default async (opts: { webpackHMR?: any } = {}) => {
}
}

export async function render(renderingProps: RenderRouteInfo) {
export async function render(renderingProps: RenderRouteInfo): Promise<void> {
if (renderingProps.err) {
await renderError(renderingProps)
return
Expand All @@ -430,7 +433,7 @@ export async function render(renderingProps: RenderRouteInfo) {
// This method handles all runtime and debug errors.
// 404 and 500 errors are special kind of errors
// and they are still handle via the main render method.
export function renderError(renderErrorProps: RenderErrorProps) {
export function renderError(renderErrorProps: RenderErrorProps): Promise<any> {
const { App, err } = renderErrorProps

// In development runtime errors are caught by our overlay
Expand Down Expand Up @@ -496,8 +499,8 @@ export function renderError(renderErrorProps: RenderErrorProps) {
}

let reactRoot: any = null
let shouldUseHydrate = typeof ReactDOM.hydrate === 'function'
function renderReactElement(reactEl: JSX.Element, domEl: HTMLElement) {
let shouldUseHydrate: boolean = typeof ReactDOM.hydrate === 'function'
function renderReactElement(reactEl: JSX.Element, domEl: HTMLElement): void {
if (process.env.__NEXT_REACT_MODE !== 'legacy') {
if (!reactRoot) {
const opts = { hydrate: true }
Expand All @@ -523,7 +526,7 @@ function renderReactElement(reactEl: JSX.Element, domEl: HTMLElement) {
}
}

function markHydrateComplete() {
function markHydrateComplete(): void {
if (!ST) return

performance.mark('afterHydrate') // mark end of hydration
Expand All @@ -541,15 +544,16 @@ function markHydrateComplete() {
clearMarks()
}

function markRenderComplete() {
function markRenderComplete(): void {
if (!ST) return

performance.mark('afterRender') // mark end of render
const navStartEntries = performance.getEntriesByName('routeChange', 'mark')
const navStartEntries: PerformanceEntryList = performance.getEntriesByName(
'routeChange',
'mark'
)

if (!navStartEntries.length) {
return
}
if (!navStartEntries.length) return

performance.measure(
'Next.js-route-change-to-render',
Expand All @@ -569,7 +573,7 @@ function markRenderComplete() {
)
}

function clearMarks() {
function clearMarks(): void {
;[
'beforeRender',
'afterHydrate',
Expand Down Expand Up @@ -600,7 +604,7 @@ function AppContainer({

const wrapApp = (App: AppComponent) => (
wrappedAppProps: Record<string, any>
) => {
): JSX.Element => {
const appProps: AppProps = {
...wrappedAppProps,
Component: CachedComponent,
Expand All @@ -614,8 +618,9 @@ const wrapApp = (App: AppComponent) => (
)
}

let lastAppProps: AppProps
function doRender(input: RenderRouteInfo): Promise<any> {
let { App, Component, props, err } = input
let { App, Component, props, err }: RenderRouteInfo = input
let styleSheets: StyleSheetTuple[] | undefined =
'initial' in input ? undefined : input.styleSheets
Component = Component || lastAppProps.Component
Expand All @@ -630,7 +635,7 @@ function doRender(input: RenderRouteInfo): Promise<any> {
// lastAppProps has to be set before ReactDom.render to account for ReactDom throwing an error.
lastAppProps = appProps

let canceled = false
let canceled: boolean = false
let resolvePromise: () => void
const renderPromise = new Promise<void>((resolve, reject) => {
if (lastRenderReject) {
Expand Down Expand Up @@ -662,17 +667,21 @@ function doRender(input: RenderRouteInfo): Promise<any> {
return false
}

const currentStyleTags = looseToArray<HTMLStyleElement>(
const currentStyleTags: HTMLStyleElement[] = looseToArray<HTMLStyleElement>(
document.querySelectorAll('style[data-n-href]')
)
const currentHrefs = new Set(
const currentHrefs: Set<string | null> = new Set(
currentStyleTags.map((tag) => tag.getAttribute('data-n-href'))
)

const noscript = document.querySelector('noscript[data-n-css]')
const nonce = noscript?.getAttribute('data-n-css')
const noscript: Element | null = document.querySelector(
'noscript[data-n-css]'
)
const nonce: string | null | undefined = noscript?.getAttribute(
'data-n-css'
)

styleSheets.forEach(({ href, text }) => {
styleSheets.forEach(({ href, text }: { href: string; text: any }) => {
if (!currentHrefs.has(href)) {
const styleTag = document.createElement('style')
styleTag.setAttribute('data-n-href', href)
Expand All @@ -689,7 +698,7 @@ function doRender(input: RenderRouteInfo): Promise<any> {
return true
}

function onHeadCommit() {
function onHeadCommit(): void {
if (
// We use `style-loader` in development, so we don't need to do anything
// unless we're in production:
Expand All @@ -700,11 +709,11 @@ function doRender(input: RenderRouteInfo): Promise<any> {
// Ensure this render was not canceled
!canceled
) {
const desiredHrefs = new Set(styleSheets.map((s) => s.href))
const currentStyleTags = looseToArray<HTMLStyleElement>(
document.querySelectorAll('style[data-n-href]')
)
const currentHrefs = currentStyleTags.map(
const desiredHrefs: Set<string> = new Set(styleSheets.map((s) => s.href))
const currentStyleTags: HTMLStyleElement[] = looseToArray<
HTMLStyleElement
>(document.querySelectorAll('style[data-n-href]'))
const currentHrefs: string[] = currentStyleTags.map(
(tag) => tag.getAttribute('data-n-href')!
)

Expand All @@ -718,13 +727,15 @@ function doRender(input: RenderRouteInfo): Promise<any> {
}

// Reorder styles into intended order:
let referenceNode = document.querySelector('noscript[data-n-css]')
let referenceNode: Element | null = document.querySelector(
'noscript[data-n-css]'
)
if (
// This should be an invariant:
referenceNode
) {
styleSheets.forEach(({ href }) => {
const targetTag = document.querySelector(
styleSheets.forEach(({ href }: { href: string }) => {
const targetTag: Element | null = document.querySelector(
`style[data-n-href="${href}"]`
)
if (
Expand Down Expand Up @@ -757,11 +768,11 @@ function doRender(input: RenderRouteInfo): Promise<any> {
}
}

function onRootCommit() {
function onRootCommit(): void {
resolvePromise()
}

const elem = (
const elem: JSX.Element = (
<Root callback={onRootCommit}>
<Head callback={onHeadCommit} />
<AppContainer>
Expand Down Expand Up @@ -814,7 +825,7 @@ function Root({

// Dummy component that we render as a child of Root so that we can
// toggle the correct styles before the page is rendered.
function Head({ callback }: { callback: () => void }) {
function Head({ callback }: { callback: () => void }): null {
// We use `useLayoutEffect` to guarantee the callback is executed
// as soon as React flushes the update.
React.useLayoutEffect(() => callback(), [callback])
Expand Down

0 comments on commit 629a7e8

Please sign in to comment.