■P023

────────────────
https://nodejs.org/ja/
────────────────


■P024

────────────────
npm create vite@latest
────────────────

※本書で解説している環境と揃える場合は、下記のようにバージョンを指定してください
────────────────
npm create vite@^6.3.5
────────────────


■P025

────────────────
{
  "name": "my-react-app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^19.1.0",
    "react-dom": "^19.1.0"
  },
  "devDependencies": {
    "@eslint/js": "^9.25.0",
    "@types/react": "^19.1.2",
    "@types/react-dom": "^19.1.2",
    "@vitejs/plugin-react": "^4.4.1",
    "eslint": "^9.25.0",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-react-refresh": "^0.4.19",
    "globals": "^16.0.0",
    "vite": "^6.3.5"
  }
}
────────────────


■P026

────────────────
cd my-react-app
────────────────
npm install
────────────────

────────────────
npm run dev
────────────────

────────────────
http://localhost:5173/
────────────────


■P029

────────────────
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
────────────────

────────────────
createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)
────────────────

────────────────
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      <div>
        <a href="https://vite.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App
────────────────


■P031

────────────────
npm run build
────────────────


■P032

────────────────
npm run preview
────────────────


■P033

────────────────
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
  { ignores: ['dist'] },
  {
    files: ['**/*.{js,jsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...js.configs.recommended.rules,
      ...reactHooks.configs.recommended.rules,
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
  },
]
────────────────


■P034

src/App.jsx
────────────────
// import { useState } from 'react'
────────────────
※コメントアウトした状態

────────────────
npm run lint
────────────────

────────────────
npx eslint --inspect-config
────────────────


■P035

src/App.jsx
────────────────
const myHelloWorld = "Hello World";
────────────────


■P037

────────────────
    rules: {
      ...js.configs.recommended.rules,
      ...reactHooks.configs.recommended.rules,
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
────────────────

────────────────
    rules: {
      ...js.configs.recommended.rules,
      ...reactHooks.configs.recommended.rules,
      'no-unused-vars': ['off', { varsIgnorePattern: '^[A-Z_]' }],
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
────────────────


■P038

────────────────
https://code.visualstudio.com/
────────────────

────────────────
Japanese Language Pack
────────────────


■P039

────────────────
ESLint
────────────────


■P040

────────────────
npm install -D --save-exact prettier
────────────────


■P041

src/App.jsx
────────────────
function App() {
   const word1    = "Hello";
const word2 =       'wrorld'

  return (
    <h1>{word1} {word2}</h1>
)       ;
}

export default App;
────────────────

────────────────
npx prettier . --write
────────────────

src/App.jsx
────────────────
function App() {
  const word1 = "Hello";
  const word2 = "wrorld";

  return (
    <h1>
      {word1} {word2}
    </h1>
  );
}

export default App;
────────────────


■P042

────────────────
prettier
────────────────

.vscode/settings.json
────────────────
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}
────────────────


■P043

.prettierrc
────────────────
{
  "singleQuote": false,
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "printWidth": 80,
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "avoid",
  "endOfLine": "lf"
}
────────────────

────────────────
function App() {
  const word1 = "Hello";
  const word2 = "wrorld";

  return (
    <h1>
      {word1} {word2}
    </h1>
  );
}

export default App;
────────────────


■P044

────────────────
https://prettier.io/docs/en/options.html
────────────────

