Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWC emotion transform plugin #34687

Merged
merged 7 commits into from Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/build_test_deploy.yml
Expand Up @@ -97,7 +97,7 @@ jobs:
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
with:
profile: minimal
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23
components: rustfmt, clippy

- name: Cache cargo registry
Expand Down Expand Up @@ -732,7 +732,7 @@ jobs:
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
with:
profile: minimal
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23

- name: Cache cargo registry
uses: actions/cache@v2
Expand Down Expand Up @@ -811,7 +811,7 @@ jobs:
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23
profile: minimal
- run: cd packages/next-swc && cargo test
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
Expand Down Expand Up @@ -889,8 +889,8 @@ jobs:
# Node.js in Baidu need to compatible with `GLIBC_2.12`
build: >-
set -e &&
rustup toolchain install nightly-2021-11-15 &&
rustup default nightly-2021-11-15 &&
rustup toolchain install nightly-2022-02-23 &&
rustup default nightly-2022-02-23 &&
rustup target add x86_64-unknown-linux-gnu &&
npm i -g @napi-rs/cli@2.4.4 turbo@1.0.28 &&
turbo run build-native --cache-dir=".turbo" -- --release --target x86_64-unknown-linux-gnu --zig --zig-abi-suffix 2.12 &&
Expand All @@ -900,8 +900,8 @@ jobs:
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: >-
set -e &&
rustup toolchain install nightly-2021-11-15 &&
rustup default nightly-2021-11-15 &&
rustup toolchain install nightly-2022-02-23 &&
rustup default nightly-2022-02-23 &&
rustup target add x86_64-unknown-linux-musl &&
npm i -g @napi-rs/cli@2.4.4 turbo@1.0.28 &&
turbo run build-native --cache-dir=".turbo" -- --release --target x86_64-unknown-linux-musl &&
Expand All @@ -922,8 +922,8 @@ jobs:
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine-zig
build: >-
set -e &&
rustup toolchain install nightly-2021-11-15 &&
rustup default nightly-2021-11-15 &&
rustup toolchain install nightly-2022-02-23 &&
rustup default nightly-2022-02-23 &&
rustup target add aarch64-unknown-linux-gnu &&
npm i -g @napi-rs/cli@2.4.4 turbo@1.0.28 &&
turbo run build-native --cache-dir=".turbo" -- --release --target aarch64-unknown-linux-gnu --zig --zig-abi-suffix 2.12 &&
Expand Down Expand Up @@ -963,8 +963,8 @@ jobs:
build: >-
set -e &&
npm i -g @napi-rs/cli@2.4.4 turbo@1.0.28 &&
rustup toolchain install nightly-2021-11-15 &&
rustup default nightly-2021-11-15 &&
rustup toolchain install nightly-2022-02-23 &&
rustup default nightly-2022-02-23 &&
rustup target add aarch64-unknown-linux-musl &&
turbo run build-native --cache-dir=".turbo" -- --release --target aarch64-unknown-linux-musl &&
llvm-strip -x packages/next-swc/native/next-swc.*.node
Expand Down Expand Up @@ -1030,7 +1030,7 @@ jobs:
with:
profile: minimal
override: true
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23
target: ${{ matrix.settings.target }}

- name: Cache cargo registry
Expand Down Expand Up @@ -1092,7 +1092,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23
override: true
target: wasm32-unknown-unknown

Expand Down Expand Up @@ -1148,7 +1148,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2021-11-15
toolchain: nightly-2022-02-23
override: true
target: wasm32-unknown-unknown

Expand Down
30 changes: 30 additions & 0 deletions docs/advanced-features/compiler.md
Expand Up @@ -189,6 +189,36 @@ First, update to the latest version of Next.js: `npm install next@latest`. Then,

## Experimental Features

### Emotion

We're working to port `@emotion/babel-plugin` to the Next.js Compiler.

First, update to the latest version of Next.js: `npm install next@latest`. Then, update your `next.config.js` file:

```js
// next.config.js

module.exports = {
experimental: {
emotion: boolean | {
Brooooooklyn marked this conversation as resolved.
Show resolved Hide resolved
// default is true. It will be disabled when build type is production.
sourceMap?: boolean,
// default is 'dev-only'.
autoLabel?: 'never' | 'dev-only' | 'always',
// default is '[local]'.
// Allowed values: `[local]` `[filename]` and `[dirname]`
// This option only works when autoLabel is set to 'dev-only' or 'always'.
// It allows you to define the format of the resulting label.
// The format is defined via string where variable parts are enclosed in square brackets [].
// For example labelFormat: "my-classname--[local]", where [local] will be replaced with the name of the variable the result is assigned to.
labelFormat?: string,
},
},
}
```

