Next.js 구형 브라우저 지원(polyfill, transfile)

샘플 코드

배경

실 서비스에서 특정 유저가 정상적으로 동작하지 않는다는 VOC를 듣게 되었습니다.

해당 유저는 Chrome55버전을 사용하는 유저였습니다.

운영중인 서비스가 JSP에서 Next.js로 마이그레이션하며 생긴 이슈라 해당 유저를 구출하고 싶은 오기가 생겼습니다.

Polyfill과 Transfile

javascript.info에서 보면

Transfile: 기존코드가 구 표준을 준수하는 코드로 변경된다.

→ 정리하면 최신버전의 코드를 구버전의 코드로 변경한 코드

Polyfill: 새로운 문법이나 기존에 없던 내장 함수에 대한 정의가 추가된다.

→ 정리하면 브라우저에서 지원하지 않는 코드를 사용가능한 코드로 변환한 코드

Next.js에서 Polyfill과 Transfile

실제로 Next.js의 공식문서에서는 설정없이 지원가능한 목록을 보여줍니다.

  • Chrome 64+

  • Edge 79+

  • Firefox 67+

  • Opera 51+

  • Safari 12+

해당 버전(ex. Chrome64)으로 Next.js를 실행시키면 오류없이 동작하는 것을 볼 수 있습니다.

혹시 특정 버전을 Target하고 싶다면 Next.js에서는 Browserslist을 제시합니다.

제가 원했던 버전인 Chrome55 버전도 package.json에 아래와 같이 명시해주면 정상적으로 동작합니다.

// package.json
  "browserslist": [
    "chrome 55",
  ]

그럼 끝일까요?

우리는 다양한 라이브러리를 사용하고 있습니다.

브라우저에서 사용할 수 있는 함수로 polyfill을 하고

해당하는 라이브러리가 내부적으로 지원하는 버전을 넘어간다면 node_modules에서 해당 부분은 transfile해주어야 우리는 비로소 구브라우저를 지원할 수 있습니다.

(여기서는 recoil@tanstack/react-query를 가이드로 작성하도록 하겠습니다.)

우선 Next.jsBabel 공식문서의 가이드를 참고하여 .babelrc 세팅을 진행합니다.

{
  "presets": [
    [
      "next/babel",
      {
        "preset-env": {
          "useBuiltIns": "entry",
          "corejs": 3
        }
      }
    ]
  ],
  "plugins": ["@babel/plugin-transform-private-methods"]
}

polyfill의 경우 _app.tsx를 권장하지않았고 next.js discussions에서 확인할 수 있듯 webpack에서 처리 할 수 있도록 설정하였습니다.

// next.config.js
  webpack(config) {
    const originalEntry = config.entry;
    config.entry = async () => {
      const entries = await originalEntry();

      if (entries["main.js"]) {
        entries["main.js"].unshift("./src/polyfills.ts");
      }

      return entries;
    };

    return config;
  },
// polyfills.ts
import "core-js/actual";

위의 과정을 통해 polyfill을 진행했다면 서드파티 라이브러리를 transfile을 하여 최신버전 문법을 쓸 수 있도록 처리해봅니다.

아래와 같이 두 라이브러리를 설치한 후

$ yarn add @tanstack/react-query recoil

App을 Provider로 각각 사용할 수 있습니다.

export default function App({ Component, pageProps }: AppProps) {
  return (
    <RecoilRootProvider>
      <RQProvider>
        <Component {...pageProps} />
      </RQProvider>
    </RecoilRootProvider>
  );
}

하지만 이렇게하면 지원 버전 이슈로 인해 오류가 발생합니다.

실제로 @tanstack/react-query의 공식문서에서도 node_modules를 직접 transfile해야 한다고 나와있습니다.

Depending on your environment, you might need to add polyfills. If you want to support older browsers, you need to transpile the library from node_modules yourselves.

우리는 next.config.js에서 아래와 같이 transpilePackages를 사용하여 node_modules를 직접 transfile할 수 있습니다.

  transpilePackages: [
    "@tanstack/react-query",
    "@tanstack/query-core",
    "recoil",
  ],

위의 과정을 통해 오류없이 구버전(Chrome55)버전까지 지원할 수 있도록 처리할 수 있었습니다.

NextStep

운영되고 있는 서비스의 라이브러리를 오류 내용을 통해 역으로 추적하며 transfile하는 과정도 재미있었지만

현재는 core-js의 쓰이는 파일을 모두 가져와서 사용하고 있는데 해당 부분을 조금 더 똑똑하게 처리할 수 있지 않을까하는 아쉬움도 함께 남는 시간이었습니다.

Reference

Last updated