Skip to content

Commit

Permalink
Disable built-in css-in-js transform on server layer (vercel#41040)
Browse files Browse the repository at this point in the history
We're supposed not to use css-in-js in server components since it will
increase the rsc response for navigation. Also adding `styledJsx` option
for next-swc for controlling styled-jsx transform.

Test case: using styled-jsx transform in server components will not be
transformed to `styled-jsx/style` imports.
  • Loading branch information
huozhi authored and Kikobeats committed Oct 24, 2022
1 parent a0f112f commit aa46d52
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 15 deletions.
9 changes: 8 additions & 1 deletion packages/next-swc/crates/core/src/lib.rs
Expand Up @@ -90,6 +90,9 @@ pub struct TransformOptions {
#[serde(default)]
pub server_components: Option<react_server_components::Config>,

#[serde(default)]
pub styled_jsx: bool,

#[serde(default)]
pub styled_components: Option<styled_components::Config>,

Expand Down Expand Up @@ -159,7 +162,11 @@ where
)),
_ => Either::Right(noop()),
},
styled_jsx::styled_jsx(cm.clone(), file.name.clone()),
if opts.styled_jsx {
Either::Left(styled_jsx::styled_jsx(cm.clone(), file.name.clone()))
} else {
Either::Right(noop())
},
hook_optimizer::hook_optimizer(),
match &opts.styled_components {
Some(config) => Either::Left(styled_components::styled_components(
Expand Down
1 change: 1 addition & 0 deletions packages/next-swc/crates/core/tests/full.rs
Expand Up @@ -59,6 +59,7 @@ fn test(input: &Path, minify: bool) {
is_server: false,
server_components: None,
styled_components: Some(assert_json("{}")),
styled_jsx: true,
remove_console: None,
react_remove_properties: None,
relay: None,
Expand Down
10 changes: 8 additions & 2 deletions packages/next/build/swc/options.js
Expand Up @@ -110,7 +110,6 @@ function getBaseSWCOptions({
},
},
sourceMaps: jest ? 'inline' : undefined,
styledComponents: getStyledComponentsOptions(nextConfig, development),
removeConsole: nextConfig?.compiler?.removeConsole,
// disable "reactRemoveProperties" when "jest" is true
// otherwise the setting from next.config.js will be used
Expand All @@ -119,7 +118,14 @@ function getBaseSWCOptions({
: nextConfig?.compiler?.reactRemoveProperties,
modularizeImports: nextConfig?.experimental?.modularizeImports,
relay: nextConfig?.compiler?.relay,
emotion: getEmotionOptions(nextConfig, development),
// Disable css-in-js transform on server layer for server components
...(isServerLayer
? {}
: {
emotion: getEmotionOptions(nextConfig, development),
styledComponents: getStyledComponentsOptions(nextConfig, development),
styledJsx: true,
}),
serverComponents: hasServerComponents
? {
isServer: !!isServerLayer,
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/webpack-config.ts
Expand Up @@ -1626,7 +1626,7 @@ export default async function getBaseWebpackConfig(
{
...codeCondition,
issuerLayer: WEBPACK_LAYERS.middleware,
use: getBabelOrSwcLoader(),
use: defaultLoaders.babel,
},
...(hasServerComponents
? [
Expand Down
3 changes: 3 additions & 0 deletions packages/next/server/config-schema.ts
Expand Up @@ -265,6 +265,9 @@ const configSchema = {
},
] as any,
},
appDir: {
type: 'boolean',
},
externalDir: {
type: 'boolean',
},
Expand Down
26 changes: 17 additions & 9 deletions test/e2e/app-dir/rsc-basic.test.ts
Expand Up @@ -38,7 +38,7 @@ describe('app dir - react server components', () => {
next = await createNext({
files: new FileRef(path.join(__dirname, './rsc-basic')),
dependencies: {
'styled-components': '6.0.0-alpha.5',
'styled-components': '6.0.0-beta.2',
react: '0.0.0-experimental-cb5084d1c-20220924',
'react-dom': '0.0.0-experimental-cb5084d1c-20220924',
},
Expand Down Expand Up @@ -76,8 +76,6 @@ describe('app dir - react server components', () => {
expect(homeHTML).toMatch(/^<!DOCTYPE html><html/)
expect(homeHTML).toContain('component:index.server')
expect(homeHTML).toContain('header:test-util')
// support esm module on server side
expect(homeHTML).toContain('random-module-instance')

const inlineFlightContents = []
const $ = cheerio.load(homeHTML)
Expand Down Expand Up @@ -247,12 +245,17 @@ describe('app dir - react server components', () => {
})

it('should handle external async module libraries correctly', async () => {
const html = await renderViaHTTP(next.url, '/external-imports')
expect(html).toContain('module type:esm-export')
expect(html).toContain('export named:named')
expect(html).toContain('export value:123')
expect(html).toContain('export array:4,5,6')
expect(html).toContain('export object:{x:1}')
const clientHtml = await renderViaHTTP(next.url, '/external-imports/client')
const serverHtml = await renderViaHTTP(next.url, '/external-imports/server')

expect(clientHtml).toContain('module type:esm-export')
expect(clientHtml).toContain('export named:named')
expect(clientHtml).toContain('export value:123')
expect(clientHtml).toContain('export array:4,5,6')
expect(clientHtml).toContain('export object:{x:1}')

// support esm module on server side
expect(serverHtml).toContain('random-module-instance')
})

it('should handle various kinds of exports correctly', async () => {
Expand Down Expand Up @@ -314,6 +317,11 @@ describe('app dir - react server components', () => {

// from styled-components
expect(head).toMatch(/{color:(\s*)blue;?}/)

// css-in-js like styled-jsx in server components won't be transformed
expect(html).toMatch(
/<style>\s*\.this-wont-be-transformed\s*\{\s*color:\s*purple;\s*\}\s*<\/style>/
)
})

it('should stick to the url without trailing /page suffix', async () => {
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/app-dir/rsc-basic/app/css-in-js/page.js
Expand Up @@ -6,6 +6,11 @@ export default function Page() {
<div>
<Comp />
<StyledComp />
<style jsx>{`
.this-wont-be-transformed {
color: purple;
}
`}</style>
</div>
)
}
@@ -0,0 +1,9 @@
import { name } from 'random-module-instance'

export default function Page() {
return (
<div>
<p>{name}</p>
</div>
)
}
2 changes: 0 additions & 2 deletions test/e2e/app-dir/rsc-basic/app/page.js
@@ -1,6 +1,5 @@
import Nav from '../components/nav'
import { headers } from 'next/dist/client/components/hooks-server'
import { name } from 'random-module-instance'

const envVar = process.env.ENV_VAR_TEST
const headerKey = 'x-next-test-client'
Expand All @@ -14,7 +13,6 @@ export default function Index() {
<h1>{`component:index.server`}</h1>
<div>{'env:' + envVar}</div>
<div>{'header:' + header}</div>
<p>{name}</p>
<Nav />
</div>
)
Expand Down

0 comments on commit aa46d52

Please sign in to comment.