はじめに
個人開発で React から Next.js へ移行しようと考えたため、その際の構築手順をまとめます。
linaria on Next.js には 今回は next-linaria を使用しました。
README.md には以下の説明文があります。
Next.jsの組み込みCSSサポートにLinariaを追加します。
バージョン1.0.0以降はlinaria@3でのみ動作します。
linaria@2のサポートが必要な場合は、本パッケージのバージョン0.11.0をご利用ください。
本パッケージのバージョン0.11.0は、next@9.5.4 以降を必要とします。next@9.2.0-9.5.3の場合、本パッケージのバージョン0.10.0をご利用ください。
このモジュールはNext.jsのビルトインCSSサポートと併用することを想定しており、おそらくカスタムCSSの処理では動作しないでしょう。
linaria@3 は現在ベータ版のため、next-linaria の対応状況は公式の README.md を参照するようにしてください。
本記事では最初にクイックスタートとして必要な手順のみを示します。
その後に筆者が実際に試した手順を示します。
後者の手順はエラーメッセージからこの記事へたどり着けること(&エラーを解決できること)を目的としています。
コードは GitHubリポジトリ にあります。
環境
各パッケージのバージョンと最終的な package.json
を先に提示します。
バージョン
パッケージ | バージョン |
---|---|
next | 12.1.5 |
react | 18.0.0 |
typescript | 4.6.3 |
linaria | 3.0.0-beta.18 |
linaria は version 3 を使用していますが、2022年4月時点では beta 版となっています。
安定版になるにあたり挙動が変更される可能性があるため、1つの参考としてください。
package.json
{
"name": "linaria-on-next-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"linaria": "3.0.0-beta.18",
"next": "12.1.5",
"next-linaria": "1.0.0-beta",
"react": "18.0.0",
"react-dom": "18.0.0"
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@linaria/webpack-loader": "^3.0.0-beta.16",
"@types/node": "17.0.25",
"@types/react": "18.0.6",
"@types/react-dom": "18.0.2",
"eslint": "8.14.0",
"eslint-config-next": "12.1.5",
"typescript": "4.6.3"
}
}
クイックスタート
必要な手順のみを示したクイックスタートを記述します。
Next.js の構築
create-next-app を使用して next アプリケーションを構築します。
$ npx create-next-app@latest --typescript
パッケージのインストール
まず linaria 関係のパッケージを追加します。
ここでは beta 版の linaria@3 を使用していますが、ユースケースに合わせて変更してください。
next-linaria のバージョンは 公式の README.md を参考にしてください。
$ yarn add linaria@3.0.0-beta.18 next-linaria@1.0.0-beta
次に webpack と babel 関係のパッケージをインストールします。
$ yarn add -D @linaria/webpack-loader @babel/core
Next.js の設定
next.config.js
を next-linaria
を使用するように修正します。
/** @type {import('next').NextConfig} */
const withLinaria = require('next-linaria')
const nextConfig = {
reactStrictMode: true,
}
const linariaOption = {}
module.exports = withLinaria({
...nextConfig,
linaria: linariaOption,
})
Babel の設定
最後に .babelrc
に設定を追加すれば終了です。
{
"presets": ["next/babel", "linaria/babel"]
}
これで linaria によるスタイリングが適用できるようになります。
実際に行った手順
筆者が実際に行った手順を記述します。
暇なときの読み物として呼んでください。
Next.js の構築
create-next-app
Next.js の公式ドキュメント を参考に作成していきます。
今回は create-next-app
を使用してサクっと作成します。
$ npx create-next-app@latest --typescript
✔ What is your project named? … linaria-on-next-demo
...
Success! Created linaria-on-next-demo at /path/to/linaria-on-next-demo
構築が終わったら、 Next.js を立ち上げて localhost にアクセスしてみましょう。
$ yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
event - compiled client and server successfully in 844 ms (124 modules)
この状態で localhost:3000 へアクセスし、Next.js の初期ページが表示されれば成功です。
プロジェクト名の使用先
余談ですが、指定したプロジェクト名はどこで活用されるのかを説明します。
✔ What is your project named?
ではプロジェクト名を指定します。
指定したプロジェクト名は以下で活用されます。
- カレントディレクトリ配下に、指定したプロジェクト名のディレクトリが作成される
- このディレクトリ配下に Next.js アプリケーションが構築される
-
pakcage.json
の application name が指定したプロジェクト名となる
$ ls
linaria-on-next-demo
$ ls linaria-on-next-demo
README.md next.config.js package.json public tsconfig.json
next-env.d.ts node_modules pages styles yarn.lock
TypeScript 関連の設定ファイルも作成されていますね。非常に便利なツールです。
作成された package.json
もう1つ余談です。
筆者の環境で作成された packa.json
は次のとおりとなります。
{
"name": "linaria-on-next-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "12.1.5",
"react": "18.0.0",
"react-dom": "18.0.0"
},
"devDependencies": {
"@types/node": "17.0.25",
"@types/react": "18.0.6",
"@types/react-dom": "18.0.2",
"eslint": "8.14.0",
"eslint-config-next": "12.1.5",
"typescript": "4.6.3"
}
}
ここから linaria を動かすためのパッケージと、webpack/babel のパッケージを追加していきます。
linaria の導入
linaria 関連パッケージの追加
次に linaria を追加していきます。
ここでは2つのパッケージを追加します。
$ yarn add linaria@3.0.0-beta.18 next-linaria@1.0.0-beta
今回は linaria の version 3 を使用したかったため、 @3.0.0-beta.18
でバージョン指定しています。
next-linaria の linaria@3 に対応しているバージョンは @1.0.0
です。
next-linaria の設定
next-linaria のREADME.md を参考に設定を追加します。
今回はあとから設定を追加する際にわかりやすいよう、 Next.js の設定と linaria の設定のオブジェクトを分けて記述しました。
/** @type {import('next').NextConfig} */
const withLinaria = require('next-linaria')
const nextConfig = {
reactStrictMode: true,
}
const linariaOption = {}
module.exports = withLinaria({
...nextConfig,
linaria: linariaOption,
})
next-linaria のドキュメントに書かれている手順としては以上です。
linaria の使用
さっそく linaria を使用してスタリングを記述してみましょう。
import { styled } from "@linaria/react"
const P = styled.p`
font-size: 30px;
`
const Home: NextPage = () => {
return (
...
<P>
Styled by linaria.
</P>
...
)
}
これで上手くいくでしょうか?
Cannot find module エラー
現段階では動かず、エラーとなるはずです。
筆者の場合は以下のエラーが発生しました。
$ yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
error - Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error
Cannot find module '@linaria/webpack-loader'
Require stack:
...
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
@linaria/webpack-loader がないと言われるので、次のステップで追加します。
Webpack の設定
パッケージのインストール
さて、ないよと言われた @linaria/webpack-loader を追加します。
$ yarn add -D @linaria/webpack-loader
これで動くでしょうか。
Cannot find module エラー
現段階ではまだエラーとなります。
$ yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
error - ./pages/_app.tsx
Error: Cannot find module '@babel/core'
Require stack:
...
今度は @babel/core がないと言われていますね。
こちらも次のステップで追加します。
Babel の設定
パッケージのインストール
どんどん追加していきます。
$ yarn add -D @linaria/webpack-loader
これでどうでしょうか。
構文エラー
まだエラーとなるんですね。
yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
error - ./pages/_app.tsx:2:12
Syntax error: Unexpected token, expected "from"
1 | import '../styles/globals.css'
> 2 | import type { AppProps } from 'next/app'
| ^
3 |
4 | function MyApp({ Component, pageProps }: AppProps) {
5 | return <Component {...pageProps} />
ふむ、 import type
のあとに {
が来るのは間違いで、from
が正しいと言われています。
正直 import type
句を存じ上げなかったのですが TypeScript 3.8 で追加された Type-Only Imports and Exports という機能らしいです。
型のみを import するため、値として使用しようとするとコンパイルエラーを吐いていくれるようですね。
本記事での TypeScript のバージョンは 4.6.3 です。
つまり、使用している TypeScript ではサポートされているものの、なぜかコンパイルエラーが発生しているという状況です🤔
.babelrc
上記のエラーに関して、 Next.jsのプロジェクトへCSS-in-JS ライブラリ Linaria(リナリア)を導入するまでの手順 を参考に解決できました。
.babelrc
に設定を追加します。
{
"presets": ["next/babel", "linaria/babel"]
}
さて、どうでしょう、、、!!
成功🎉
これで起動が成功するはずです!
$ yarn dev
いざ localhost:3000 へ!
なんと既存のスタイルリングがぶっこわれている🤣
*.css
ファイルに寄るスタリングが効いていないですね。
しかし Styled by linaria
のスタイリングはバッチリ効いていることが確認できます。
本記事の目的は達成できたため、以上で終了とします。
もし今後 CSS ファイルによるスタイリングが必要となった場合、解決できたら記事にしたいと思います。
最後に
TypeScript 3.8 で追加された Type-Only Imports は初めて知りました。
今後も活用したいと思います。
また、 babel/webpack 周りの知識が弱々すぎて .babelrc
の設定が必要な背景を理解できずにいます、、、。
babel のプリセットとして next/babel
と linaria/babel
を有効化しているのはわかるのですが、なぜそれが必要なのか、もっというと「babel - webpack - next - typescript - linaria (linaria-next)」間の関係性がわかっていないです。
どこかで勉強したいと思います。
どなたかのお役に立てば幸いです。