Setting to create React Project

React 개발 ν™˜κ²½ μ„ΈνŒ…

πŸš€ κΈ°λ³Έ ν™˜κ²½ μ„ΈνŒ…

ν”„λ‘œμ νŠΈ 폴더 생성

mkdir [proeject name]
cd [proeject name]

npm global μ„€μΉ˜

npm install -g npm

node version μ„ΈνŒ…

node --version > .node-version

npm μ΄ˆκΈ°ν™”

npm init -y

πŸš€ Typescript μ„€μΉ˜ 및 μ„€μ •

npm i -D typescript

Typescript μ„€μ • 파일 생성

npx tsc --init

tsconfig.json νŒŒμΌμ—μ„œ jsx ν•­λͺ© μˆ˜μ •

{
  "jsx": "react-jsx"
}

πŸš€ ESLint μ„€μΉ˜ 및 μ„€μ •

npx eslint --init

$ > To check syntax, find problems, and enforce code style
$ > JavaScript modules (import/export)
$ > React
$ > Yes(TypeScript)
$ > Browser
$ > Use a popular style guide
$ > XO
$ > JavaScript
$ > Yes
$ > npm

Airbnb μŠ€νƒ€μΌ μ μš©ν•˜κΈ°(optional)

TypeScriptμ—μ„œ Airbnb μ§€μ›ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, 기쑴에 μ„€μΉ˜ν•œ XOλ₯Ό μ‚­μ œν•˜κ³  Airbnb μŠ€νƒ€μΌμ„ μ μš©ν•œλ‹€.

npm uninstall eslint-config-xo
npm uninstall eslint-config-xo-typescript

npm i -D eslint-config-airbnb
npm i -D eslint-plugin-import
npm i -D eslint-plugin-react
npm i -D eslint-plugin-react-hooks
npm i -D eslint-plugin-jsx-a11y

# install by one line
npm i -D eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y

.eslintrc.js 파일 μˆ˜μ •

module.exports = {
  env: {
    browser: true,
    es2021: true,
    jest: true, // jest 섀정은 미리 ν•΄λ‘ 
  },
  extends: [
    'airbnb',
    'plugin:@typescript-eslint/recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['react', 'react-hooks', '@typescript-eslint'],
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },
  rules: {
    indent: ['error', 2],
    'no-trailing-spaces': 'error',
    curly: 'error',
    'brace-style': 'error',
    'no-multi-spaces': 'error',
    'space-infix-ops': 'error',
    'space-unary-ops': 'error',
    'no-whitespace-before-property': 'error',
    'func-call-spacing': 'error',
    'space-before-blocks': 'error',
    'keyword-spacing': ['error', { before: true, after: true }],
    'comma-spacing': ['error', { before: false, after: true }],
    'comma-style': ['error', 'last'],
    'comma-dangle': ['error', 'always-multiline'],
    'space-in-parens': ['error', 'never'],
    'block-spacing': 'error',
    'array-bracket-spacing': ['error', 'never'],
    'object-curly-spacing': ['error', 'always'],
    'key-spacing': ['error', { mode: 'strict' }],
    'arrow-spacing': ['error', { before: true, after: true }],
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: [
          '**/*.test.js',
          '**/*.test.jsx',
          '**/*.test.ts',
          '**/*.test.tsx',
        ],
      },
    ],
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],
    'react/jsx-filename-extension': [
      2,
      {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    ],
    'jsx-a11y/label-has-associated-control': ['error', { assert: 'either' }],
  },
};

prettier 좩돌 λ°©μ§€(optional)

npm install --save-dev eslint-config-prettier

.eslintrc.js 파일 μˆ˜μ •

extends: [
  'airbnb',
  'plugin:@typescript-eslint/recommended',
  'plugin:react/recommended',
  'plugin:react/jsx-runtime',
  'prettier',
],

.eslintignore 파일 생성

/node_modules/
/dist/
/.parcel-cache/

πŸš€ React μ„€μΉ˜

npm i react react-dom
npm i -D @types/react @types/react-dom

src 폴더 생성

mkdir src

App.tsx 파일 생성: ./src/App.tsx

