LoginSignup
6
3

More than 1 year has passed since last update.

Next.js + TypeScriptの環境構築(ツール導入編)

Last updated at Posted at 2022-03-13

はじめに

Next.js で環境構築する機会があったのでメモとしてまとめます。
なるべく一般的なライブラリ選定やその設定などにして汎用性を持たせることを意識しました。
その際、エラーが出ることもあったので解消方法も書きました。
一部主観で選定している部分もあるので、一つの参考としてご覧いただければと幸いです。

前提

JavaScript のコードフォマットについて

今回、JavaScript のコードフォーマットは Prettier は使用せず JavaScript Standard Style を使用します。
一般的なスタイルを使用したほうが良いと考えているのとツールを増やしたくないためです。

CSS

スタイルは今回 CSS Modules を使用します。
Next.js で標準サポートされているから、というのは大義で、個人的に CSS in JS を使用するよりも CSS は CSS(Sass) として書いたほうがメリットを感じているためです。

環境

以下は導入時点での各パッケージのバージョンです。
パッケージのメジャーアップデートが発生している場合は破壊的な変更がないか各パッケージの Release note をよくご確認ください。

  • Node.js v16.14.0
  • npm v8.3.1
  • yarn v1.22.4
  • Next.js v12.1.0
  • TypeScript v4.5.5
  • sass v1.49.8
  • eslint v8.9.0
  • stylelint v14.5.3
  • jest v27.5.1
  • husky v7.0.4
  • lint-staged v12.3.5

今回は CLI のコマンドは yarn を使って実行していきます。
npm コマンドを使用したい方は適宜読み替えてください。

Next.js のインストール

公式サイト:Basic Features: TypeScript | Next.js
今回は TypeScript 版でインストールします。
まずはインストールしたいディレクトリへ移動します。

cd [インストールしたいディレクトリ]

次に Next.js(TypeScript 版)をインストールします。

bash
npx create-next-app@latest --ts
# or
yarn create next-app --typescript

CLI 上でプロジェクト名を質問されるので任意の名前を入力して Enter を押します。
※ 入力したものがディレクトリ名になってその配下に Next.js のディレクトリ・ファイル群が作成されます。

What is your project named? › my-app

しばらくすると Next.js のインストールが完了します。
インストール完了後、試しに起動してみます。

bash
yarn dev

以下がCLIで表示されたら実際にブラウザのアドレスバーに http://localhost:3000を 入力して Enter を押して確認します。

ready - started server on 0.0.0.0:3000, url: http://localhost:3000

「 Welcome to Next.js! 」と表示されたページが開かれれば成功です。

Sassのインストール

公式サイト:Basic Features: Built-in CSS Support | Next.js

次に Sass をインストールします。

bash
yarn add -D sass

インストール後、Sass が動作するか試しに変えてみます。
Home.module.css を scss ファイルに変更します。

bash
mv styles/Home.module.css styles/Home.module.scss

pages/index.tsx のインポートを css ファイルから scss ファイルに変更します。

pages/index.tsx
- import styles from '../styles/Home.module.css'
+ import styles from '../styles/Home.module.scss'

styles/Home.module.scss の内容を Sass 独自の書き方に変更します。

変更前

styles/Home.module.scss
.title a {
  color: #0070f3;
  text-decoration: none;
}

.title a:hover,
.title a:focus,
.title a:active {
  text-decoration: underline;
}

変更後

styles/Home.module.scss
.title a {
  color: #0070f3;
  text-decoration: none;

  &:hover,
  &:focus,
  &:active {
    text-decoration: underline;
  }
}

エラーが出ず title のリンクをホバー時に下線が表示されれば正常に動作しています。

ESLintの設定

公式サイト:Basic Features: ESLint | Next.js

ESLint は Next.js v11.0.0 以降では標準実装されています。
以下を実行して動作することを確認します。

bash
yarn lint

