3월 넷째 주 TWIL : webpack - 엔트리/아웃풋

윤슬기·2020년 3월 29일
1

TWIL

목록 보기
32/32
post-thumbnail

부트캠프에서는 시간 내에 우선 움직이는 결과물을 만드는 게 중요하니, 항상 Create React App을 이용해서 자동으로 개발환경을 세팅했다. 그리고는 그 안의 내용물을 뜯어보지 않았었는데, 포트폴리오 사이트를 다시 한번 CRA로 만들면서 번들과 컴파일러가 어떻게 돌아가는지 궁금해졌다. 관련 키워드로 정보를 찾아보니 매우 적절한 강의 '프론트엔드 개발환경의 이해와 실습'이 인프런에 있어 등록했다. 한 주간 강의를 따라가며 공부하고 실습한 내용을 간략하게 정리했다.


개발 환경과 Node.js

CRA같은 도구를 사용하면 세팅이 편하지만, 프로젝트별로 필요한 개발 환경이 다르기에 그를 이루는 도구들을 알아두어야 한다. 사용하는 도구들은 상당 부분 Node.js 환경에서 돌아가므로 그에 대한 지식을 갖추자.

최신 스펙으로 개발하기

프론트엔트 개발 환경의 발전은 매우 빠르다. 그러나 브라우저는 상대적으로 느리게 기술 스펙을 지원한다. 그래서 최신 기술들을 사용하려면 그 둘을 이어주는 웹팩이나 바벨 같은 도구를 사용해야 한다. 이런 징검다리 역할을 하는 도구들은 대부분 Node.js 환경에서 돌아간다. TypeScript, Sass 등을 변환하는 트랜스파일러 역시 마찬가지다.

빌드 자동화

요즘 개발 환경에서는 순수하게 작성한 코드만을 배포하지 않고, 코드를 압축, 난독화하거나 polyfill을 더하는 등 추가적인 작업을 거친 후 배포하게 된다. 이 작업을 자동화한 도구들에는 Node.js가 많이 사용된다. 더불어 라이브러리 다운로드, 테스트 자동화 등에도 사용된다.

npm의 역할

외부 패키지 사용하기

개발에 사용하는 여러 도구는 다양한 방법으로 가져올 수 있다. CDN(콘텐츠 전송 네트워크)으로 배포된 라이브러리 주소를 script 태그를 이용해 삽입하거나, 주소에 링크된 파일에 들어 있는 내용을 수동으로 다운받거나 모두 복사해 파일 안에 붙여넣을 수도 있다.

<!-- React 라이브러리 파일을 script 태그로 가져오기 -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>

하지만 이 경우 서버 장애가 발생하면 라이브러리를 읽어올 수 없고, 라이브러리의 버전이 업데이트되어 새로운 코드를 다시 사람이 일일이 다운받거나 복사해온다면 그 과정에서 실수가 발생할 확률이 높다.

npm은 package.json의 정보를 토대로 신뢰할 수 있는 소스에서 자동으로 라이브러리 파일을 받아 설치한다. npm은 라이브러리의 버전 숫자와 그 앞에 표기된 '~' 혹은 '^'과 같은 약속된 기호들을 토대로 설치할 라이브러리 버전을 판단한다.

모듈

기본적으로 웹서비스에 필요한 파일들은 HTML 문서에서 script 태그를 이용해 모두 불러온다. 이 때 파일 구성에 따라 불러오는 순서를 염두에 두어야 한다.

// math.js
function sum(a, b) {
  return a + b;
}
// app.js
console.log(sum(1, 2));

math.js에 값을 더하여 반환하는 함수 sum이 들어있고, app.js에서 그 함수를 사용한다면 아래와 같은 순서로 파일을 불러온다.

<body>
  <script src="src/math.js"></script>
  <script src="src/app.js"></script>
</body>

여기서 불러오는 코드들은 전역에 선언되어 있다. 즉 math.js의 함수 sumwindow.sum이다. 그러므로 프로젝트 규모가 커질수록 변수명을 중복으로 선언하게 되거나, 변수에 값을 재할당하는 일이 일어날 수 있어 안전하지 않다.

IIFE 방식 모듈

함수를 정의하자마자 실행하는 즉시실행함수(IIFE)를 통해 함수 안에 독립적 스코프를 만들고, 그 안에서 필요한 함수와 변수들을 선언한다. 그리고 다른 모듈과 구분하기 위해 전역에 선언한 네임스페이스 - 여기서는 math - 에 그 함수와 변수들을 등록해 활용한다. IIFE 안에서 선언한 이름들은 그 안에서만 유효하기에 함수 바깥에서 해당 변수에 접근할 수 없고, 같은 변수명을 사용해도 충돌이 일어나지 않는다.