export default function App() {
  return <div>Hello, world!</div>;
}

main.tsx 파일 생성: ./src/main.tsx

import ReactDOM from 'react-dom/client';

import App from './App';

function main() {
  const element = document.getElementById('root');

  if (!element) {
    return;
  }

  const root = ReactDOM.createRoot(element);

  root.render(<App />);
}

main();

index.html 파일 생성: ./index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="./src/main.tsx"></script>
  </body>
</html>

πŸš€ Parcel μ„€μΉ˜ 및 μ„€μ •

npm i -D parcel

parcel-reporter-static-files-copy μ„€μΉ˜

npm install -D parcel-reporter-static-files-copy

.parcelrc 생성: ./.parcelrc

{
  "extends": ["@parcel/config-default"],
  "reporters":  ["...", "parcel-reporter-static-files-copy"]
}

static folder 생성: ./static

  • ν”„λ‘œμ νŠΈ root path 에 static 폴더 생성

  • 정적 이미지 λ“± μ €μž₯ 폴더

mkdir static

package.json μˆ˜μ •

main μ‚­μ œ ν›„ μ•„λž˜μ˜ μ½”λ“œ μΆ”κ°€

"source": "./index.html",

scripts 속성 μˆ˜μ •(*jestλŠ” μΆ”ν›„ μ„€μΉ˜)

"scripts": {
  "start": "parcel --port 8080",
  "build": "parcel build",
  "check": "tsc --noEmit",
  "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx .",
  "test": "jest",
  "coverage": "jest --coverage --coverage-reporters html",
  "watch:test": "jest --watchAll"
},

πŸš€ ν”„λ‘œμ νŠΈ ꡬ동 ν…ŒμŠ€νŠΈ

# 둜컬 μ‹€ν–‰
npm run start

# λΉŒλ“œ
npx parcel build

# 정적 μ„œλ²„ μ‹€ν–‰
npx servor ./dist

πŸš€ Jest 와 React Testing Library μ„€μΉ˜

npm i -D jest @types/jest
npm i -D @swc/core @swc/jest jest-environment-jsdom
npm i -D @testing-library/react @testing-library/jest-dom@5.16.4

jest.config.js: ./jest.config.js

module.exports = {
  // ν…ŒμŠ€νŠΈ ν™˜κ²½ μ„€μ •
  testEnvironment: 'jsdom',

  // Jestλ₯Ό μ‹€ν–‰ν•˜κΈ° μ „ μ„€μ • 파일
  setupFilesAfterEnv: ['<rootDir>/src/jest.setup.js'],

  // 트랜슀파일러 μ„€μ •
  transform: {
    '^.+\\.(t|j)sx?$': [
      '@swc/jest',
      {
        jsc: {
          parser: {
            syntax: 'typescript',
            jsx: true,
            decorators: true,
          },
          transform: {
            react: {
              runtime: 'automatic',
            },
            legacyDecorator: true,
            decoratorMetadata: true,
          },
        },
      },
    ],
  },
};

jest.setup.js 파일 생성: ./src/jest.setup.js

  • 일단 μƒμ„±λ§Œ 해두고, λ‚˜μ€‘μ— ν•„μš”ν•  λ•Œ μ½”λ“œ μΆ”κ°€

eslintrc.js 파일 μˆ˜μ •

module.exports = {
  env: {
    browser: true,
    es2021: true,
    jest: true, // μΆ”κ°€(이전 μ„€μ •μ—μ„œ 미리 ν•΄λ‘μ—ˆμ§€λ§Œ ν•œ 번 더 확인)
  },
  ...
}

ν…ŒμŠ€νŠΈ ꡬ동 ν…ŒμŠ€νŠΈ

npm run test

# μ•„λž˜μ™€ 같이 ν˜„μž¬ λ§Œλ“€μ–΄μ§„ ν…ŒμŠ€νŠΈ 파일이 μ—†λ‹€κ³  λ‚˜μ˜€λ©΄ μ™„λ£Œ
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /.../workspace/react-project
  9 files checked.
  testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
  testPathIgnorePatterns: /node_modules/ - 9 matches
  testRegex:  - 0 matches
Pattern:  - 0 matches

Last updated