実際には next lint コマンドを実行しています。
Next.js では eslint コマンドを実行するとエラーになってしますようなので、今回は next lint を ESLint の実行コマンドとして使用します。
Next.js として .eslintrc.json に書かれている ESLint の設定は以下です。

.eslintrc.json
{
  "extends": "next/core-web-vitals"
}

React としての設定をするため、 ESLint を改めて初期化します。

bash
yarn create @eslint/config

CLI 上でいくつか質問されるので答えていきます。

? How would you like to use ESLint? … 
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

「構文チェック」「問題の発見」「スタイル強制」をすべておこないたいので、カーソルキーで一番下の項目を選んで Enter キーを押します。

? What type of modules does your project use? … 
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

モジュールのインポート形式には import/export を選択します。

? Which framework does your project use? … 
❯ React
  Vue.js
  None of these

今回は React を選択します。

? Does your project use TypeScript? › No / Yes

TypeScript を使用するので Yes を選択します。

? Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
  Node

Browser を選択します。

? How would you like to define a style for your project? … 
❯ Use a popular style guide
  Answer questions about your style

ポピュラーなスタイルガイドを選択します。

? Which style guide do you want to follow? … 
  Airbnb: https://github.com/airbnb/javascript
❯ Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google
  XO: https://github.com/xojs/eslint-config-xo

Standard を選択します。

? What format do you want your config file to be in? … 
❯ JavaScript
  YAML
  JSON

JavaScript を選択します。

Checking peerDependencies of eslint-config-standard@latest
? The style guide "standard" requires eslint@^7.12.1. You are currently using eslint@8.9.0.
  Do you want to downgrade? › No / Yes

パッケージの依存関係の都合上、 ESLint をダウングレードする必要がある場合に上記の表示が出ます。 Yes を選択します。

The config that you've selected requires the following dependencies:

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest eslint-config-standard@latest eslint@^7.12.1 eslint-plugin-import@^2.22.1 eslint-plugin-node@^11.1.0 eslint-plugin-promise@^4.2.1 || ^5.0.0 @typescript-eslint/parser@latest
? Would you like to install them now with npm? › No / Yes

必要なパッケージの一覧が表示されインストールしたいか聞かれるので Yes を選択します。
インストールが完了したら以下のファイルが作成されます。

.eslintrc.json
module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: [
    'plugin:react/recommended',
    'standard'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  plugins: [
    'react',
    '@typescript-eslint'
  ],
  rules: {
  }
}

ここで改めて yarn lint を実行します。

bash
yarn lint

すると以下のエラーが出ます。

./pages/_app.tsx
4:15  Error: Missing space before function parentheses.  space-before-function-paren
5:10  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope

./pages/api/hello.ts
8:32  Error: Missing space before function parentheses.  space-before-function-paren

./pages/index.tsx
8:5  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
9:7  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
10:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
11:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
12:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
15:7  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
16:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
17:22  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
20:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
22:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
25:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
26:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
27:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
28:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
31:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
32:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
33:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
36:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
40:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
41:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
44:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
48:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
49:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
56:7  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
57:9  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
63:11  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope
64:13  Error: 'React' must be in scope when using JSX  react/react-in-jsx-scope

info  - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Error: 'React' must be in scope when using JSX react/react-in-jsx-scope というエラーは、 React v17 からは JSX を使っているファイルに import React from 'react' を書かなくても OK になったようです。
しかし ESLint で plugin:react/recommended を指定していると JSX で import React from 'react' が無いとエラーになってしまってしまうようです。
ESLint のこのエラーは検知しなくても良さそうです。
.eslintrc.js'react/react-in-jsx-scope': 'off', を追加して無効にします。

.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: [
    'plugin:react/recommended',
    'standard'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  plugins: [
    'react',
    '@typescript-eslint'
  ],
  rules: {
    'react/react-in-jsx-scope': 'off', // 追加
  }
}

参考:React v17 create-react-app で作ったアプリで ESLint に怒られまくった

