콘텐츠로 이동

2023 11 30

2023-11-30

React 빌드/컴파일 과정

참고: https://velog.io/@nnoshel/react-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0 참고: https://soonysoon.tistory.com/88 참고: https://dev.classmethod.jp/articles/the-process-from-installing-react-to-distributing-it/

  • 용어
    • npm: node.js로 만들어진 프로그램을 쉽게 설치할 수 있게해주는 앱스토어 (node.js 설치시 자동으로 설치 됨)
  • npm run build
    • 빌드 완료시 build 폴더가 생성됨
    • css/js/html/image 등 정적 리소스 생성 (minify 과정도 거침)
    • 하지만 실제로 index.html 실행해서 열어보면 끝인줄 알았으나...
  • serve -s build
    • You may serve it with a static server
    • build 폴더의 정적 파일을 실행시키기 위해서는 웹서버가 필요하다
    • serve 패키지가 정적 사이트를 제공하거나, SPA를 사용하기에 좋은 초이스라고 함
  • 왜 웹서버가 필요하지?
    • index.html을 파일로 그냥 바로 열면, 다른 파일은 가져올 때 file: 프로토콜을 써
      • 근데 이 file: 프로토콜이란 친구는 AJAX, Routing 이런거 하나도 이해못해.
      • 그래서 http: 프로토콜로 해당 파일을 가져올 수 있어야 해
    • 그러다보니까.. 우리는 웹서버가 살짝 필요해지는거야.
      • nginx/apache 같은걸로도 서브할 수 있어
      • serve 같은 간단한 웹서버도 가능하고
      • SPA 라우팅, 리다이렉트 등...
        • 그저 정적파일이긴 하지만, 파일시스템에서 바로 가져다가 쓸수는 없어요
    • 해당 문제는 Client Side Rendering을 사용한다면 꼭 발생할 수 있어요
      • Angular, vue, ember etc...
      • js의 기능을 엄청많이 사용해서 DOM 갈아끼우는 방식들인데 이는 static html, css, vanilla js의 기능을 넘어서요
      • 브라우저 등에서 사용할 수 없었던 모던 JS ES6+ 기능을 많이 사용해요 (import/export)

JS 라이브러리 사용하기

  • 두가지 방법으로 사용할 수 있게 지원하기
    • npm, script형 설치
  • npm
    • npm으로 install 하면 코드베이스 거의 전체가 다 가다보니 interface로 야무지게 추출해서 제공할 수 있을 것 같고...
  • script

    • 스크립트는 이런식으로 임포트해서 가져오면, script 태그에서 쓸 수 있도록 지원받을 수 있음
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
      </head>
          <script src="path/to/YourLibrary.js"></script>
          <script>
            // Now users can use your library
            const instance = new YourLibrary.YourClass();
            YourLibrary.yourFunction();
          </script>
      </body>
      </html>
      
    • 이게 가능한 이유는 라이브러리의 클래스와 함수가 global scope로 제공되기 때문임
      • js 파일을 브라우저로 로딩하고
      • global scope에서 해당 라이브러리에 접근하고
      • YourLibrary 전역으로 정의되어 있다면, YourClass, YourFunction 직접 쓸 수 있음
    • 해당 접근 방식은 다양한 조건에서 쓸 수 있도록 함 (npm이던 script던)
      • global 변수이다보니 충돌이 나지 않도록, 같은 페이지에서 충돌나지 않도록 고려해야해.
      • global namespace가 신경쓰인다면, 모듈 번들러 (웹팩, 롤업) 신경써봐

Babel & Webpack

