最近は、静的なウェブサイトも、動的なウェブサイトも、デスクトップアプリもNext.jsで開発しています。
もっというと、スマホアプリもExpoを使っているのですが、ExpoはReactではあるものの、Next.jsではないので今回は除外します。
Next.jsのすべての機能をフル活用できているかというと、全然そんなことはないのですが、全てをNext.js + TypeScript + styled-components + SCSSで開発すると、プロジェクトを跨いでカスタムフックやコンポーネントの使い回しが可能なため、非常に効率的です。
また、Webpackなどで自作の開発環境を構築するよりも、他のエンジニアと共同作業しやすいので、とても助かってます。
そんなこんなで、Next.jsをセットアップする機会が多い今日この頃ですが、なんだか毎回同じコマンドを打っている気がするので、思い切って雛形を作ってみました。
それぞれブランチを分けてリポジトリにコミットしています。
今後も細かい調整を入れていくことになると思いますが、当面はこの雛形をベースに開発していこうと思う所存です。
Next.js + TypeScript + styled-components + SCSS
App Router
リポジトリ
設定した項目
styled-componentsの導入
yarn add styled-components
yarn add -D @types/styled-components
next.config.jsの設定
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { compiler: { styledComponents: { ssr: true } } }; module.exports = nextConfig;
StyledComponentsRegistryの作成
// StyledComponentsRegistry.tsx 'use client' import { ServerStyleSheet, StyleSheetManager } from 'styled-components'; import { ReactNode, useState } from 'react'; import { useServerInsertedHTML } from 'next/navigation'; export function StyledComponentsRegistry({ children }: { children: ReactNode }) { const [ styledComponentsStyleSheet ] = useState(() => new ServerStyleSheet()); useServerInsertedHTML(() => { const styles = styledComponentsStyleSheet.getStyleElement(); styledComponentsStyleSheet.instance.clearTag(); return <>{ styles }</>; }) if (typeof window !== 'undefined') { return <>{ children }</> }; return ( <StyleSheetManager sheet={ styledComponentsStyleSheet.instance }> { children } </StyleSheetManager> ); }
// layout.tsx import type { Metadata } from 'next'; import { Noto_Sans_JP } from 'next/font/google'; import { StyledComponentsRegistry } from '@/styling/StyledComponentsRegistry'; import { PageStateProvider } from '@/contexts/PageStateContext'; const noto = Noto_Sans_JP({ subsets: [ 'latin' ] }); export const metadata: Metadata = { title: 'App Router', description: 'description' }; export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="ja"> <body className={ noto.className }> <PageStateProvider> <StyledComponentsRegistry>{ children }</StyledComponentsRegistry> </PageStateProvider> </body> </html> ); }
SCSSの導入
yarn add sass
Page Router
リポジトリ
設定した項目
styled-componentsの導入
yarn add styled-components
yarn add -D @types/styled-components babel-plugin-styled-components
.babelrcの作成
// .babelrc { "presets": [ "next/babel" ], "plugins": [[ "styled-components", { "ssr": true }] ] }
_document.tsxの編集
// _document.tsx import Document, { DocumentContext } from 'next/document'; import { ServerStyleSheet } from 'styled-components'; export default class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => { return originalRenderPage({ enhanceApp: (App) => function MyDocument(props) { return sheet.collectStyles(<App {...props} />); } }); }; const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> { initialProps.styles } { sheet.getStyleElement() } </> ) }; } finally { sheet.seal(); } } }
SCSSの導入
yarn add sass
Electron
リポジトリ
設定した項目
styled-componentsの導入
yarn add styled-components
yarn add -D @types/styled-components babel-plugin-styled-components
.babelrcの作成
// .babelrc { "presets": [ "next/babel" ], "plugins": [[ "styled-components", { "ssr": true }] ] }
_document.tsxの編集
// _document.tsx import Document, { DocumentContext } from 'next/document'; import { ServerStyleSheet } from 'styled-components'; export default class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => { return originalRenderPage({ enhanceApp: (App) => function MyDocument(props) { return sheet.collectStyles(<App {...props} />); } }); }; const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> { initialProps.styles } { sheet.getStyleElement() } </> ) }; } finally { sheet.seal(); } } }
SCSSの導入
yarn add sass