본문 바로가기

WEB개발/REACT

이React, Vite, Typescript 참고, 오류

 

Window객체 확장

 

declare global 구문을 사용하면 브라우저의 window 객체를 확장하는 인터페이스를 정의할 수 있습니다. TypeScript에서 Window 인터페이스는 전역 window 객체를 나타내므로, 이 인터페이스를 확장하면 브라우저 환경에서 window 객체에 새로운 속성을 추가할 수 있습니다.

declare global {
  interface Window {
    myCustomProperty: string;
    myCustomFunction: () => void;
  }
}

// window 객체에 새로운 속성을 추가
window.myCustomProperty = "Hello, world!";
window.myCustomFunction = () => {
  console.log("Custom function called!");
};

// 사용 예제
console.log(window.myCustomProperty); // "Hello, world!"
window.myCustomFunction(); // "Custom function called!"
 

declare global 구문을 사용하면 브라우저의 window 객체를 확장하는 인터페이스를 정의할 수 있습니다. TypeScript에서 Window 인터페이스는 전역 window 객체를 나타내므로, 이 인터페이스를 확장하면 브라우저 환경에서 window 객체에 새로운 속성을 추가할 수 있습니다.

 

 

 


 

` prettier --write` 명령어

 

prettier --write 명령어는 파일을 자동으로 포맷하고 변경 사항을 저장(덮어쓰기)하는 명령어입니다.

 

 

prettier --write "src/**/*.{js,ts,jsx,tsx}"
prettier --write --parser babel index.js

 


 

 Vite와 TypeScript의 Alias 설정은 동일하게 맞추는 것이 좋다!

  • Vite의 alias → 번들링(Bundling) 시 적용
  • TypeScript의 paths → 트랜스파일링(Transpiling) 시 적용

즉, 서로 다르게 설정하면 모듈 해석 방식이 달라져서 충돌 가능성이 높아지므로, 같은 alias를 동일하게 설정하는 것이 가장 안전한 방법입니다.

 


 

ESM(ES Modules) vs CJS(CommonJS) 개념 정리

 

ESM (ECMAScript Modules) CJS (CommonJS)
import/export 문법 사용

브라우저 및 최신 Node.js 환경에서 사용 가능

비동기 로드(호이스팅 지원, 최적화 가능)
require/module.exports 문법 사용

Node.js에서 기본 지원
(하지만 브라우저에서는 직접 실행 불가능)

동기 로드(실행 순서가 중요함)

 

 

CSR (브라우저 실행)

  • 브라우저에서 실행되므로 기본적으로 ESM 사용.
  • import 문법으로 모듈을 로드함.

 

SSR (Node.js 실행)

  • Node.js에서는 기본적으로 CJS 방식(require())을 사용.
  • 하지만, ESM 전용 패키지를 사용하려면 추가 설정이 필요함.
  • Vite 같은 번들러에서는 ssr.noExternal 설정을 통해 해결 가능.
 
SSR에서 ESM 패키지 사용하려면?
  • package.json에 "type": "module" 추가
  • tsconfig.json에 "moduleResolution": "NodeNext" 설정
  • Vite 사용 시 ssr.noExternal 옵션 추가
 

 

-Vite에서 SSR을 사용할 때 기본적으로 node_modules에 있는 대부분의 패키지를 외부 모듈(external)로 설정합니다.

-Vite뿐만 아니라 Webpack, Rollup, esbuild 같은 번들러들도 기본적으로 node_modules를 외부 모듈(external)로 설정하는 경우가 많습니다.


=> 이유는 번들 크기를 줄이고 성능을 최적화하기 위해서입니다.

여러 프로젝트나 페이지가 동일한 외부 라이브러리(예: React, Vue, lodash 등)를 사용할 때, 각 번들에 라이브러리를 포함시키지 않고 외부에서 로드하면 중복된 코드를 제거할 수 있습니다.

 

Vite의 경우 특정 외부모듈을 번틀링 설정할 수 있음

import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [reactRouter(), tsconfigPaths()],
  optimizeDeps: {
    include: ["@mui/material", "@mui/icons-material"],
  },
  ssr: {
    noExternal: ["@mui/material", "@mui/icons-material"], // MUI 관련 패키지 번들링 포함
  },
});

 

 


 

리엑트의 상태와 재랜더링 (useState, useEffect)

usState의 상태값

기본적으로 `set[State]` 함수는 항상 같은 참조값을 유지

 

1. 기본 타입 (number, string, boolean, null, undefined)

  • 상태 값이 변하지 않으면 참조 값도 변하지 않음 → 리렌더링이 발생하지 않음.
  • 상태 값이 변하면 새로운 값으로 대체됨 → 리렌더링 발생.

2. 객체, 배열, 함수 ({}, [], () => {})

  • 상태 값이 새로운 객체(배열, 함수)로 변경되면 참조값이 변경됨 → 리렌더링 발생.
    => 안의 변경사항이 없이 다시 set하다러도 새로운 객체가 할당됨으로 참조값이 변경됨
  • React는 은 비교(shallow comparison)를 사용해서 기존 객체와 다른 새 객체가 생성되면 리렌더링을 트리거함.

 

React의 상태 업데이트 최적화 방식과 의존성 배열(deps)이 상태 변화에 미치는 영향 때문

export default function Home() {
    const [count, setCount] = useState(0);
    const input = { mbrNo: "0909" };

    setCount(1); // ❌ 렌더링 중 상태 업데이트 → 무한 루프 발생 🚨

    return (
        <>
            <p>hello</p>
            <button onClick={() => setCount(0)}>init</button>
        </>
    );
}

 

React는 렌더링 중에 setState를 호출하면 즉시 다시 렌더링을 트리거함.

 

useEffect활용

useEffect(() => {
    setCount(1);
    console.log("useEffect....");
}, [input]);

 

❓ 왜 무한 루프가 발생하지 않을까?

  • 여기서 핵심은 setCount(1);이 실행되더라도 React가 상태가 변하지 않았다고 판단하면 리렌더링을 하지 않기 때문

 

‼ React에서는 useEffect 내부에서 사용된 외부 변수 의존성 배열([])에 포함되지 않으면 경고

'WEB개발 > REACT' 카테고리의 다른 글

VITE  (0) 2025.03.17
[환경구성] React개발을 위한 유용한 노드모듈 (node_modules)  (0) 2025.02.14
[환경구성] tsconfig.js, tsc  (0) 2025.02.13
[React] Next, Typescript... 오류모음  (0) 2024.01.26
[React] web성능 메트릭  (0) 2023.12.18