Next.js+linariaを試してみる
はじめに
linariaを使ってみたかったのでNextjsと一緒に使ってみる。
TL;DR
前提
create-next-app --ts
でNext.jsのテンプレートが出来上がっている状態。
インストール
必要なライブラリのインストールから始める
# next-linariaのreadmeの通りにinstall
$ yarn add next-linaria linaria
# next-linariaの依存のwebpack-loaderの依存のwebpack(4|5)-loaderの依存に@babel/coreが居て
# 入っていないと動かすときに怒られるため追加。
$ yarn add -D @babel/core
試しに起動してみる(yarn dev
)と以下のエラーで落ちる。
error - ./pages/_app.tsx:2:12
Syntax error: Unexpected token
1 | import '../styles/globals.css'
> 2 | import type { AppProps } from 'next/app'
| ^
3 |
4 | function MyApp({ Component, pageProps }: AppProps) {
5 | return <Component {...pageProps} />
このエラーは下記issueと同じ状態。
Syntax error: Unexpected token · Issue #6 · Mistereo/next-linaria
で、それの回答が下記issue。
How to use with NextJS + typescript? · Issue #795 · callstack/linaria
Then add this to your babel config: presets: ['@linaria'] and wrap your next.config.js options with the default export from next-linaria withLinaria()
つまりbabelのpresetsにlinariaのpresetを追加すれば良いとのこと。
回答では@linaria
と書かれているが、今インストールしているlinaria
ベースで書くのであればlinaria/babel
と記載すればOK。(@linaria
を追加しても動く)
presetsの設定を入れる場合は入れたいものとNext.jsが必要としているpreset(next/babel
)も入れる必要がある。
module.exports = {
presets: ["next/babel", "linaria/babel"],
}
この状態で起動しエラーが出なければOK。
linariaを使ってみる
実際に使ってみる。
試しに作ったコードは下記の通り。
import type {NextPage} from 'next'
import Head from 'next/head'
import {css} from 'linaria';
import {styled} from 'linaria/react';
import {useState} from 'react';
const color = {
black: '#000'
} as const;
// cssを定義して使える
const MainStyle = css`
display: flex;
flex-direction: column;
align-items: center;
`;
// 変数の参照もできる
const TitleStyle = css`
color: ${color.black};
font-weight: 700;
font-size: 20px;
`;
// styled-componentsの様な書き方もできる
const Paragraph = styled.p`
color: #333;
font-size: 16px;
`;
// propsも受け取れる
const Button = styled.button<{ isDisabled: boolean }>`
background-color: ${props => props.isDisabled ? '#999' : '#fff'};
`;
const Home: NextPage = () => {
const [isGray, setGray] = useState(false);
return (
<>
<Head>
<title>Next.js + Linaria sample</title>
<meta name="description" content="Generated by create next app"/>
<link rel="icon" href="/favicon.ico"/>
</Head>
<main className={MainStyle}>
<h1 className={TitleStyle}>Next.js + Linaria sample</h1>
<Paragraph>サンプル</Paragraph>
<Button isDisabled={isGray} onClick={() => setGray((before) => !before)}>ボタン</Button>
</main>
</>
)
}
export default Home
起動できボタンクリックするたびに色が変わればOK。
まとめ
今回はlinariaを触ってみた。
css書くときはstyled-componentsを使うことが多かったが、同じ様な記法が使えるため切り替えることで覚え直しみたいなのは余りなさそうだった。
css-in-jsはパフォーマンスの懸念があるので乗せ換えられるのであれば乗せ換えてしまった方が良さそうではある。
ただし、一部IE11をサポートしていない機能があるため万が一IE11をターゲットにするのであれば注意が必要そう。
https://github.com/callstack/linaria#trade-offs
参考リンク
- callstack/linaria: Zero-runtime CSS in JS library
- Mistereo/next-linaria: Linaria support for Next.js
- How to use with NextJS + typescript? · Issue #795 · callstack/linaria
- linaria/packages/babel at master · callstack/linaria
- Advanced Features: Customizing Babel Config | Next.js
- next.js/examples/with-linaria at canary · vercel/next.js