참고: https://velog.io/@dbsbest10/Webpack-%EA%B3%BC-Babel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C

  • 웹팩 (모듈 번들러)
    • 여러개의 파일을 하나로 합쳐주는 모듈 번들러
    • 파일 분할 기능, css loader 기능, jsx 변환 작업 등
    • 여러개로 나눠진 js 파일을 html이 실행할 수 있는 하나의 js 파일로 합쳐줌
    • 많은 파일을 다운받아와 네트워크 부하가 커지는 현상 + 같은 이름의 변수/함수 충돌 가능성 해결 위해 등장
  • 바벨 (트랜스파일러)
    • 특정 언어로 작성된 코드를 비슷한 다른 언어로 변환시키는 트랜스파일러
    • 모든 브라우저가 ES6 최신 기능을 제공하지 않기에 ES5 구기능으로 변환시키는 과정이 필요

Webpack

참고: https://wonsss.github.io/webpack/webpack-all-in-one/ 참고: https://developer-talk.tistory.com/550 참고: https://joshua1988.github.io/webpack-guide/motivation/problem-to-solve.html#%EC%9B%B9%ED%8C%A9%EC%9C%BC%EB%A1%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EB%A0%A4%EB%8A%94-%EB%AC%B8%EC%A0%9C

  • 0. 모듈
    • 어플리케이션 기능 많아질수록 기능별로 파일 분리 (모듈 == 분리된 파일)
    • JS에서 현재 모듈을 다른 모듈에서 접속가능하도록 export 키워드를 사용하고, import를 통해 분리된 모듈을 불러올 수 있음
    • node_modules만 봐도 상당히 많은 모듈이 들어가게됨
    • 모듈 종속성 : 서로다른 js 파일이 서로 다른 js 파일을 import 하게되면 에러 추적도 어려워... 병합도 어려워
  • 1. 모듈 번들러, 웹팩이란?
    • 위의 문제를 해결해 짧은 시간 최상의 성능을 위해 최적화
    • 모듈 번들러: 웹 어플리케이션을 동작시키기 위한 구성자원 (static resources)을 모두 각각의 모듈로 보고 이들의 의존성을 묶고 조합해 합친 하나의 결과물 (static 자원) 만드는 도구
    • 사용자가 웹사이트 접속시, 모든 파일 네트워크 통신으로 가져오는데, 하나하나 가져오면 느려.
    • 브라우저 HTTP 연결수도 최대 6건으로 제한. 너무 많으면 병목됨
    • 웹팩을 통해 여러 리소스를 번들링해 로딩 속도 개선
    • 웹서비스 개발 + 배포 => {HTML/CSS/JS/이미지} 압축/CSS 전처리기 변환 등 추가 작업 모두 대신해줌
    • 엔트리 포인트를 시작으로 연결되어있는 모든 모듈을 합쳐 아웃풋 포인트로 결과물 저장.
  • 2. 웹팩이 해결하고자 하는것
    • js 변수 유효범위
    • 브라우저별 http 요청 숫자의 제약
    • 사용하지 않는 코드의 관리
    • dynamic loading, lazy loading 미지원

CommonJs vs ES6

참고: https://commnetall.tistory.com/46

  • 개요
    • 둘 모두 js에서 모듈을 쓰기 위한 방식
    • 클라이언트단 프레임워크와 서버단 프레임워크 모듈을 불러오는 키워드가 다르다고 생각하면 좋음
    • 다만 둘다 js를 사용해서 혼란이 생겨버림
  • CommonJs
    • Node.js에서 모듈 불러오기 위해 require, exports 키워드 사용
    • 2009년 표준, JS 모듈을 만들기 위한 법칙.
    • 오로지 서버사이드 모듈을 만들고 불러오기 위해 개발됨
  • ES6
    • ECMA 국제기구 표준문서 스펙
    • 표준으로 만들어서 통일시키려고 ECMA 등장
    • 클라이언트가 단순한 기능넘어 클래스도 추가되어 CommonJS와 혼동
  • 코드 비교
    //CommonJS
    module.export = function || class || variable
    const modul1 = require('./example.js')
    
    //ES6
    export default module
    import module2 from './example.js'
    
  • 그럼 뭐써?
    • ES6식 모듈 권장
    • "strict mode" + ECMAScript 차기 버전 정의 문법 금지해줘서 좋음