Error: Missing space before function parentheses. は関数括弧の前にスペースがないためなので、スペースを追加します。

pages/_app.tsx( MyApp の後にスペースを追加)

pages/_app.tsx
function MyApp ({ Component, pageProps }: AppProps) {

pages/api/hello.ts( handler の後にスペースを追加)

pages/api/hello.ts
export default function handler (

改めて yarn lint を実行します。

bash
yarn lint

エラーがすべて出なくなっていれば OK です。
VSCode で自動でフォーマットするようにしたい場合、拡張機能の追加と .vscode/settings.json ファイルを作成します。

拡張機能

.vscode/settings.json ファイルを作成します。

bash
mkdir .vscode
touch settings.json

.vscode/settings.json ファイルには以下を書きます。

.vscode/settings.json
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.defaultFormatter": "standard.vscode-standard",
  "eslint.format.enable": false,
  "editor.formatOnSave": true,
  "editor.lineNumbers": "on",
  "editor.rulers": [80],
  "editor.wordWrap": "on",
  "eslint.packageManager": "yarn",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,
  "npm.packageManager": "yarn",
  "typescript.enablePromptUseWorkspaceTsdk": true
}

上記を保存すると ESLint でエラーになる部分に赤の下線が表示され、保存するとフォーマットを調整できるものは自動で調整してくれます。

参考:

next.config.js.eslintrc.js を開くと1行目に赤い下線が表示され以下のようなエラーが出るかと思います。

Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: next.config.js.
The file must be included in at least one of the projects provided.

これは主にファイルがどこからも import されていない場合に表示されるエラーです。
.eslintignore ファイルを作成して対象ファイルを記述します。
まずは .eslintignore ファイルの作成します。

bash
touch .eslintignore

.eslintignore ファイルには以下を記述します。

.eslintignore
/.eslintrc.js
/next.config.js

これで赤い下線が出なければOKです。

stylelintの設定

公式サイト:Getting started | Stylelint

今回は scss ファイルを対象にするので以下をインストールします。

bash
yarn add -D stylelint stylelint-config-standard-scss

次に .stylelintrc ファイルを作成します。

bash
touch .stylelintrc

.stylelintrc には以下を記述します。

.stylelintrc
{
  "extends": "stylelint-config-standard-scss"
}

package.json に以下を追加します。

package.json
"scripts": {
    // 省略
    "stylelint": "stylelint '**/*.scss'"
  },

実際にコマンドを実行してみます。

bash
yarn stylelint

すると Next.js の作成時に自動で作成されたファイルでエラーが出るのでエラーを確認しながらエラーを解消していきます。

styles/Home.module.scss
 64:14  ✖  Expected newline after ":" with a            declaration-colon-newline-after       
           multi-line declaration                                                             
 64:21  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 64:29  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 64:31  ✖  Expected quotes around "Lucida Console"      font-family-name-quotes               
 64:45  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 64:47  ✖  Expected quotes around "Liberation Mono"     font-family-name-quotes               
 64:62  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 64:64  ✖  Expected quotes around "DejaVu Sans Mono"    font-family-name-quotes               
 65:5   ✖  Expected quotes around "Bitstream Vera Sans  font-family-name-quotes               
           Mono"                                                                              
 65:29  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 65:31  ✖  Expected quotes around "Courier New"         font-family-name-quotes               
 65:42  ✖  Expected newline after "," in a multi-line   value-list-comma-newline-after        
           list                                                                               
 96:3   ✖  Unexpected longhand value '0 0 1rem 0'       shorthand-property-no-redundant-values
           instead of '0:0 1rem'

エラー部分に赤い下線を表示させたいのと自動修正してほしいので拡張機能の追加と.vscode/settings.jsonに設定していきます。

拡張機能:stylelint

.vscode/settings.json に以下を追加します。

.vscode/settings.json
{
  "editor.codeActionsOnSave": {
    // 省略
    "source.fixAll.stylelint": true
  },
  // 省略
  "stylelint.validate": ["css", "scss"],
  "scss.validate": false,
  "css.validate": false,
}

設定できたら styles/Home.module.scss を開いて保存します。
おそらくすべてのエラーが解消したかと思います。もしエラーがまだ残っているようなら手動で修正していきます。

参考:Stylelint(14系)をSCSSとVSCodeに導入する2022

プロパティも自動で並び替えしてほしいので、ファイル保存時に自動でプロパティを並び替えてくれるライブラリをインストールします。
並び替えのライブラリはいくつかありますが、今回は stylelint-config-property-sort-order-smacss というライブラリにします。

bash
yarn add -D stylelint-order stylelint-config-property-sort-order-smacss

.stylelintrc を以下に書き換えます。

.stylelintrc
{
  "extends": [
    "stylelint-config-standard-scss",
    "stylelint-config-property-sort-order-smacss"
	]
}

参考:GitHub - hudochenkov/stylelint-order: A plugin pack of order related linting rules for Stylelint.

改めて stylelint のコマンドを実行します。

bash
yarn stylelint

すると順番についてのエラーが出ます。

styles/Home.module.scss
   8:3  ✖  Expected "flex" to come before "padding" in group "box"                    order/properties-order
   9:3  ✖  Expected "display" to come before "flex" in group "box"                    order/properties-order
  12:3  ✖  Expected "align-items" to come before "justify-content" in group "box"     order/properties-order
  20:3  ✖  Expected "justify-content" to come before "border-top" in group "box"      order/properties-order
  21:3  ✖  Expected "align-items" to come before "justify-content" in group "box"     order/properties-order
  27:3  ✖  Expected "align-items" to come before "justify-content" in group "box"     order/properties-order
  28:3  ✖  Expected "flex-grow" to come before "align-items" in group "box"           order/properties-order
  45:3  ✖  Expected "font-size" to come before "line-height" in group "text"          order/properties-order
  56:3  ✖  Expected "font-size" to come before "line-height" in group "text"          order/properties-order
  61:3  ✖  Expected "border-radius" to come before "background" in group "border"     order/properties-order
  62:3  ✖  Expected "padding" to come before "border-radius" in group "box"           order/properties-order
  64:3  ✖  Expected "font-family" to come before "font-size" in group "text"          order/properties-order
  79:3  ✖  Expected "flex-wrap" to come before "justify-content" in group "box"       order/properties-order
  87:3  ✖  Expected "color" to come before "text-align" in group "text"               order/properties-order
  89:3  ✖  Expected "border" to come before "text-decoration" in group "border"       order/properties-order
  91:3  ✖  Expected "transition" to come before "border-radius" in group "animation"  order/properties-order
  92:3  ✖  Expected "max-width" to come before "transition" in group "box"            order/properties-order
  99:3  ✖  Expected "border-color" to come before "color" in group "border"           order/properties-order
 121:5  ✖  Expected "flex-direction" to come before "width" in group "box"

styles/Home.modules.scss ファイルを開いて保存すると自動で順番が並び変わります。
改めて stylelint のコマンドを実行します。

bash
yarn stylelint

エラーは出なくなったかと思います。
おっと、 globals.css が scss ファイルになっていませんでした。
scss ファイルへ変換して stylelint のコマンドを実行しましょう。

scss ファイルへ変換します。

bash
mv styles/globals.css styles/globals.scss

pages/_app.tsx で読み込んでいるのでインポート元のパスを変更します。

pages/_app.tsx
import '../styles/globals.scss' // cssをscssに修正

stylelint のコマンドを実行します。

bash
yarn stylelint

ファイルの中身をまだ変更していなければ以下のエラーが出ます。

styles/globals.scss
 4:3   ✖  Expected "margin" to come before "padding" in group "box"  order/properties-order         
 5:14  ✖  Expected newline after ":" with a multi-line declaration   declaration-colon-newline-after
 5:29  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 5:49  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 5:51  ✖  Expected quotes around "Segoe UI"                          font-family-name-quotes        
 5:59  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 5:67  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 6:11  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 6:22  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 6:24  ✖  Expected quotes around "Fira Sans"                         font-family-name-quotes        
 6:33  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 6:35  ✖  Expected quotes around "Droid Sans"                        font-family-name-quotes        
 6:45  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after 
 6:47  ✖  Expected quotes around "Helvetica Neue"                    font-family-name-quotes        
 6:61  ✖  Expected newline after "," in a multi-line list            value-list-comma-newline-after

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

styles/globals.scss を開いて保存し、改めて stylelint のコマンドを実行します。

bash
yarn stylelint

エラーが出なくなれば OK です。

Jest の設定

公式サイト:Setting up Jest (with the Rust Compiler)

Jest を使用するのに必要なパッケージをインストールします。

bash
yarn add --dev jest @testing-library/react @testing-library/jest-dom

jest.config.js を作成します。

bash
touch jest.config.js

jest.config.js に以下を記述します。

jest.config.js
const nextJest = require('next/jest')

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

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

module.exports = createJestConfig(customJestConfig)

jest.config.js にエラーが出ているので .eslintignore に以下を追加します。

.eslintignore
/jest.config.js

typescript-eslint の GitHub で「 TypeScript プロジェクトでは no-undeflint ルールを使用しないことを強くお勧めします。」とあり、実際にこの後のテストコードで書く test()expect() がエラーになるので回避する設定をおこないます。

.eslintrc.js に以下を追加します。

.eslintrc.js
rules: {
    // 省略
    "no-undef": "off"
  }

参考:I get errors from the no-undef rule about global variables not being defined, even though there are no TypeScript errors

package.json に Jest の実行コマンドを記述します。

package.json
"scripts": {
    // 省略
    "test": "jest"
  },

これで設定が整いました。
次にテストするファイルとテストコードを作成します。

sum.ts
export default function sum (a: number, b: number) {
  return a + b
}
module.exports = sum
sum.test.ts
import sum from './sum'

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3)
})

