Skip to content

Latest commit

 

History

History
692 lines (508 loc) · 12.1 KB

File metadata and controls

692 lines (508 loc) · 12.1 KB

react setting

JavaScript 개발 환경 (Node.js) 셋팅

LTS(Long Term Support) 버전을 설치하고 기본으로 사용하게 한다.

$ brew install fnm
$ fnm install --lts
$ fnm use lts-latest

// Zsh 기준
$ eval "$(fnm env --use-on-cd)"

참고 : https://github.com/Schniz/fnm

설치된 상태 확인.

$ fnm list
- v18.17.1 default, lts-latest
- system

$ node -v
v18.17.1

TypeScript + React + Jest + ESLint + Parcel 개발 환경 셋팅

먼저, 적절한 작업 폴더를 준비한다.

mkdir 프로젝트명
cd 프로젝트명

프로젝트 열기

여기서 바로 Visual Studio Code를 열면 편하다.

code .

npm 패키지 작업

npm init -y

.gitignore 작업

touch .gitignore
  • 추천

    Node 검색 후 내용 .gitignore에 추가

    gitignore.io

    아래 내용이 꼭 포함되어 있는지가 중요!

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

타입스크립트 설정

npm i -D typescript

npx tsc --init

tsconfig.json 파일의 jsx 속성 변경한다. jsx 부분 열어준다.

{% hint style="info" %} npx

npm package에서 정의한 binary를 실행시키는 러너 {% endhint %}


ESLint 설정

npm i -D eslint

npx eslint --init
**? How would you like to use ESLint?**
> To check syntax, find problems, and enforce code style

**? What type of modules does your project use?
>** JavaScript modules (import/export)

**? Which framework does your project use?**
> React

**? Does your project use TypeScript?
>** Yes

? **Where does your code run?**
> Browser

? **How would you like to define a style for your project?**
> Use a popular style guide

**? Which style guide do you want to follow?**
> xo-typescript

**? What format do you want your config file to be in?**
> JavaScript

**? Would you like to install them now?**
> Yes

**? Which package manager do you want to use?**
> npm

린트 스타일 세팅

타입스크립트의 경우 ESLint 에서 에어비엔비 스타일을 지원하지 않아 XO 스타일을 제거하고 에어비엔비 스타일로 변경

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

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,
  },
  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: {
    quotes: ["error", "double", { avoidEscape: true }],
    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" }],
  },
};

.eslintignore 작성

  • .gitignore 있는것 복사 붙혀넣기

  • 아래 내용이 꼭 포함되어 있는지가 중요!

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

.vscode/settings.json 작성

mkdir .vscode
touch .vscode/settings.json
{
    "editor.rulers": [
        80
    ],
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    "trailing-spaces.trimOnSave": true
}

pacakge.json 파일에 lint 명령 추가:

{
  "scripts": {
    // ...(전략)...
    "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx ."
  }
}

React 설치

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

Jest 설치 (테스팅 도구)

bun add -d @types/jest @swc/core @swc/jest \\
    jest-environment-jsdom \\
    @testing-library/react @testing-library/jest-dom

jest.config.js 파일 작성:

touch jest.config.js
module.exports = {
  testEnvironment: "jsdom",
  setupFilesAfterEnv: [
    "@testing-library/jest-dom",
    "<rootDir>/src/setupTests.ts",
  ],
  transform: {
    "^.+\\.(t|j)sx?$": [
      "@swc/jest",
      {
        jsc: {
          parser: {
            syntax: "typescript",
            jsx: true,
            decorators: true,
          },
          transform: {
            react: {
              runtime: "automatic",
            },
            legacyDecorator: true,
            decoratorMetadata: true,
          },
        },
      },
    ],
  },
};

.eslintrc.js 파일에 설정 추가:

module.exports = {
  env: {
    // ...(전략)...
    jest: true,
  },
  // ...(후략)...
};

pacakge.json 파일에 test 명령 추가:

{
  "scripts": {
    // ...(전략)...
  "test": "jest",
    "coverage": "jest --coverage --coverage-reporters html",
    "watch:test": "jest --watchAll"
  }
}

Parcel 설치

npm i -D parcel

pacakge.json 파일에 start 명령 추가:

{
  "scripts": {
    "start": "parcel --port 8080",
    "build": "parcel build",
    "check": "tsc --noEmit",
    // ...(후략)...
  }
}

zero-configuration이지만, 2가지 정도 작업은 하는게 좋다.

  1. package.json 파일에 source 속성 추가.
"main": "index.js" // 제거
"source": "./index.html" // 그 자리에 추가
  1. parcel-reporter-static-files-copy 패키지 설치 후 .parcelrc 파일 작성.
    이렇게 하면 static 폴더의 파일을 정적 파일로 Serving할 수 있다(이미지 등 Assets).
