CRA로 생성된 React 프로젝트의 webpack 설정파일을 자세히 알아보겠습니다. CRA로 cra-eject-example
프로젝트를 생성해줍니다.
% create-react-app cra-eject-example
명령어 한 줄로 간단하게 프로젝트를 만들었습니다. 그런데 디렉토리를 보면 어떤 설정파일도 보이지 않습니다.
그 이유는 CRA가 설정파일을 숨겼기 때문입니다. 이 또한 명령어로 설정파일을 뽑을 수 있습니다. package.json
의 스크립트를 정의하는 부분을 보면 “eject”: “react-scripts eject”
이 있습니다. 이 명령어가 설정파일을 추출하는 명령어입니다.
% npm run eject
위 명령어를 입력해서 숨겨져있던 파일을 꺼내면 config
와 scripts
폴더가 생기고 package.json
파일이 모든 dependency
와 babel
, jest
설정 코드가 드러납니다.
⚙️ Config
이 포스트에서는 webpack 설정 부분만 확인하겠습니다. webpack.config.js
에 명시되어있는 옵션 입니다.
- mode: webpack에게 현재 모드를 알려주는 옵션입니다.
- bail:
True
일 경우 첫 번째 오류를 허용합니다. 여기서는production
일 때만 허용합니다. - devtool: 어떤
source-map
을 사용할지 결정하는 부분입니다.source-map
이란 원본 코드와 빌드된 코드를 매핑 해주는 방법입니다. CRA 에서는production
일 때는source-map
,development
일 때는cheap-module-source-map
을 사용하는군요. 근데 source-map 를 넣었을 때 원본 코드가 드러나는 경우가 있어서 source map 을 안쓰는 사람도 있습니다. 또 쓰더라도source-map
의 성능이 안 좋아서source-map
대신cheap-module-source-map
를 사용하는 경우도 있습니다. - entry: 앱을 번들할 때 시작 점을 정의합니다. 배열로 받을 경우 시작시 모든 모듈이 로드됩니다. 여기서는
].filter(Boolean)
을 통해서isEnvDevelopment
부분을 모드에 따라서 제외시켰습니다. - output: 번들을 완료한 파일을 설정합니다.
path
는 파일을 저장할 경로 입니다.pathinfo
는 모듈에 관련된 내용을 주석으로 표시합니다.production
일 때는 안하는 것이 좋습니다.filename
은 번들을 완료한 파일의 이름을 정의합니다.futureEmitAssets
는webpack-5
에서 없어진다고 하니 중요하지 않아보여서 넘어 가겠습니다.chunkFilename
은 청크 파일의 이름을 정의합니다.publicPath
는 브라우저에서 참조될때 출력 파일의 공용 URL 주소를 지정합니다.devtoolModuleFilenameTemplate
은 source-map의 소스 배열을 커스터마이징 합니다.jsonpFunction
는 여러 개의 webpack이 작동할 때 충돌을 막기위해 설정합니다.globalObject
는 전역변수를 설정하는 부분입니다. 기본 값은window
입니다. - optimization:
webpack 4
부터mode
에 따라서 설정이 가능해졌습니다.minimize
는TerserPlugin
이나minimizer
에 따로 정의된plugin
을 사용해서 번들한 파일을 최소화 할지 결정합니다.minimizer
는TerserPlugin
을 커스터마이징 하거나 기본 값으로minimize
에 사용될minimizer
를 설정합니다. 여기서는TerserPlugin
커스터마이징과OptimizeCSSAssetsPlugin
을 추가해서 사용했네요.splitChunks
는 청크 파일에서 중복되는 모듈을 모으는 역할을 합니다.runtimeChunk
를true
나 설정을 하면 런타임만 포함하는 각 진입점에 청크가 추가됩니다. - resolve: 이 옵션은 모듈을 해석하는데 관여합니다. 모듈을 해석할 때
modules
로 먼저 탐색할 폴더를 지정할 수 있습니다.extensions
로.ts
,.jsx
와 같은 확장자를 관리할 수 있습니다. 여기서는paths.js/moduleFileExtensions
로 관리하고 있습니다.alias
는 모듈에 별명을 주어서 간단하게import
,require
를 할 수 있습니다.plugins
는 모듈 해석에 대한 plugin 입니다. - resolveLoader: resolve 와 같은 속성을 갖지만 resolveLoader는 loader 모듈만 해석합니다.
- module: loader 를 설정하는 부분입니다.
strictExportPresence
는 경고 대신 에러를 보냅니다.rules
로 loader를 설정합니다. - plugins: plugin을 설정합니다.
- node: 노드 객체를 설정합니다.
true, false, empty, mock
값으로 객체를 설정할 수 있습니다.true
는 polyfill 을 제공합니다.false
는 어떤 것도 반환하지 않습니다.empty
는 빈 객체,mock
은 mock 객체를 반환합니다.
자세한 내용이나 추가 옵션은 webpack 공식 사이트에서 확인해주세요.
🏗 Build
다음으로 eject로 생긴 scripts
폴더의 build.js
를 봅시다. 아래는 build.js 의 함수 실행 순서 입니다.
checkBrowsers()
: 브라우저를 체크합니다.measureFileSizesBeforeBuild()
: 빌드 전 build 폴더의 크기를 계산합니다.emptyDirSync()
: build 폴더를 비웁니다.copyPublicFolder()
: 비워진 build 폴더에 public 폴더를 복사합니다.build()
: 빌드를 진행합니다.
이런 식으로 빌드를 진행하고나면 마지막으로 상태를 로그에 찍고 마무리 합니다. scripts/build.js
나 config/webpack.config.js
를 살펴보니 create-react-app
으로 만들어도 .env
환경 변수 파일로 어느정도 설정을 할 수 있게 해놓았네요. 또 eject 를 사용할 때 조심해야할 부분이 있습니다. 바로 한번 eject 를 진행하면 eject 하기 전으로 되돌리지 못한다는 점 입니다. 그때 그때 상황에 따라 webpack 설정을 해주시면 될 것 같습니다. 감사합니다.