Closed8

Next.js の環境構築

Kenta WatashimaKenta Watashima

https://zenn.dev/higa/articles/d7bf3460dafb1734ef43

まずは、プロジェクトの作成

$ mkdir ${project_dir}
$ cd ${project_dir}
$ yarn create next-app .

--examples with-typescript で bootstrap するのもよいが、不要なものもたくさんついてくるので、今回は使わない

ベースディレクトリの変更

$ mkdir src && \
  mv pages/ src/pages & \
  mv styles/ src/styles
Kenta WatashimaKenta Watashima

TypeScript を入れる

$ yarn add -D typescript @types/react @types/react-dom @types/node

TS ファイルに変換

$ find src/pages -name "_app.js" -or -name "index.js" | sed 'p;s/.js$/.tsx/' | xargs -n2 mv & \
  find src/pages/api -name "*.js" | sed 'p;s/.js$/.ts/' | xargs -n2 mv

開発サーバを起動して tsconfig.json を生成

$ yarn dev

src/pages/_app.tsx を修正

src/pages/_app.tsx
import React from 'react';
import { AppProps } from 'next/app';
import '../styles/globals.css';

function MyApp({ Component, pageProps }: AppProps): JSX.Element {
  return <Component {...pageProps} />;
}

export default MyApp;

src/pages/index.tsx を修正

src/pages/index.tsx
import React from 'react';
import { NextPage } from 'next';
import Head from 'next/head';
import styles from '../styles/Home.module.css';

const Home: NextPage = () => {
  return (
    // ...
  );
};

export default Home;

src/pages/api/ は使わないので削除

$ rm -rf src/pages/api/
Kenta WatashimaKenta Watashima

_document.tsx の追加

$ code src/pages/_document.tsx
src/pages/_document.tsx
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';

const url = '';
const title = '';
const description = '';

class MyDocument extends Document {
  render() {
    return (
      <Html lang="ja-JP">
        <Head>
          <meta charSet="utf-8" />
          <meta name="description" content={description} />
          <meta property="og:type" content="website" />
          <meta property="og:title" content={title} />
          <meta property="og:url" content={url} />
          <meta property="og:description" content={description} />
          <meta property="og:site_name" content={title} />
          <meta property="og:image" content={`${url}/og_image.png`} />
          <meta name="twitter:card" content="summary_large_image" />
          <meta name="format-detection" content="telephone=no" />
          <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

_document.tsx に Viewport meta tags や title を置くと怒られる[1][2]ので、_app.tsx も下記に変更しておく

src/pages/_app.tsx
import React from 'react';
import { AppProps } from 'next/app';
import Head from 'next/head';
import 'styles/globals.css';

function MyApp({ Component, pageProps }: AppProps): JSX.Element {
  return (
    <>
      <Head>
        <title />
        <meta name='viewport' content='width=device-width, initial-scale=1' />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;
脚注
  1. https://github.com/vercel/next.js/blob/master/errors/no-document-title.md ↩︎

  2. https://github.com/vercel/next.js/blob/master/errors/no-document-viewport-meta.md ↩︎

Kenta WatashimaKenta Watashima

ベース URL を src に変更

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "src"
  }
}
$ sed -i '' -e 's/..\/styles/styles/' src/pages/_app.tsx & \
  sed -i '' -e 's/..\/styles/styles/' src/pages/index.tsx
Kenta WatashimaKenta Watashima

EditorConfig の追加

$ code .editorconfig
.editorconfig
# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
Kenta WatashimaKenta Watashima

Prettier, ESLint の追加
2021 年 1 月現在、eslint-plugin-prettier は Prettier 公式で非推奨とされているので、使わない

https://prettier.io/docs/en/integrating-with-linters.html

$ yarn add -D eslint eslint-plugin-react eslint-config-prettier prettier & \
              @typescript-eslint/parser @typescript-eslint/eslint-plugin
.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/react',
    'prettier/@typescript-eslint',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: ['react', '@typescript-eslint'],
  rules: {},
};
.prettierrc.js
module.exports = {
  semi: true,
  singleQuote: true,
};
Kenta WatashimaKenta Watashima

Sass のインストール

$ yarn add -D sass
$ find src/styles -name "*.css" | sed 'p;s/.css$/.scss/' | xargs -n2 mv
$ sed -i '' -e 's/\.css/\.scss/' src/pages/_app.tsx & \
  sed -i '' -e 's/\.css/\.scss/' src/pages/index.tsx

Sass 記法(.sass)は stylelint が対応していない[1]っぽいので、SCSS で進める

sanitize.css のインストール

$ yarn add sanitize.css
src/pages/_app.tsx
import 'sanitize.css'

stylelint のインストール

$ yarn add -D stylelint stylelint-config-standard stylelint-config-recess-order

Prettier と stylelint の競合問題が面倒なので、この二つは併用しない

.stylelintrc.js
module.exports = {
  extends: ['stylelint-config-standard', 'stylelint-config-recess-order'],
  ignoreFiles: ['**/node_modules/**'],
};
脚注
  1. https://github.com/stylelint/stylelint/issues/1685 ↩︎

このスクラップは2021/01/21にクローズされました