생계유지형 개발자/JS Framework

[webpack5] HtmlWebpackPlugin 사용하여 html 번들링 시 js 골라서 삽입하기

이 가을 2023. 1. 20. 14:39

하나의 프로젝트 안에서 디바이스 별로 디렉토리를 나누어 pc용 모듈, mobile용 모듈을 따로 개발하려고 한다.

즉, 한 번의 빌드로 pc.js, mobile.js 라는 산출물을 만들어야 한다.

 

2개 이상의 js 파일로 번들링 하기 위한 설정이다.

// webpack.config.js

entry : {
	index: ! isDev ? './dist/index.js' : './src/pc/index.js',
	mobile: ! isDev ? './dist/mobile.js' : './src/mobile/index.js'
},
output: {
        filename: "[name].js",
        chunkFilename: '[name][id].js',
        path: path.resolve(__dirname, 'dist'),
        clean: true,
        publicPath: '/',
        library: {
            name: 'ConnectComment',
            type: 'umd'
        },
},

 

최종 필요한 산출물은 번들링된 js만 있으면 되지만, 로컬에서 개발할 때 화면으로 확인이 필요하기 때문에 HtmlWebpackPlugin 플러그인을 사용했다.

개발하면서도 pc용 화면, mobile용 화면이 따로 필요했기 때문에 플러그인 설정을 아래와 같이 했다.

// webpack.config.js

plugins: [
	new HtmlWebpackPlugin({ 		// pc
    		filename : 'index.html', 
    		chunks: ["index"], 
        	minify: true, 
        	template: './src/pc/index.html' 
        }),
	new HtmlWebpackPlugin({ 		// mobile
    		filename : 'mobile.html', 
    		chunks: ["mobile"], 
        	minify: true, 
        	template: './src/mobile/index.html' 
        })
]

 

위의 설정을 하고 빌드했을 때 산출물은 다음과 같이 나온다. (module 옵션에 따라 다를수도)

dist/
    ㄴ index.html
    ㄴ index.js
    ㄴ index.js.LICENSE.txt
    ㄴ mobile.html
    ㄴ mobile.js
    ㄴ mobile.js.LICENSE.txt

 

여기서 요점은 HtmlWebpackPlugin 에서 chunks 옵션을 넣은거다.

만약 저걸 넣지 않고 빌드하면 아래와 같이 생성된 각각의 html 파일에 index.js, mobile.js 파일이 둘다 삽입된다.

<!-- dist/index.html --> 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script defer src="/index.js"></script>
    <script defer src="/mobile.js"></script>
  </head>
  <body>
    <div id="app"></div>    
    <script type="text/javascript">
      window.onload =  () => new ConnectComment.load("#app");
    </script>
  </body>
</html>


<!-- dist/mobile.html --> 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script defer src="/index.js"></script>
    <script defer src="/mobile.js"></script>
  </head>
  <body>
    <div id="app"></div>    
    <script type="text/javascript">
      window.onload =  () => new ConnectComment.load("#app");
    </script>
  </body>
</html>

 

하지만 내가 원하는건 index.html 에는 index.js가, mobile.html에는 mobile.js가 삽입되는 것이기 때문에 이를 지원하는 것이 chunks 옵션이다.

chunks 옵션 값으로 entry 키값을 넣으면 해당하는 js 파일이 삽입되어 아래와 같이 내가 원하는 결과가 생성된다.

<!-- dist/index.html --> 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script defer src="/index.js"></script>
  </head>
  <body>
    <div id="app"></div>    
    <script type="text/javascript">
      window.onload =  () => new ConnectComment.load("#app");
    </script>
  </body>
</html>


<!-- dist/mobile.html --> 
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script defer src="/mobile.js"></script>
  </head>
  <body>
    <div id="app"></div>    
    <script type="text/javascript">
      window.onload =  () => new ConnectComment.load("#app");
    </script>
  </body>
</html>