// math.js
// math가 있으면 할당하고 없으면 빈 객체를 하나 할당한다.
var math = math || {};

(function() {
  function sum(a, b) {
    return a + b;
  }

  // 전역에 있는 객체 math에 함수 sum을 할당해서,
  // 전역에서 함수 sum에 접근할 수 있는 수단을 부여한다
  math.sum = sum;

})();
// app.js
console.log(math.sum(1, 2));

다양한 모듈 스펙

자바스크립트에서 모듈 시스템을 정의하고 사용하고자 하는 커뮤니티인 AMD(비동기로 JS코드가 로딩되는 환경에서 모듈을 사용하기가 목표), CommonJS(자바스크립트를 사용하는 모든 환경에서 모듈을 사용하기가 목표), UMD(AMD와 CommonJS를 모두 지원하기가 목표)등에서 각자의 모듈 스펙들을 지원, 제안하다가 ES2015에서 표준 모듈 시스템을 내놓았다. exportimport로 모듈을 내놓고 가져와 사용하는 형태이다.

// math.js
// ES2015 모듈 시스템을 지원하는 브라우저에서 사용가능
export function sum(a, b) { return a + b; }
// app.js
// ES2015 모듈 시스템
import { sum } from './math.js';

sum(1, 2);
<!-- index.html -->
<!-- app.js에서 math.js를 읽어오므로 app.js만 로딩하고, type 속성을 module로 지정 -->
<!-- ES2015 모듈 시스템을 지원하는 브라우저에서 동작한다 -->
<script type="module" src="src/app.js"></script>

최신 브라우저에서는 script태그에 type="module" 속성을 지정하여 모듈 시스템을 사용할 수 있지만, 모듈 시스템을 지원하지 않는 브라우저들에서도 모듈을 사용하고 싶다면 웹팩과 같은 번들러가 필요하다.

webpack

모듈끼리 연결된 모습을 '의존 관계에 있다'라고 표현한다. 예를 들어 app.js가 math.js를 import하여 사용할 때 두 파일 간에 의존성이 생긴다. 웹팩은 의존관계에 있는 여러 자바스크립트 파일을 하나로 합쳐준다. 그렇게 하나로 합쳐진 파일을 '번들'이라 하며, 웹팩은 '번들러'라고 불린다.

webpack 설정파일 작성

번들링에 필수적인 정보는 mode, entry, ouput 세 가지이다. 정보를 명령어로 CLI 상에서 모두 입력하여 번들링 할 수 있지만, 번들링 시마다 입력하기는 번거로우므로 설정 파일을 만들어 파일 안에 필요한 정보를 입력해 사용한다.

설정 파일은 프로젝트의 root에 webpack.config.js 혹은 webpackfile.js라는 이름으로 파일을 생성하면 번들링 시에 웹팩이 설정 파일을 바로 읽는다. 혹은 다른 위치에 생성하고 --config 명령으로 경로를 설정해 주어도 된다.

// nodejs의 path 모듈
const path = require('path');

module.exports = {
  mode: 'development',
  // 모듈을 어디서부터 읽을지를 지정한다
  entry: {
    main: './src/app.js',
  },
  // 번들링을 마친 결과 파일을 어디에 저장할지, 파일명을 무엇으로 할지 지정한다
  output: {
    // 저장할 곳. 절대경로를 입력한다
    // nodejs의 path 모듈을 사용한다. 입력한 경로를 문자열로 바꿔주는 메서드
    path: path.resolve('./dist'),
    // 파일명. entry에서 설정한 키값이 name으로 들어간다.
    // entry가 한 개가 아니라 여러개인 경우가 있으므로, 이런 식으로 설정하면 동적으로 파일명을 부여할 수 있다.
    filename: '[name].js',
  }
}

node_modules/.bin/webpack 명령을 CLI로 입력하면 번들링이 실행되지만, 위와 마찬가지로 매번 입력하기 번거로우므로 package.json에 따로 script를 설정하자. 값에 들어가는 경로에 node_modules/ 를 적지 않아도 npm이 node_modules폴더 안에서 입력한 문자열 webpack을 찾아 실행한다.

"scripts": {
  "build": "webpack"
},

script에 지정한대로 npm run build 를 입력하면 웹팩 설정 파일에 지정한 dist폴더 안에 번들 main.js가 생긴다. index.html에서 /dist/main.js 파일을 script 태그로 가져와 브라우저에 띄워보면 이전과 같은 결과를 확인할 수 있다.

profile
👩🏻‍💻

0개의 댓글