WEB掻っ穿じり

WEB備忘録とチャリとカメラ

NEXT.jsのStatic Site Generatorでexportした静的サイトをサブディレクトリへデプロイして運用、Emotionも導入【備忘録】

  category:web

Web アプリで開発で React を使うことはほとんどになってきた。
案件によってはクライアントとサーバーサイドで完全に異なる環境に分けた設計、開発運営していくことも増えてきた。

Web アプリ開発以外でちょっとしたサイトの制作依頼を受けたときも TypeScript + React (CSS in JS)を使ってしばらく自分の中でスキルのスタンダードにしたい、というのもあって NEXT.js をチョイスした。

Static Site Generator(SSG)を使って依頼に対して柔軟に対応できるように、ハマったところなども加えて覚書として残しておきたい。

TypeScript を使った NEXT.js を使ったプロジェクト作成

yarn create next-app --typescript

デフォルトでは root に export されるようになっているので、 next.config.js 設定で basePath を定義していく。

SSG export のディレクトリ設定

next.config.js 設定

export 時は production になる。 assetPrefix の設定でアセットファイルと、css 内部の画像、フォント指定などもパス指定される。 publicRuntimeConfig の設定で、コンポーネントからの読み込みが可能になる。

/* デプロイ先のディレクトリ */
const DIRECTORY = "/directory";

/* 本番/開発環境、export時はproduction */
const isProduction = process.env.NODE_ENV == "production"

module.exports = {
  // 公開先と開発でディレクトリを分けるのであれば、basePathの設定
  basePath: isProduction ? DIRECTORY : "",
  // アセットファイルのパス指定 assetPrefixの設定
  assetPrefix: isProd ? DIRECTORY : "",
  // リンク/画像のパス設定 tsxコンポーネント内呼び出し用
  publicRuntimeConfig: {
    basePath: isProd ? DIRECTORY : "",
  },
}

tsx コンポーネント config を読み込み、パス指定

next/image Image は export 時に error になるので、img タグを使用。 Link タグは as を指定

import getConfig from "next/config";
import Link from "next/link";

const { publicRuntimeConfig } = getConfig();

export const SomeComponent = () => {
  const basePath = (publicRuntimeConfig && publicRuntimeConfig.basePath) || "";

  return (
    
<img src={`${basePath}/vercel.svg`} alt="Vercel Logo" /> <Link href="/about" as={`${basePath}/about`}> リンク </Link>
); }

build ファイルのディレクトリ指定

package.json の build コマンドに && next export を加え、さらに build ファイルもディレクトリ指定する場合は -o out/directory のように追記する。

 "scripts": {
    "build": "next build && next export -o out/xxxxx",
  },

CSS in JS Emotion の導入

ついでに CSS in JS の Emotion の導入も。

Emotion のパッケージと、Emotion の babel 用プラグインを導入

yarn add @emotion/react @emotion/babel-plugin

JSX プラグマ ディレクティブを追記

css prop を使うため JSX から JavaScript へのコンパイル設定。 emotion を読み込むコンポーネント毎に記述が必要。

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react"

それか Babel Condig を設定する方法がある

Babel の Config を設定

NEXT.js の roor に .babelrcを作成。

{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}

TypeScript の型定義ファイルを読み込む

TypeScript 用に Emotion の型定義ファイルも必要。

tsconfig.jsonの compilerOptions に Emotion の型定義ファイルを指定。

"compilerOptions": {
    "types": ["@emotion/react/types/css-prop"],
  }

参考