본문 바로가기

자바스크립트

[자바스크립트] 웹팩으로 바닐라js MPA 프로젝트 번들링하기

728x90

메인 화면상세페이지
main(좌) / detail(우)

 

오늘은 팀 프로젝트를 거의 마무리하고 지난번처럼 웹팩을 적용해서 Github Pages에 배포했다. 지난번과 다르게 MPA(Multi Page Application) 방식의 프로젝트를 만들었고, html 파일과 css 파일도 함께 번들링하는 작업을 수행했다.


MPA 번들링

  entry: {
    main: './js/main.js',
    detail: './js/detail.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },

 

MPA 방식에서는 각 html 파일의 진입점에 해당하는 js 파일을 각각 설정하면 된다. 위 코드와 같이 entry에 객체로 '진입점 이름 : 소스 파일 경로'을 지정하면 된다. 그러면 output[name] 부분에 진입점 이름이 지정되어 dist 경로에 각각 main.js와 detail.js로 번들 파일이 생성된다.

 

entry: {
  main: { import: './js/main.js', filename: 'main/[name].js' },
  detail: { import: './js/detail.js', filename: 'detail/[name].js' }
},

 

만약 두 번들 파일을 서로 다른 경로에 생성하고 싶으면 entry에 객체로 importfilename을 지정하면 된다. import는 소스 파일의 경로이고 filename은 번들 파일의 생성 위치이다. 위 경우에는 각각 dist/main/main.jsdist/detail/detail.js로 생성된다.

 

이외에도 entry에 다양한 옵션이 존재하는데 webpack 공식 홈페이지에서 확인할 수 있다.


html 파일 번들링

가장 먼저 HtmlWebpackPlugin을 설치해야하며, 이는 웹팩 번들에 사용하기 위한 html 파일을 쉽게 생성해주는 플러그인이라고 한다. 즉, js를 번들링할 때 html을 같이 번들링해서 해당 js 파일을 head 태그에 자동으로 삽입해주는 역할이다.

 

plugins: [
  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: './html/main.html',
    chunks: ['main']
  }),
  new HtmlWebpackPlugin({
    filename: 'detail.html',
    template: './html/detail.html',
    chunks: ['detail']
  }),
]

 

SPA의 경우 하나의 진입점만 존재하기 때문에 HtmlWebpackPlugin을 한 번만 사용하면 되는데, MPAhtml 파일 갯수와 동일하게 사용해야 한다. filename은 생성되는 파일의 이름이고, template은 소스 파일의 경로이다. 가장 중요한 것은 js 번들링에서 entry에 지정한 진입점 이름chunk에 넣어주면 자동으로 해당 html 파일의 head 부분에 js파일과 css 파일이 자동으로 삽입된다.

 

index.html <head/>
index.html <head/>

 

위 사진에서 번들링된 index.html 파일의 head 부분에 진입점 이름 main에 해당하는 js파일과 css 파일이 정상적으로 삽인된 것을 볼 수 있다. detail.html에는 진입점 이름 detail에 해당하는 js파일과 css 파일이 포함되어 있다.


css 번들링

main.js
main.js

 

css를 함께 번들링 하기 위해서는 기존에 html 태그에 삽입되어 있던 css 파일을 js 파일의 상단으로 옮겨야 한다. 이는 웹팩이 js 파일을 진입점으로 관련된 파일을 함께 번들링 하기 때문인 것 같다.

 

다음으로 css-loadermini-css-extract-plugin을 설치한다. css-loader는 @import나 url() 구문을 import/require와 같이 해석하는 것이라고 하고, mini-css-extract-plugin는 css 파일을 별도로 생성해주는 것이라고 한다.

 

module: {
  rules: [
    {
      test: /\.css$/,
      use: [MiniCssExtractPlugin.loader, 'css-loader']
    }
  ]
},
  
plugins: [new MiniCssExtractPlugin()]

 

mini-css-extract-pluginmoduleplugins에서 모두 사용되는 점만 주의하면 된다. 공홈에서는 아쉽게도 정확하게 설명해주진 않는데, 아마 module 부분에서 css-loader로 css 파일을 처리한 후 mini-css-extract-plugin에 내장된 loader를 사용해 css 번들 파일을 생성하는 것 같다.

 

new MiniCssExtractPlugin({
  filename: (pathData) => {
    return pathData.chunk.name === 'main'
      ? 'main/[name].css'
      : 'detail/[name].css';
  }
})

 

css 번들 파일의 경로를 지정하고 싶으면 위와 같은 객체를 넣어주면 된다. pathData는 css 파일의 정보를 객체로 가지고 있다.


최종 디렉토리 경로
최종 디렉토리 경로

 

그동안 리액트에서 cra만 사용해서 제대로 웹팩 설정을 해본적이 없었는데, 지난번과 이번 프로젝트를 통해 웹팩에 대한 이해도를 매우 높힐 수 있었던 것 같다. 사실 이번 프로젝트부터 vite를 사용하고 싶었는데 아쉽게도 그러지 못했고 다음주부터 리액트 과제를 시작하면 진짜로 vite를 써야겠다.

 


 

 

 

webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

728x90