Skip to content

Commit

Permalink
Add experimental flag for styled-components transform + add test
Browse files Browse the repository at this point in the history
  • Loading branch information
timneutkens committed Nov 9, 2021
1 parent af1b30b commit 9a19263
Show file tree
Hide file tree
Showing 11 changed files with 369 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"seedrandom": "3.0.5",
"selenium-webdriver": "4.0.0-beta.4",
"shell-quote": "1.7.3",
"styled-components": "5.3.3",
"styled-jsx-plugin-postcss": "3.0.2",
"tailwindcss": "1.1.3",
"taskr": "1.1.0",
Expand Down
7 changes: 7 additions & 0 deletions packages/next/build/swc/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function getBaseSWCOptions({
development,
hasReactRefresh,
globalWindow,
styledComponents,
}) {
const isTSFile = filename.endsWith('.ts')
const isTypeScript = isTSFile || filename.endsWith('.tsx')
Expand Down Expand Up @@ -42,6 +43,10 @@ function getBaseSWCOptions({
},
},
},
styledComponents: {
displayName: styledComponents,
ssr: styledComponents,
},
}
}

Expand Down Expand Up @@ -78,12 +83,14 @@ export function getLoaderSWCOptions({
pagesDir,
isPageFile,
hasReactRefresh,
styledComponents,
}) {
let baseOptions = getBaseSWCOptions({
filename,
development,
globalWindow: !isServer,
hasReactRefresh,
styledComponents,
})

const isNextDist = nextDistPath.test(filename)
Expand Down
1 change: 1 addition & 0 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ export default async function getBaseWebpackConfig(
isServer: isMiddleware || isServer,
pagesDir,
hasReactRefresh: !isMiddleware && hasReactRefresh,
styledComponents: config.experimental.styledComponents,
},
}
: {
Expand Down
4 changes: 3 additions & 1 deletion packages/next/build/webpack/loaders/next-swc-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ async function loaderTransform(parentTrace, source, inputSourceMap) {

let loaderOptions = this.getOptions() || {}

const { isServer, pagesDir, hasReactRefresh } = loaderOptions
const { isServer, pagesDir, hasReactRefresh, styledComponents } =
loaderOptions
const isPageFile = filename.startsWith(pagesDir)

const swcOptions = getLoaderSWCOptions({
Expand All @@ -45,6 +46,7 @@ async function loaderTransform(parentTrace, source, inputSourceMap) {
isPageFile,
development: this.mode === 'development',
hasReactRefresh,
styledComponents,
})

const programmaticOptions = {
Expand Down
1 change: 1 addition & 0 deletions packages/next/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export type NextConfig = { [key: string]: any } & {
crossOrigin?: false | 'anonymous' | 'use-credentials'
swcMinify?: boolean
experimental?: {
styledComponents?: boolean
swcMinify?: boolean
cpus?: number
sharedPool?: boolean
Expand Down
60 changes: 60 additions & 0 deletions test/development/basic/styled-components.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { join } from 'path'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { fetchViaHTTP } from 'next-test-utils'

describe('styled-components SWC transform', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
// 'next.config.js': new FileRef(
// join(__dirname, 'styled-components/next.config.js')
// ),
pages: new FileRef(join(__dirname, 'styled-components/pages')),
},
dependencies: {
'styled-components': '5.3.3',
},
})
})
afterAll(() => next.destroy())

async function matchLogs$(browser) {
let foundLog = false

const browserLogs = await browser.log('browser')

browserLogs.forEach((log) => {
console.error({ log })
if (log.message.includes('Warning: Prop `%s` did not match.')) {
foundLog = true
}
})
return foundLog
}
it('should not have hydration mismatch with styled-components transform enabled', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/')

// Compile /_error
await fetchViaHTTP(next.appPort, '/404')

// Try 4 times to be sure there is no mismatch
expect(await matchLogs$(browser)).toBe(false)
await browser.refresh()
expect(await matchLogs$(browser)).toBe(false)
await browser.refresh()
expect(await matchLogs$(browser)).toBe(false)
await browser.refresh()
expect(await matchLogs$(browser)).toBe(false)
} finally {
if (browser) {
await browser.close()
}
}
})
})
5 changes: 5 additions & 0 deletions test/development/basic/styled-components/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
styledComponents: true,
},
}
26 changes: 26 additions & 0 deletions test/development/basic/styled-components/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createGlobalStyle, ThemeProvider } from 'styled-components'

const GlobalStyle = createGlobalStyle`
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
`

const theme = {
colors: {
primary: '#0070f3',
},
}

export default function App({ Component, pageProps }) {
return (
<>
<GlobalStyle />
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
</>
)
}
30 changes: 30 additions & 0 deletions test/development/basic/styled-components/pages/_document.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage

try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
})

const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
38 changes: 38 additions & 0 deletions test/development/basic/styled-components/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import styled, { css } from 'styled-components'
const Button = styled.a`
/* This renders the buttons above... Edit me! */
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
/* The GitHub button is a primary button
* edit this to target it specifically! */
${(props) =>
props.primary &&
css`
background: white;
color: black;
`}
`

export default function Home() {
return (
<div>
<Button
href="https://github.com/styled-components/styled-components"
target="_blank"
rel="noopener"
primary
>
GitHub
</Button>

<Button href="/docs">Documentation</Button>
</div>
)
}
Loading

0 comments on commit 9a19263

Please sign in to comment.