Jest のコマンドを実行します。

bash
yarn test

問題なく動作してテストが通っていれば OK です。

Storybook の設定

公式サイト:React 向け Storybook のチュートリアル | Storybook Tutorials

Storybook のパッケージを追加します。

bash
npx -p @storybook/cli sb init

しばらくすると ESLint プラグインをインストールするか聞かれるので y を押します。

We've detected you are not using our eslint-plugin.

In order to have the best experience with Storybook and follow best practices, we advise you to install
eslint-plugin-storybook.

More info: https://github.com/storybookjs/eslint-plugin-storybook#readme

? Do you want to run the 'eslintPlugin' fix on your project?

プロジェクトのルートフォルダーに .env という名前で、以下の内容のファイルを作成します。

.env
SKIP_PREFLIGHT_CHECK=true

Storybook を以下のコマンドで起動します。

bash
yarn storybook

http://localhost:6006/ で Storybook を起動できたら成功です。

試しにESLint, stylelint を実行して問題ないか確認します。

bash
yarn lint
yarn stylelint

stylelint で以下のエラーが出る場合があります。

TypeError: Class extends value undefined is not a constructor or null

このエラーが出た場合、postcss を明示的にインストールしておく必要があります。
執筆時点での最新版として postcss v8.4.7 をインストールします。

