Next-TypeScriptのアプリ作成（mui, storybook, eslint, prettier, translation）

# Next app

how to create project with TypeScript, Next, eslint, prettier, Storybook, Mui and translation

1. create Next app
2. eslint
3. prettier
4. vscode setting
5. test
6. storybook
7. mui
8. translation

## reference
https://zenn.dev/hungry_goat/articles/b7ea123eeaaa44

https://dev-yakuza.posstree.com/react/nextjs/typescript/

## environment Version
Node 16.16.0
npm 8.11.0

## 1. create Next app

1 create your app

```
npx create-next-app --typescript [project-name]
```

2 show your app

```
npm run dev
```

## 2. eslint

edit `./.eslintrc.json` file

```
{
  "extends": [
    "next/core-web-vitals",
    "plugin:import/recommended",
    "plugin:import/warnings",
    "prettier"
  ],
  "rules": {
    "import/order": [
      "error",
      {
        "alphabetize": {
          "order": "asc"
        }
      }
    ],
    "semi": ["error", "always"]
  }
}
```

more about [eslint](https://eslint.org/)

## 3. prettier

1 install prettier

```
npm install --save-dev prettier
```

2 edit `./.prettierrc` file

```
{
  "trailingComma": "all",
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true,
  "jsxSingleQuote": true,
  "printWidth": 100
}
```

3 edit `script` of `./package.json` file

```
"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint --dir src",
    "lint:fix": "yarn lint --fix",
    "format": "prettier --check --ignore-path .gitignore .",
    "format:fix": "prettier --write --ignore-path .gitignore .",
  },
```

more about [prettier](https://prettier.io/docs/en/)

## 4. VsCode setting

If you change VsCode setting, you can align format when you save
you need vscode extension([eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode))

1. open `settings.json` file
open command palette(mac : `cmd` + `shift` + `p`/ windows : `ctrl` + `shift` + `p`)
type `settings.json`
choose `Open User Settings(JSON)`
2. add settings
   (add setting tab size of typescript)

```
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "[typescript]": {
    "editor.tabSize": 2
  },
  "[typescriptreact]": {
    "editor.tabSize": 2
  }
}
```

## 5. test

1 install Jest and React Testing Library

```
npm install --save-dev jest @testing-library/react @testing-library/jest-dom jest-environment-jsdom
```

2 create `./jest.setup.js`

```
// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`

// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect';
```

3 create `./jest.config.js`

```
const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  moduleDirectories: ['node_modules', '<rootDir>/'],
  testEnvironment: 'jest-environment-jsdom',
};

module.exports = createJestConfig(customJestConfig);
```

4 create `./tests/index/index.test.tsx`

```
import { render, screen } from '@testing-library/react';

import Home from '../../pages/index';

describe('Home', () => {
  it('renders a heading', () => {
    const { container } = render(<Home />);

    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js!/i,
    });

    expect(heading).toBeInTheDocument();

    expect(container).toMatchSnapshot();
  });
});
```

5 edit `script` of `./package.json` file

```
"scripts": {
    (...)
    "test": "jest --watch",
    "test:ci": "jest --ci",
```

6 test

```
npm test
```

## 6. storybook

1 install storybook

```
npm install --save-dev sb
```

2 init storybook

```
npx sb init --builder webpack5
```

3 edit `script` of `./package.json` file

```
"scripts": {
    (...)
    "storybook": "start-storybook -p 6006 -s ./public",
    "build-storybook": "build-storybook -s public"
```

4 show storybook

```
npm run storybook
```

more about [storybook](https://storybook.js.org/docs/react/get-started/introduction)

## 7. mui

install mui and emotion

```
npm install --save @mui/material @emotion/react @emotion/styled
```

more about [mui](https://mui.com/)

## 8. translation

1 install next/translation

```
npm install --save next-translate
```

2 edit `./next.config.js` file
   add this

```
const nextTranslate = require('next-translate');

module.exports = nextTranslate();
```

3 create `./i18n.json` file

```
{
  "locales": ["ja", "en"],
  "defaultLocale": "en",
  "localeDetection": false,
  "pages": {
    "*": ["common"]
  }
}
```

4 create `./locales/en/common.json` file

```
{
  "Japanese": "Japanese",
  "English": "English",
}
```

5 create `./locales/ja/common.json` file

```
{
  "Japanese": "日本語",
  "English": "英語",
}
```

6 use translation
   like this

```
import useTranslation from 'next-translate/useTranslation';
...
const { t } = useTranslation('common');
...
{t('Japanese')}
```