Closed14

Vite + React + Eslint(airbnb) + Prettier + Stylelint + Emotion + Storybook の開発環境構築メモ

warugakiwarugaki

#.editorconfigの追加

# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
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

warugakiwarugaki

Eslint の導入

npm i -D eslint

Eslint |airbnbスタイルガイドを追加

npx eslint --init

コンソール対話式で選択していく

不要なルールを削除
※airbnbでReactのルールをほぼカバーできると思っているのと、今後はなくなるらしいw

    "extends": [
-       "plugin:react/recommended",
        "airbnb"
    ],

ルールの追加

https://www.npmjs.com/package/eslint-config-airbnb

    "extends": [
        "airbnb",
+      "airbnb/hooks"
    ],

lint のテスト実行

npx eslint . --ext .js,.jsx,.ts,.tsx

エラーがでるので、lint —fixの実行

npx eslint --fix . --ext .js,.jsx,.ts,.tsx 

いくつかは、自動修正むりなので手動でなおす

- vite.config.jsをeslintの対象外にする

更新:2021/12/05
除外ファイルではなくルールを追加して回避:

  overrides: [
    {
      files: ['**/vite.config.js'],
      rules: {
        'import/no-extraneous-dependencies': 'off',
      },
    },
  ],
  • react v17.x からimport reactがいらないため無効化

ルールの追加
.eslintrc.json

  "rules": {
+    "react/react-in-jsx-scope": "off"
  }
  • コンポーネントはアロー関数で書く様に

ルールを追加

  "rules": {
    "react/react-in-jsx-scope": "off",
    "react/function-component-definition": [
      "error",
      {
        "namedComponents": "arrow-function" //"function-declaration" | "function-expression" | "arrow-function"
      }
    ]
  }

手動で修正
App.jsx

const App = function () {const App = () => {
<button type="button" onClick={() => setCount((count) => count + 1)}><button type="button" onClick={() => setCount((count + 1)}>

これにてエラー解消!!

未使用のインポートを検知できるように

npm i -D eslint-plugin-unused-imports
  "plugins": [
    "react",
+  "unused-imports"
  ],
  rules: {
    'react/react-in-jsx-scope': 'off',
    'react/function-component-definition': [
      'error',
      {
        namedComponents: 'arrow-function', // "function-declaration" | "function-expression" | "arrow-function"
      },
    ],
    'no-unused-vars': 'off', // or "@typescript-eslint/no-unused-vars": "off",
    'unused-imports/no-unused-imports': 'error',
    'unused-imports/no-unused-vars': [
      'warn',
      {
        vars: 'all',
        varsIgnorePattern: '^_',
        args: 'after-used',
        argsIgnorePattern: '^_',
      },
    ],
  },

npm scripts の追加

    "lint:eslint": "eslint --ignore-path .gitignore . --ext .js,.jsx",
    "fix:eslint": "eslint --fix --ignore-path .gitignore . --ext .js,.jsx"
warugakiwarugaki

Emotionの導入

インストール

npm i @emotion/react
npm i -D @emotion/babel-plugin

vite.config.js にBabelの設定を追加

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react({
      jsxImportSource: '@emotion/react',
      babel: {
        plugins: ['@emotion/babel-plugin'],
      },
    }),
  ],
});

settings.json

{
  "emmet.includeLanguages": {
    "typescriptreact": "css",
    "javascriptreact": "css"
  }
}

公式ドキュメント

https://emotion.sh/docs/@emotion/react

VsCodeの拡張機能をインストールする

以下の拡張機能で Syntax highlighting と cssの補完がきくようになる

https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components

warugakiwarugaki

DEMOコード

Demo.jsx

import { css } from '@emotion/react';

const style = css`
  & {
    color: #333;
  }

  p {
    font-size: 14px;
  }

  @media (min-width: 1024px) {
    p {
      font-size: 28px;
      color: #aaa;
      transition: opacity 0.3s ease-out;
    }

    p:hover {
      opacity: 0.5;
    }
  }
`;

const Demo = () => (
  <div className="demo" css={style}>
    <p>Demo</p>
  </div>
);

export default Demo;

warugakiwarugaki

Prettierの導入

npm i -D prettier eslint-config-prettier

ルールを追加

.prettierrcを作成して以下を追加

{
  "singleQuote": true,
  "trailingComma": "all"
}

Eslintとprettierの競合ルールを無効化

.eslintrc.jsに追加する

extends: [
///省略
    'prettier',
  ],

VSCode保存時にフォーマットが実行されるように

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
///省略
}

npm scripts の追加

    "format:check": "prettier --check --ignore-path .gitignore './**/*.{js,jsx,json,css}'",
    "format:fix": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,json,css}'",
warugakiwarugaki

Stylelintの導入

インストール

npm i -D stylelint stylelint-config-recess-order stylelint-config-standard postcss-syntax @stylelint/postcss-css-in-js stylelint-config-prettier

Stylelintのルールを追加
.stylelintrc

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-recess-order",
    "stylelint-config-prettier"
  ],
  "rules": {},
  "overrides": [
    {
      "files": [
        "**/*.jsx",
        "**/*.tsx"
      ],
      "rules": {
      },
      "customSyntax": "@stylelint/postcss-css-in-js"
    }
  ]
}

npm scriptsを追加

    "lint:stylelint": "stylelint ./src/**/*.{css,jsx}",
    "fix:stylelint": "stylelint --fix ./src/**/*.{css,jsx}"
warugakiwarugaki

VSCodeの設定

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  "css.validate": false,
  "scss.validate": false,
  "stylelint.validate": ["css", "javascriptreact", "typescriptreact"]
}

warugakiwarugaki

Storybookの導入

npx sb init
npm i -D eslint-plugin-storybook

Storybookの導入|storybookのeslintの導入

npx sb@next automigrate

対話式で選択[y]

自動で追加される

extends: [
・・・
  'plugin:storybook/recommended',
],

手動で追加

./eslintrc.js
overrides: [
///省略
    {
      files: ['**/*.stories.*'],
      rules: {
        'react/jsx-props-no-spreading': 'off',
      },
    },
  ],

Storybookの導入|storybookのbabel設定を追加

この設定をしないとemotionがエラーで動作しない

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

上記だと Introduction.stories.mdx がコンパイルエラーになるので
webpackの設定でmdx は対象外にしてemotionが動作するように

.storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  framework: '@storybook/react',
  webpackFinal: (config) => {
    config.module.rules.push({
      test: /\.(js|jsx)$/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-react',
                { runtime: 'automatic', importSource: '@emotion/react' },
              ],
            ],
            plugins: ['@emotion/babel-plugin'],
          },
        },
      ],
    });
    return config;
  },
};

上記だとstorybookのアドオンがうまく動作しないので、
css props が機能するようにした

.storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  framework: '@storybook/react',
  babel: async (options) => ({
    ...options,
    presets: [...options.presets, '@emotion/babel-preset-css-prop'],
  }),
};
warugakiwarugaki

開発環境のアップデート

  • Eslintのルール見直し
    • import/order
      • airbnb入れているなら不要かも・・・
  • vscode 設定 stylelint.validate
    • postcss を追加する
このスクラップは2021/12/30にクローズされました