Only `importMap` in `@emotion/babel-plugin` is not supported for now.

### Minification

You can opt-in to using the Next.js compiler for minification. This is 7x faster than Terser.
Expand Down
34 changes: 34 additions & 0 deletions examples/with-emotion-swc/.gitignore
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
31 changes: 31 additions & 0 deletions examples/with-emotion-swc/README.md
@@ -0,0 +1,31 @@
# Emotion Example

Extract and inline critical css with
[@emotion/css](https://github.com/emotion-js/emotion/tree/master/packages/css),
[@emotion/server](https://github.com/emotion-js/emotion/tree/master/packages/server),
[@emotion/react](https://github.com/emotion-js/emotion/tree/master/packages/react),
and [@emotion/styled](https://github.com/emotion-js/emotion/tree/master/packages/styled).

## Preview

Preview the example live on [StackBlitz](http://stackblitz.com/):

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-emotion)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-emotion&project-name=with-emotion&repository-name=with-emotion)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example with-emotion with-emotion-app
# or
yarn create next-app --example with-emotion with-emotion-app
```

Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
10 changes: 10 additions & 0 deletions examples/with-emotion-swc/next.config.js
@@ -0,0 +1,10 @@
/** @type {import('next').NextConfig} */

const nextConfig = {
reactStrictMode: true,
experimental: {
emotion: true,
},
}

module.exports = nextConfig
15 changes: 15 additions & 0 deletions examples/with-emotion-swc/package.json
@@ -0,0 +1,15 @@
{
"private": true,
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@emotion/react": "11.8.1",
"@emotion/styled": "11.8.1",
"next": "latest",
"react": "17.0.2",
"react-dom": "17.0.2"
}
}
15 changes: 15 additions & 0 deletions examples/with-emotion-swc/pages/_app.js
@@ -0,0 +1,15 @@
import createCache from '@emotion/cache'
import { CacheProvider } from '@emotion/react'

import { globalStyles } from '../shared/styles'

const cache = createCache({ key: 'next' })

const App = ({ Component, pageProps }) => (
<CacheProvider value={cache}>
{globalStyles}
<Component {...pageProps} />
</CacheProvider>
)

export default App
20 changes: 20 additions & 0 deletions examples/with-emotion-swc/pages/index.js
@@ -0,0 +1,20 @@
import { css } from '@emotion/react'
import { Animated, Basic, bounce, Combined, Pink } from '../shared/styles'

const Home = () => (
<div
css={css`
display: flex;
flex-direction: column;
`}
>
<Basic>Cool Styles</Basic>
<Pink>Pink text</Pink>
<Combined>
With <code>:hover</code>.
</Combined>
<Animated animation={bounce}>Let's bounce.</Animated>
</div>
)

export default Home
72 changes: 72 additions & 0 deletions examples/with-emotion-swc/shared/styles.js
@@ -0,0 +1,72 @@
import { css, Global, keyframes } from '@emotion/react'
import styled from '@emotion/styled'

export const globalStyles = (
<Global
styles={css`
html,
body {
padding: 3rem 1rem;
margin: 0;
background: papayawhip;
min-height: 100%;
font-family: Helvetica, Arial, sans-serif;
font-size: 24px;
}
`}
/>
)

export const basicStyles = css({
backgroundColor: 'white',
color: 'cornflowerblue',
border: '1px solid lightgreen',
borderRight: 'none',
borderBottom: 'none',
boxShadow: '5px 5px 0 0 lightgreen, 10px 10px 0 0 lightyellow',
transition: 'all 0.1s linear',
margin: '3rem 0',
padding: '1rem 0.5rem',
})

export const hoverStyles = css`
&:hover {
color: white;
background-color: lightgray;
border-color: aqua;
box-shadow: -15px -15px 0 0 aqua, -30px -30px 0 0 cornflowerblue;
}
`
export const bounce = keyframes`
from {
transform: scale(1.01);
}
to {
transform: scale(0.99);
}
`

export const Basic = styled.div`
${basicStyles};
`

export const Combined = styled.div`
${basicStyles};
${hoverStyles};
& code {
background-color: linen;
}
`

export const Pink = styled.div(basicStyles, {
color: 'hotpink',
})

export const Animated = styled.div`
${basicStyles};
${hoverStyles};
& code {
background-color: linen;
}
animation: ${({ animation }) => animation} 0.2s infinite ease-in-out alternate;
`