webpack concepts

zmin·2022년 8월 20일
0

언제까지고 CRA를 쓸 순 없으니까..

https://webpack.js.org/concepts/

webpack은 자바스크립트 번들러

concepts 파트는 config파일을 통해 웹팩에 어떤 설정 등을 할 수 있는지 가볍게 설명해주는 부분이다. 뭘 할 수 있는지 알아야 나중에 찾아볼 수도 있지 않을까 하는 마음으로...

webpack.config.js 웹팩 설정파일로 여러 설정 등을 할 수 있다. 4.0.0이후로 필수적인 것은 아니지만 직접 구성할 수 있음.

// webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
	entry: './src/js/main.js',
	output: {
		path: './bundle/',
		filename: 'my-bundle.js'
	},
	module: {
		rules: [
			{ test: /\.txt$/, use: 'raw-loader' }
		]
	},
	plugins: [
		// 아래 플러그인은 만들어진 번들 파일들을 자동으로 template에 지정된 html파일에 추가해준다.
		new HtmlWebpackPlugin({ template: './src/index.html' })
	],
	mode: 'development',
}

concepts

  • entry point
    • 여러 모듈들을 하나의 파일로 만들기 위해서는 import/require을 찾아내서 모듈간의 의존성 그래프를 알아내는 것이 중요하다. 그래야 필요한 파일도 불러와서 하나의 파일로 합칠 수 있기 때문이다.
    • entry point는 그렇게 import/require를 찾아내는 것을 시작할 파일을 말한다. 말그대로 진입점. 여러개를 지정할 수도 있음
    • default : ./src/index.js
    • 문자열(또는 문자열 배열)로 간편하게 지정해줄 수 있지만 object syntax를 사용하면 세세한 설정이 가능하다. 번들링한다는게 무조건 하나의 파일로만 만드는 것이 아니다. 다중 페이지인 경우 아래와 같이 각각의 의존성 그래프를 만들어 각각 번들링 할 수 있다. → multiple entry points
      entry: {
      	one: './src/one/index.js',
      	another: {
      		dependOn: 'one',
      		import: './another-basic'
      	},
      	others: './src/others/index.js'
      }
  • output
    • 번들링된 파일을 어디에 어떤 이름으로 저장할 건지 지정
    • default : ./dist/main.js
    • 만약 multiple entry points를 사용한다면 substitution을 사용하여 파일의 이름이 중복되지 않도록 해야한다.
  • loader
    • 처음에 말한 것처럼 기본적으로 javascript파일과 json파일만 처리하지만 이를 이용해서 다른 파일도 처리하게 설정
    • module.rules에 {test: string, use: string}[] 로 설정해줄 수 있다.
    • test는 대상이 될 파일(일반적으로 확장자), use는 어떤 로더를 이용할 건지 명시함
      • 또는 실제 각 파일에서 모듈을 불러오는 import/require등의 구문에서 ! 를 사용하여 로더를 지정해줄 수도 있음
        import module from '로더이름!대상파일'
      • !, !!, -! 를 가장 앞에 붙여서. 로더에 대한 활성화 여부를 결정할 수 있다
      • 하지만 config파일에 rules에 지정하는 것을 추천
    • 여러 로더를 설정하게 되면 각 로더는 리소스를 처리하여 다음 로더에게 전달하는 방식으로 작업
    • 기본 자바스크립트 번들링을 더 확장하는 로직을 추가할 때 사용
  • plugin
    • 로더에 비해 로더가 할 수 없는 광범위한 추가 작업을 할 수 있는 플러그인이 필요할 때 사용
    • 번들의 최적화, 환경변수 관리 등
    • new 키워드로 인스턴스를 만들어서 사용
    • 웹팩에서 제공하는 내장 플러그인
      • const webpack = require('webpack'); 에 내장되어 있음
  • mode
    • 웹팩이 실행될 환경에 따라 최적화 방법을 지정해줄 수 있다
    • development, production, none
    • default : production

위 핵심 내용 말고도 module.exports에 정의해줄 수 있는 것들이 많다.
https://webpack.js.org/configuration/

이런 configuration 파일 내에서도 역시 node.js CommonJs 기반이라 필요한 플러그인이나 파일을 require()을 통해 로드할 수 있다.

일반적으로 webpack.config.js 의 module.exports 에는 단일 객체를 할당하지만 배열을 전달하여 여러 설정을 export할 수도 있다. 이 경우는 보통 라이브러리를 만들면서 여러 모듈을 타겟(output.libraryTarget으로 구분)으로 할 때, 아니면 배포 환경을 다양하게 정의하고 싶어 target 를 이용하여 나타낼 때 사용하게 된다.

webpack module

common js(cjs), esm, amd 처럼 webpack에도 처리할 수 있는 모듈 포맷이 존재한다.

기본적으로 esm, cjs, amd, assets, webAssembly 모듈을 지원하여 이 포맷으로 작성된 모듈들의 의존성을 분석할 수 있다.

추가로 편리한 개발을 위해 사용하는 전처리기나 typescript같은 언어들도 지원한다. loader 항목을 통해 지정해줄 수 있으며 기본적으로 로더를 제공하고 있다. (물론 직접 만들어서 쓸 수도 있다.)

각 모듈의 path는 절대/상대/모듈(기본으로 지정된 디렉터리 내부) 경로로 지정해 줄 수 있고, 이때 사용되는 enhanced-resolve 는 이런 접근들을 캐싱하여 추가로 요청해야할 때 더 빨리 처리할 수 있도록 한다.

웹팩이 내가 작성한 코드들과 패키지, 모듈을 합치는 과정에서 생기는 정보들은(상호작용이라고 표현) manifest 파일의 메타데이터로 관리된다. 이후 실제 이 파일들을 실행할 때 각 모듈을 해석할 때 이 정보를 이용한다.

Hot Module Replacement

뭔가 수정했을 때 모듈 전체를 다시 불러오지 않고도 수정된 부분을 적용할 수 있다 → live reload의 역할이 가능하게 함

HMR 런타임이 업데이트된 내용이 있는지 먼저 확인하고 수정된 부분에 대해서만 알아서 업데이트를 진행한 후에 어플리케이션 런타임에 업데이트를 진행한다. → 어플리케이션 런타임 입장에서는 모듈을 다시 업데이트하지 않음

헷갈리면 안되는게 번들링 자체와는 다르다. 코드가 수정되면 당연히 번들링은 다시 진행된다.


다른 번들러들과의 비교

https://betterprogramming.pub/the-battle-of-bundlers-6333a4e3eda9#:~:text=webpack and Rollup both require,is why you use path
https://bundlers.tooling.report/

자세한 내용은 위 글들에 있지만 정리하자면 번들러 근본인 웹팩은 다른 번들러들에 비해서 제공해주는 것도 많고 기능도 많다. 정말 기본적인 것을 제공하면서 추가적인 기능과 예외적인 상황에 대한 처리를 다양하게 쌓아올릴 수 있는 형태다. 그래서 덕분에 일일이 config 해줘야하지만 그만큼 다양한 상황을 개발자 마음대로 다룰 수 있다는 것을 의미한다. 그래서 보통

  • 나만의 작은 앱을 만들고 번들링을 진행할 거라면 가볍게 다른 번들러를 사용
  • 다양한 종속성을 포함하고 esm 뿐만 아니라 cjs 모듈도 다루게 되는 복잡한 앱을 만들 때는 웹팩

을 대부분 추천한다.

profile
308 Permanent Redirect

0개의 댓글