what is webpack?
ESmodule(import/export) 구문은 최신 브라우저에게 어떤 파일을 다운로드하고 실행할지 명시해 준다. 즉 import 구문이 많아질수록 더 많은 파일을 다운로드 해야 하고, 이는 더 많은 http request가 필요하다는 것을 의미한다.
물론 import 파일을 다운로드 하는 데에도 시간이 소요되지만, 파일을 다운로드 하기 위해 보내는 request 자체를 준비(set up)를 하는데에도 시간(base overhead)이 소요된다. 이는 dev tool > network > waterfall 그래프에서 확인할 수 있다.
실제 웹에서 다수의 http 요청을 보내는 것은 어플리케이션의 속도를 느리게 만든다. 따라서 request의 빈도를 줄이는 것이 좋고, webpack이 하는 주된 일이 바로 이것이다. 물론 웹팩은 다른 일도 한다.
- bundling | 여러 코드(파일)를 하나로 묶어서 http 요청의 개수를 줄여준다.
- compiling | ts-loader 패키지를 통해 변환 방법을 전달받고, 코드를 컴파일한다.
- code optimization | as small as possible
- 가독성을 고려해서 작성하는 코드가 최적화된 코드(as small as possible)는 아니다.
- 웹팩은 개발자가 작성한 코드를 최적화된 코드로 변환해 준다.
- 원하는 build 단계를 추가할 수 있다.
- ??? more tools | ex) css files
how to use webpack?
$ npm install --save-dev webpack webpack-cli webpack-dev-server typescript ts-loader
$ npm i -D ~
- --save-dev, -D | 어플리케이션을 개발하는 과정에서만 사용되는 툴을 설치할 때 사용하는 옵션
- webpack-cli | 해당 프로젝트에서 웹팩 명령어를 실행하기 위해 필요한 패키지
- webpack-dev-server | 웹팩에 내장되어 있는 개발용 서버로, 컴파일된 파일을 토대로 웹 페이지를 보여준다.
- typescript
- typescript가 이미 global option으로 설치되어있더라도, 프로젝트 폴더 내부에서 다시 한번 설치하는 것이 좋다.
- global에서 typescript를 새로운 버전으로 설치하더라도, 프로젝트 폴더에 따로 설치된 typescript은 영향을 받지 않기 때문이다. 즉, 프로젝트에서 사용되는 ts의 버전이 고정된다.
- +) typescript를 설치하면 tsc 명령어도 사용 가능
- ts-loader | 웹팩과 함께 동작하는 패키지로, ts를 js로 어떻게 변환할 것인지(how to convert) 전달한다. ??? 물론 내부적으로는 tsc를 사용한다.
webpack.config.js
webpack config 파일은 json 형식이 아니라 js 형식이며, node.js의 feature를 사용한다.
const path = require('path');
// module.exports => node's export syntax
module.exports = { // export configuration object
mode: 'development',
entry: './src/app.ts',
output: {
fileName: 'bundle.js', // "app.[contenthash].js"
path: path.resolve(__dirname, 'dist'),
publicPath: 'dist',
},
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.ts$/, // ts 확장자를 갖는 모든 파일을 의미
use: 'ts-loader',
exclude: /node_modules/, // ??? 생략해도 되는지
},
],
},
resolve: { // import 구문에서 확장자를 생략하더라도, 아래 옵션에 전달된 확장자를 자동으로 적용한다
extensions: ['.ts', '.js']
}
}
- entry | 프로젝트가 시작되는 파일(entry point)
- entry point에서 import 하고 있는 모든 파일을 확인한다.
- 그 파일 안에서 import 하고 있는 모든 파일을 확인한다.
- 프로젝트 내의 모든 파일을 분석할 때 까지 위의 과정을 반복한다.
- output | compile 파일의 이름, 위치 지정
- ??? publicPath
- webpack-dev-server를 제대로 이용하기 위해 필요한 옵션
- webpack-dev-server 모드에서는 매번 dist 폴더 내부에 bundle.js 파일이 생성되는 것이 아니라, 메모리에서만 생성되고, 그 메모리를 바탕으로 개발 서버에서 index.html 페이지를 보여준다. => publicPath에서 이를 전달해 주어야 개발 서버와 연결된다.
- +) build 명령어를 이용했을 때에만 dist 폴더 안에 bundle.js 파일이 생성된다.
- publicPath를 지정❌ | 컴파일 대상 파일에 변화가 생기더라도, 그 내용이 서버에 반영되지 않는다(source tab에서도 변화 내용이 반영되지 않는 것을 확인할 수 있다).
- publicPath를 지정⭕ | dev-server에게 output 파일(bundle.js)의 위치가 index.html과 비교했을 때 어디인지를 알려준다(기본적으로 dev-server는 index.html을 serve하기 때문).
- 결론 | publicPath를 설정해 주지 않으면 실시간으로 변화되는 코드가 개발 서버에 반영되지 않는다.
- ??? publicPath
- module
- webpack에게 파일을 어떻게 처리할 것인지 전달할 수 있다.
- ts 파일 뿐만 아니라, 다양한 타입의 파일(ex. css, image...)을 어떻게 처리할 것인지 rules 배열에 전달할 수 있다.
- test
- webpack이 찾아낸 모든 파일에 대해 실행할 test를 의미한다.
- regEx로 작성한다. => 두 개의 슬래시 사이에 regEx 작성
- use | test를 통과한 파일에 대해 compile rule을 적용한다.
- ts-loader는 tsconfig.json을 토대로 컴파일 옵션을 전달한다.
- resolve | extensions을 전달하면 import 구문에서 파일의 확장자를 생략 할 수 있다.
- mode
- development | 더 나은 개발 환경을 제공한다 => 더 나은 디버깅, 에러 메세지, 더 적은 코드 최적화 작업
- production
- webpack을 이용하려면 tsconfig.json 파일에서도 몇가지 옵션을 설정해 주어야 한다.
- target | es5 이상
- module | es2015
- sourceMap | true, devtools 옵션과 함께 source 탭에서 ts 파일을 디버깅할 수 있다.
- outFile, rootDir | 옵션 해제, webpack이 entry point에서 모든 파일을 하나씩 찾아가기 때문에 rootDir 옵션을 해제해야 한다(고 생각한다).
package.json
"scripts": {
"start": "webpack-dev-server",
"build": "webpack" // "webpack --config webpack.config.prod.js"
}
- build: webpack | 기본값인 webpack.config.js 파일에서 설정한 대로 컴파일(build app for production)
- build: webpack --config [filename] | 폴더 내의 filename에 해당하는 config 파일에서 설정한 대로 컴파일
$ npm start
$ npm run build
- start | 개발 서버 start
- build | 모든 파일이 번들링, 컴파일링 된 하나의 bundle.js 파일이 생성된다. 이 파일을 index.html에 script에 연결한다.
webpack.config.prod.js | production, 파일 이름은 아무거나 상관❌
$ npm i clean-webpack-plugin
const path = require('path')
const CleanPlugin = require('clean-webpack-plugin')
module.exports = {
mode:'production',
entry: './src/app.ts',
output: {
fileName: 'app.js',
path: path.resolve(__dirname, 'dist'),
// publicPath: 'dist', => dev-server에서 사용, production에서는 불필요
},
devtools: 'none', // production에서는 불필요
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
plugins: [
new CleanPlugin.CleanWebpackPlugin() // build 명령어를 실행하기 전, dist 폴더를 비워준다
]
}
'Study > TypeScript' 카테고리의 다른 글
Module (0) | 2022.08.10 |
---|---|
Decorators (0) | 2022.08.03 |
Generic (0) | 2022.07.24 |
Advanced Types (0) | 2022.07.23 |
Interface (0) | 2022.07.21 |