Skip to content

Commit

Permalink
Adopt context based experimental styled-jsx version (#28646)
Browse files Browse the repository at this point in the history
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
huozhi and kodiakhq[bot] authored Sep 9, 2021
1 parent 1389339 commit 57d9076
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 61 deletions.
3 changes: 2 additions & 1 deletion packages/next/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import '@next/polyfill-module'
import React from 'react'
import ReactDOM from 'react-dom'
import { StyleRegistry } from 'styled-jsx'
import { HeadManagerContext } from '../shared/lib/head-manager-context'
import mitt, { MittEmitter } from '../shared/lib/mitt'
import { RouterContext } from '../shared/lib/router-context'
Expand Down Expand Up @@ -598,7 +599,7 @@ function AppContainer({
>
<RouterContext.Provider value={makePublicRouterInstance(router)}>
<HeadManagerContext.Provider value={headManager}>
{children}
<StyleRegistry>{children}</StyleRegistry>
</HeadManagerContext.Provider>
</RouterContext.Provider>
</Container>
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"stream-browserify": "3.0.0",
"stream-http": "3.1.1",
"string_decoder": "1.3.0",
"styled-jsx": "4.0.1",
"styled-jsx": "5.0.0-beta.1",
"timers-browserify": "2.0.12",
"tty-browserify": "0.0.1",
"use-subscription": "1.5.1",
Expand Down
95 changes: 47 additions & 48 deletions packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { Component, ReactElement, ReactNode, useContext } from 'react'
import flush from 'styled-jsx/server'
import {
BODY_RENDER_TARGET,
OPTIMIZED_FONT_PROVIDERS,
Expand Down Expand Up @@ -166,16 +165,8 @@ export default class Document<P = {}> extends Component<DocumentProps & P> {
* `getInitialProps` hook returns the context object with the addition of `renderPage`.
* `renderPage` callback executes `React` rendering logic synchronously to support server-rendering wrappers
*/
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const enhanceApp = (App: any) => {
return (props: any) => <App {...props} />
}

const { html, head } = await ctx.renderPage({ enhanceApp })
const styles = [...flush()]
return { html, head, styles }
static getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
return ctx.defaultGetInitialProps(ctx)
}

render() {
Expand Down Expand Up @@ -213,6 +204,50 @@ export function Html(
)
}

function AmpStyles({
styles,
}: {
styles?: React.ReactElement[] | React.ReactFragment
}) {
if (!styles) return null

// try to parse styles from fragment for backwards compat
const curStyles: React.ReactElement[] = Array.isArray(styles)
? (styles as React.ReactElement[])
: []
if (
// @ts-ignore Property 'props' does not exist on type ReactElement
styles.props &&
// @ts-ignore Property 'props' does not exist on type ReactElement
Array.isArray(styles.props.children)
) {
const hasStyles = (el: React.ReactElement) =>
el?.props?.dangerouslySetInnerHTML?.__html
// @ts-ignore Property 'props' does not exist on type ReactElement
styles.props.children.forEach((child: React.ReactElement) => {
if (Array.isArray(child)) {
child.forEach((el) => hasStyles(el) && curStyles.push(el))
} else if (hasStyles(child)) {
curStyles.push(child)
}
})
}

/* Add custom styles before AMP styles to prevent accidental overrides */
return (
<style
amp-custom=""
dangerouslySetInnerHTML={{
__html: curStyles
.map((style) => style.props.dangerouslySetInnerHTML.__html)
.join('')
.replace(/\/\*# sourceMappingURL=.*\*\//g, '')
.replace(/\/\*@ sourceURL=.*?\*\//g, ''),
}}
/>
)
}

export class Head extends Component<
OriginProps &
React.DetailedHTMLProps<
Expand Down Expand Up @@ -555,30 +590,6 @@ export class Head extends Component<
return child
})

// try to parse styles from fragment for backwards compat
const curStyles: React.ReactElement[] = Array.isArray(styles)
? (styles as React.ReactElement[])
: []
if (
inAmpMode &&
styles &&
// @ts-ignore Property 'props' does not exist on type ReactElement
styles.props &&
// @ts-ignore Property 'props' does not exist on type ReactElement
Array.isArray(styles.props.children)
) {
const hasStyles = (el: React.ReactElement) =>
el?.props?.dangerouslySetInnerHTML?.__html
// @ts-ignore Property 'props' does not exist on type ReactElement
styles.props.children.forEach((child: React.ReactElement) => {
if (Array.isArray(child)) {
child.forEach((el) => hasStyles(el) && curStyles.push(el))
} else if (hasStyles(child)) {
curStyles.push(child)
}
})
}

const files: DocumentFiles = getDocumentFiles(
this.context.buildManifest,
this.context.__NEXT_DATA__.page,
Expand Down Expand Up @@ -635,19 +646,7 @@ export class Head extends Component<
as="script"
href="https://cdn.ampproject.org/v0.js"
/>
{/* Add custom styles before AMP styles to prevent accidental overrides */}
{styles && (
<style
amp-custom=""
dangerouslySetInnerHTML={{
__html: curStyles
.map((style) => style.props.dangerouslySetInnerHTML.__html)
.join('')
.replace(/\/\*# sourceMappingURL=.*\*\//g, '')
.replace(/\/\*@ sourceURL=.*?\*\//g, ''),
}}
/>
)}
<AmpStyles styles={styles} />
<style
amp-boilerplate=""
dangerouslySetInnerHTML={{
Expand Down
24 changes: 19 additions & 5 deletions packages/next/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ParsedUrlQuery } from 'querystring'
import { PassThrough } from 'stream'
import React from 'react'
import * as ReactDOMServer from 'react-dom/server'
import flush from 'styled-jsx/server'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
import Observable from 'next/dist/compiled/zen-observable'
import { warn } from '../build/output/log'
import { UnwrapPromise } from '../lib/coalesced-function'
Expand Down Expand Up @@ -40,6 +40,7 @@ import {
ComponentsEnhancer,
DocumentInitialProps,
DocumentProps,
DocumentContext,
HtmlContext,
HtmlProps,
getDisplayName,
Expand Down Expand Up @@ -482,6 +483,7 @@ export async function renderToHTML(
isPreview,
(req as any).__nextIsLocaleDomain
)
const jsxStyleRegistry = createStyleRegistry()
const ctx = {
err,
req: isAutoExport ? undefined : req,
Expand All @@ -499,6 +501,17 @@ export async function renderToHTML(
</AppContainer>
)
},
defaultGetInitialProps: async (
docCtx: DocumentContext
): Promise<DocumentInitialProps> => {
const enhanceApp = (AppComp: any) => {
return (props: any) => <AppComp {...props} />
}

const { html, head } = await docCtx.renderPage({ enhanceApp })
const styles = jsxStyleRegistry.styles()
return { html, head, styles }
},
}
let props: any

Expand Down Expand Up @@ -536,7 +549,9 @@ export async function renderToHTML(
<LoadableContext.Provider
value={(moduleName) => reactLoadableModules.push(moduleName)}
>
{children}
<StyleRegistry registry={jsxStyleRegistry}>
{children}
</StyleRegistry>
</LoadableContext.Provider>
</HeadManagerContext.Provider>
</AmpStateContext.Provider>
Expand Down Expand Up @@ -1018,8 +1033,7 @@ export async function renderToHTML(
documentElement: () => (Document as any)(),
head,
headTags: [],
// TODO: Experimental styled-jsx 5 support
styles: [...flush()],
styles: jsxStyleRegistry.styles(),
}
}
}
Expand Down Expand Up @@ -1108,7 +1122,7 @@ export async function renderToHTML(
locale,
disableOptimizedLoading,
head: documentResult.head,
headTags: documentResult?.headTags,
headTags: documentResult.headTags,
styles: documentResult.styles,
}
const documentHTML = ReactDOMServer.renderToStaticMarkup(
Expand Down
3 changes: 2 additions & 1 deletion packages/next/shared/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export type RenderPageResult = {

export type RenderPage = (
options?: ComponentsEnhancer
) => RenderPageResult | Promise<RenderPageResult>
) => DocumentInitialProps | Promise<DocumentInitialProps>

export type BaseContext = {
res?: ServerResponse
Expand Down Expand Up @@ -178,6 +178,7 @@ export type AppPropsType<

export type DocumentContext = NextPageContext & {
renderPage: RenderPage
defaultGetInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps>
}

export type DocumentInitialProps = RenderPageResult & {
Expand Down
1 change: 0 additions & 1 deletion packages/next/types/misc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ declare module 'cssnano-simple' {
const cssnanoSimple: any
export = cssnanoSimple
}
declare module 'styled-jsx/server'

declare module 'next/dist/compiled/amphtml-validator' {
import m from 'amphtml-validator'
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18512,10 +18512,10 @@ styled-jsx-plugin-postcss@3.0.2:
postcss "^7.0.2"
postcss-load-plugins "^2.3.0"

styled-jsx@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.1.tgz#ae3f716eacc0792f7050389de88add6d5245b9e9"
integrity sha512-Gcb49/dRB1k8B4hdK8vhW27Rlb2zujCk1fISrizCcToIs+55B4vmUM0N9Gi4nnVfFZWe55jRdWpAqH1ldAKWvQ==
styled-jsx@5.0.0-beta.1:
version "5.0.0-beta.1"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0-beta.1.tgz#159e147ff77cdc7aff7631d248fad649b870b7cd"
integrity sha512-c8pkEyI4J2lNedm/kaurCU/4U+L7Z4XUSzXBXnf0voGFwERgO2LPcKg03oV8xUMdsy0T5ZZSvlMPbNSsSMAxkg==
dependencies:
"@babel/plugin-syntax-jsx" "7.14.5"
"@babel/types" "7.15.0"
Expand Down

0 comments on commit 57d9076

Please sign in to comment.