webpack에서 typescript tsconfig 다중으로 설정하기

May 27, 2020

프로젝트로 typescript와 react로 전환을 준비중에 있습니다. 프로젝트가 pc 및 mobile을 모두 대응해야 했고, 각자의 target이 달라 각 디바이스별로 tsconfig를 분리해서 진행해야 하는 이슈가 있습니다. (실제로 IE 하위 버전을 대응하기 위해서는 typescript target을 ES3로 가져가야 하는 이슈가 있었고, mobile은 이보다 높은 ECMAScript 버전 지원이 필요했습니다.)

tsconfig의 경우 IDE에 적용되는 tsconfig는 project root에 존재하는 tsconfig.json하나를 바라보고 있었고, webpack으로 구성된 프로젝트를 변형하지 않으면서 최대한 typescript를 반영해야 했습니다.

이번 포스팅은 저와 비슷한 이슈가 있는 경우, 각 빌드 환경별 ts-loader 를 이용하여 tsconfig.json 을 다중으로 설정하는 방법에 대해서 포스팅 하고자 합니다.

concepts

하나의 tsconfig - 두개의 빌드 환경

IDE상에서는 개발 환경에 대응될 수 있어야 하고, 실제 빌드되는 환경에서는 각 환경에 맞게 세팅하고자 합니다. 빌드 예시를 들어보겠습니다.

src
	- m
		- main.ts
	- pc
		- main.ts
config
	- tsconfig.m.json
	- tsconfig.pc.json
webpack.config.js
tsconfig.json

root에 IDE 등 개발 시에 공통의 configuration을 위한 tsconfig.json 이 위치해 있고, 실제 config 폴더내에는 m/main.ts 를 빌드하기 위한 tsconfig.m.json , pc/main.ts 를 빌드하기 위한 tsconfig.pc.json 이 위치하고 있습니다.

tsconfig 설정

tsconfig.m.json , tsconfig.pc.json 은 root에 위치해 있는 tsconfig.json 을 extends 할 수 있습니다.

root의 tsconfig부터 보겠습니다.

{
  "compilerOptions": {
    // leave JSX as it is
    "jsx": "react",
    // resolve modules as you would expect
    "moduleResolution": "node",
    "types": ["jest", "node", "react", "react-dom", "react-redux"],
    "module": "commonjs",
    // do not transpile stuff like classes, async/await, ...
    "target": "es5",
    "lib": [
      "es2015", "es6", "esnext", "dom"
    ],
    "allowJs": true,
    "baseUrl": ".",
    "allowSyntheticDefaultImports": true,
    "keyofStringsOnly": true,
    "skipLibCheck": true,
    "noImplicitAny": false
  },
  ...
}

다른 프로젝트에서 설정하는 tsconfig.json과 다르지 않습니다. 이제, 각 디바이스별 tsconfig에서는 root의 tsconfig.json을 extends 라는 property를 사용하여 extends 합니다.

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "outDir": "dist",
    "sourceMap": true,
	  ...
  },
}

root에 있는 tsconfig를 extends 라는 property로 확장받을 수 있으며, 이 tsconfig를 확장하여 다른 옵션으로 오버라이딩이 가능합니다.

webpack 설정하기

ts-loader 내에 option중, configFile 옵션을 이용하여 빌드 환경별 tsconfig를 바라보도록 설정합니다.

{
	module: {
		rules: [
			{
				test: /\.ts$/,
				use: [{
					loader: 'ts-loader',
					options: {
						configFile: './config/tsconfig.m.json',
					}
				}]
			}
		]
	}
}

Mobile 빌드를 위해 configFile을 tsconfig.m.json으로 설정하거나, tsconfig.pc.json으로 설정합니다. 이때, 각 환경별로 포함시킬 파일들은 tsconfig 파일 내 include 옵션에 정의하여 각 빌드별 파일을 분기하여 사용 가능합니다.

tsconfig내 extends를 이용한 확장은 굳이 webpack내 ts-loader를 사용하지 않더라도, tsc 및 기타 번들러로도 사용이 가능한 방법이니, tsconfig 분기가 필요하신 분들은 이러한 방법으로 사용 가능하지 않을까 생각합니다.

...