티스토리 뷰

문제점

npm run build 명령을 통해서 떨어지는 최종 결과물에, Code Split를 적용하기 위해서 아래와 같은 옵션을 적용했다.

module.exports = {
  configureWebpack: {
    optimization: {
      minimize: true,
      splitChunks: {
        chunks: "all" // 이거
      },
    },
  },
}

Entry파일을 여러개로 나눈, Multiple Entry 형태의 구조로 개발을 하기위해서 공통으로 활용되는 npm 패키지들을 하나로 묶고자 위와 같이 설정한 것인데...위와 같이 정의하고 npm run build로 webpack을 동작시키면 의도한대로 최종 빌드된 html과 js파일들은 잘 생성이 된다.

 

하지만, npm run serve를 통해 webpack-dev-server를 구동시키면 아래와같은 warning을 띄우며 화면이 렌더링 되지 않는다.

 

The resource http://localhost:8080/vendors~index.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally

 

해결법

해당 원인이 발생하는 이유는, vue-cli를 통해서 생성한 프로젝트에서, 빌드할 경우 생성되는 HTML에서 메타 데이터인javascript를 가져 올 경우 prefetch와 preload 옵션을 자동으로 정의해주는데...이게 문제라는거다. 

 

preload 옵션으로 로드해오는 리소스는 3초내에 실제로 '활용'이 되어야한다는데, 공통으로 활용되는 패키지가 있는 javascript 파일이니만큼 즉각적으로 활용이 안 되니까, 위와 같은 문제가 발생하는 것으로 추정된다(실제로 구글링해보면 위와같은 에러는 font 리소스를 가져올 때 많이들 발생한다고 포스팅되어있다)

 

처음엔 이 prefetch나 preload를 제거할 방법을 찾고자했지만...

github 이슈를 통해서 확인해보니 In vue-cli webpack, modules are ALWAYS prefetched, and there is no way...라고 누가 답변을 작성해놓았더라. no way...그러니까 단순히 vue-cli의 설정만으로는 방법이 없다는거다.

 

하지만 분명 예전에 투입됐던 모 프로젝트에서는 이걸 당연하게 썼었는데, 싶어서 당시의 webpack 설정파일을 찾아서 비교해보니 이 이슈를 해결할 실마리를 찾게되었다.

 

그것은 바로 HtmlWebpackPlugin 플러그인.

 

해당 플러그인은 최종 빌드되어 떨어지는 HTML 파일과 관련된 설정을 여러 옵션으로 정의해주는 방식인데, 이걸 사용하면 preload나 prefetch와 같은 메타데이터 링크의 옵션들이 붙지 않는다. 물론, preload나 prefetch가 선별적으로 필요한 경우라면 해법을 다르게 찾아봐야하겠지만 현재로썬 그러한 점이 불필요하기 때문에 하기와 같이 플러그인을 설치하고 옵션을 정의하여 해결하게였다.

 

우선, npm install을 통해 html-webpack-plugin을 설치해줘야하는데 webpack 버전을 확인하고 사용하는 버전에 맞는 플러그인을 설치해야한다.

 

Webpack 버전이 4.x 일 경우

npm i --save-dev html-webpack-plugin@4

Webpack 버전이 5.x 일 경우

npm i --save-dev html-webpack-plugin

 

npm install이 완료되면, 이제 vue.config.js(혹은 webpack 설정파일)에 아래와 같이 plugin을 정의해주고 webpack-dev-server를 구동시켜주면 정상적으로 동작되는 걸 확인할 수 있다.

// 나는 Entry 파일이 2개라서 2개의 HtmlWebpackPlugin을 정의했다.
plugins: [
  new HtmlWebpackPlugin({
    template: 'public/index.html',
    filename: 'index.html',
    inject: true,
    chunks: ['index']
  }),
  new HtmlWebpackPlugin({
    template: 'public/index2.html',
    filename: 'index2.html',
    inject: true,
    chunks: ['index2']
  })
]
댓글
최근에 올라온 글
Total
Today
Yesterday