npm i -D parcel-reporter-static-files-copy

static 안에 이미지 파일 넣으면 됨

mkdir static
touch .parcelrc

.parcelrc 파일에 작성:

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

빌드 + 정적 서버 실행 방법

npx parcel build

npx servor ./dist

HTML, JSX 준비

기본 코드 작성

  • index.html
  • src/main.tsx
  • src/App.tsx
  • src/components/Greeting.test.tsx
  • src/components/Greeting.tsx

index.html 파일 작성:

<!DOCTYPE html>
<html lang="ko">
  <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>

src/main.tsx 파일 작성:

import { createRoot } from "react-dom/client";

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

  if (!element) {
    return;
  }

  const root = createRoot(element);
  root.render(<App />);
}

main();

src/App.tsx 파일 작성:

import { createRoot } from "react-dom/client";

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

  if (!element) {
    return;
  }

  const root = createRoot(element);
  root.render(<App />);
}

main();

MSW

MSW 설치

npm i -D msw

MSW 관련 파일 생성

src/setupTests.ts, src/mocks/server.ts, src/mocks/handler.ts 파일 추가

// src/setupTests.ts 파일

import server from './mocks/server';

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));

afterAll(() => server.close());

afterEach(() => server.resetHandlers());
// src/mocks/server.ts 파일

import { setupServer } from 'msw/node';

import handlers from './handlers';

const server = setupServer(...handlers);

export default server;
// src/mocks/handlers.ts 

import {rest} from 'msw';
// import fixtures from '../../fixtures';

const BASE_URL = 'http://localhost:3000';

const handlers = [
    rest.get(`${BASE_URL}/products`, (req, res, ctx) => {
        // const { products } = fixtures; // fixtures를 사용해도 됨  
        const products = [
            {
                category: 'Fruits', price: '$1', stocked: true, name: 'Apple',
            },
        ];

        return res(
            ctx.status(200), // 없어도 됨(기본 설정이 200)
            ctx.json({products}), // 위의 요청을 이 형태로 반황 
        );
    }),
];

export default handlers;

React Router

리액트 라우터 설치

npm install react-router-dom

라우터 객체 생성

React Router 6.4버전부터 라우터 객체를 지원함. routes.tsx 파일 생성

import Layout from './components/Layout';

import HomePage from './pages/HomePage';

const routes = [
  {
    element: <Layout />,
    children: [
      { path: '/', element: <HomePage /> }
    ],
  },
];

export default routes;

styled-components

설치

  npm i [email protected]
  
  npm i -D @types/styled-components @swc/plugin-styled-components
   
  npm i styled-reset

swc 세팅

{
	"jsc": {
		"experimental": {
			"plugins": [
				[
					"@swc/plugin-styled-components",
					{
						"displayName": true,
						"ssr": true
					}
				]
			]
		}
	}
}

Axios

설치

npm i axios

usestore-ts

설치

npm i tsyringe reflect-metadata usestore-ts

의존성 셋팅

src/main.tsxsrc/setupTests.tsreflect-metadata import 해주기

tsconfig.jsonexperimentalDecoratorsemitDecoratorMetadata 속성 true 로 변경

jest.config.js 세팅 수정

CodeceptJS

CodeceptJS 설치

npx codeceptjs init

# > Where are your tests located? ./tests/**/*_test.js
# > What helpers do you want to use? Playwright
# > where should logs, screenshots, and reports to be stored? (./output) 
# > Do you want localization for tests? English (no localization)
# > [Playwright] Base url of site to be tested (http://localhost)
# > [Playwright] Show browser window n
# > [Playwright] Browser in which testing will be performed. Possible options: chromium, firefox or webkit (chromium)
# > Feature which is being tested (ex: account, login, etc)
# > Filename of a test (_test.js)

부가적인 세팅

2023년 5월 기준 CodeceptJS 문제로 에러가 발생할 수 있음. 그래서 부가적인 세팅이 필요함.

  1. 의존성 설치 npm i -D eslint-plugin-codeceptjs playwright @codeceptjs/configure
  2. codecept.conf.ts 에서 config의 타입 제거 및 수정.
  3. tests/steps.d.ts 파일 생성
  4. steps_files.js 파일 tests 폴더로 이동
  5. CodeceptJS가 내부적으로 ts-node를 쓰기 때문에 tsconfig.json 파일에 ts-node 설정을 추가
    1. /* CodeceptJS */
        "ts-node": {
          "files": true
        }
      
  6. /tests/.eslintrc.js 파일 생성
  7. .gitignoreoutput/ 추가