bash
yarn add -D postcss@8.4.7

改めて yarn stylelint を実行します。

bash
yarn stylelint

エラーが出なければ OK です。
スナップショットテスト機能を実装します。
必要なパッケージをインストールします。

bash
yarn add -D @storybook/addon-storyshots react-test-renderer

src/storybook.test.js ファイルを以下の内容で作成します

src/storybook.test.js
import initStoryshots from '@storybook/addon-storyshots'
initStoryshots()

テストしてみます。

bash
yarn test
console.error
      Unexpected error while loading ./Introduction.stories.mdx: Cannot use import statement outside a module
       Jest encountered an unexpected token
      
      Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
      
      Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
      
      By default "node_modules" folder is ignored by transformers.
      
      Here's what you can do:
       • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
       • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
       • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
       • If you need a custom transformation specify a "transform" option in your config.
       • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
      
      You'll find more details and examples of these config options in the docs:
      https://jestjs.io/docs/configuration
      For information about custom transformations, see:
      https://jestjs.io/docs/code-transformation
      
      Details:
      
      /Users/user/Documents/web/nextjs-example/stories/Introduction.stories.mdx:1
      ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { Meta } from '@storybook/addon-docs';
                                                                                        ^^^^^^
      
      SyntaxError: Cannot use import statement outside a module
          at new Script (node:vm:100:7)
          at Runtime.createScriptFromCode (/Users/user/Documents/web/nextjs-example/node_modules/jest-runtime/build/index.js:1728:14)
          at Runtime._execModule (/Users/user/Documents/web/nextjs-example/node_modules/jest-runtime/build/index.js:1596:25)
          at Runtime._loadModule (/Users/user/Documents/web/nextjs-example/node_modules/jest-runtime/build/index.js:1185:12)
          at Runtime.requireModule (/Users/user/Documents/web/nextjs-example/node_modules/jest-runtime/build/index.js:1009:12)
          at Runtime.requireModuleOrMock (/Users/user/Documents/web/nextjs-example/node_modules/jest-runtime/build/index.js:1210:21)
          at requireContext (/Users/user/Documents/web/nextjs-example/node_modules/@storybook/babel-plugin-require-context-hook/register.js:29:12)
          at /Users/user/Documents/web/nextjs-example/node_modules/@storybook/core-client/dist/cjs/preview/executeLoadable.js:77:29
          at Array.forEach (<anonymous>)
          at /Users/user/Documents/web/nextjs-example/node_modules/@storybook/core-client/dist/cjs/preview/executeLoadable.js:75:18

Introduction.stories.mdx でエラーが出たようです。
mdx ファイルはテスト不要なので無視する設定をおこないます。
以下のファイルを作成します。

bash
mkdir -p .jest/__mocks__
touch .jest/__mock__/mdx.ts

.jest/mocks/mdx.ts に以下を追加します。

.jest/**mocks**/mdx.ts
export default ''

jest.config.js に以下を追加します。

jest.config.js
const customJestConfig = {
  // 省略
  moduleNameMapper: {
  "\\.(mdx)$": "<rootDir>/.jest/__mocks__/mdx.ts"
  },
}"

参考:StorybookのStoryshots入れるだけでやたら手こずった

もう一度テストコマンドを実行します。

bash
yarn test

エラーが出なくなったらOKです。

husky/lint-staged の設定

公式サイト:GitHub - okonet/lint-staged: 🚫💩 — Run linters on git staged files

husky と lint-staged をインストールします。

bash
npx mrm@2 lint-staged

package.json に以下を追加します。

package.json
{
  "scripts": {
    //省略
    "lint-staged": "lint-staged"
  },
  "lint-staged": {
    "*.{ts,tsx}": "eslint --cache --fix",
    "*.scss": "stylelint --syntax=scss --fix"
  },
}

ついでに npm scripts を整理しておきます。

npm-run-all をインストールします。

bash
yarn add -D npm-run-all

lint のコマンドを整理します。

package.json
{
  "scripts": {
    // 省略
    "lint": "run-p lint:*",
    "lint:eslint": "next lint",
    "lint:stylelint": "stylelint '**/*.scss'",
  }
}

参考:GitHub - mysticatea/npm-run-all: A CLI tool to run multiple npm-scripts in parallel or sequential.

さいごに

以上で Next.js * TypeScript の環境でツールを導入する方法を終わります。
ディレクトリ構成等、他にも環境構築に必要なことはありますが、別の機会で記事にしたいと思います。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3