본문 바로가기

개발/React

(짧) Vite환경에서 tanstack/query 사용 시 useSyncExternalStore 관련 에러가 발생하는 경우 해결 방법

반응형

 

 

 

Vite환경에서 build시에 위와 같이 tanstack/query에서 사용중인 패키지 중 useSyncExternalStore.mjs에서 해당 메서드를 제대로 export하지 못하여 import하지 못했다는 에러 메시지가 발생하는 경우가 있다.

 

 

발생한 에러 메시지는 다음과 같다.

 

RollupError: node_modules/@tanstack/react-query/build/lib/useSyncExternalStore.mjs (2:9): "useSyncExternalStore" is not exported by "node_modules/use-sync-external-store/shim/index.js", imported by "node_modules/@tanstack/react-query/build/lib/useSyncExternalStore.mjs".

 

구글검색을 통해 찾아보면 2022년쯤 이러한 에러를 마주한 글이 간혹 있고, 그러한 경우에는 v3버전인 react-query에서 v4이후 버전인 @tanstack/query로 migration을 하는 과정에서 제대로 import하지 못해서 생긴 이슈라고 한다.

 

참고 자료 : https://github.com/TanStack/query/issues/3848

 

하지만 내가 마주한 경우는 이미 tanstack/query v4를 사용중이었고, 정상적으로 사용하던 레포이기에 이러한 경우에 해당하지 않았다.

 

다양한 루트로 검색해본 결과 나온 결론은 다음과 같다.

 

해당 패키지가 ESM형식을 제대로 지원하지 않거나, Vite가 해당 모듈을 제대로 해석하지 않는 문제로 보였다.

 

실제 해당 라이브러리의 코드는 아래와 같다.

 

/**
 * 링크 : https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStore.js
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

'use strict';

// Intentionally not using named imports because Rollup uses dynamic
// dispatch for CommonJS interop named imports.
import * as React from 'react';

export const useSyncExternalStore = React.useSyncExternalStore;

if (__DEV__) {
  console.error(
    "The main 'use-sync-external-store' entry point is not supported; all it " +
      "does is re-export useSyncExternalStore from the 'react' package, so " +
      'it only works with React 18+.' +
      '\n\n' +
      'If you wish to support React 16 and 17, import from ' +
      "'use-sync-external-store/shim' instead. It will fall back to a shimmed " +
      'implementation when the native one is not available.' +
      '\n\n' +
      "If you only support React 18+, you can import directly from 'react'.",
  );
}

 

 

그렇다면 ESM 을 사용하지 않아서 생기는 문제는 아닌 것으로 보였고, 다른 코드를 보았을 때 require 문법을 사용하여 동적으로 import해주는 부분이 존재하는 것을 확인했다. 또한 디렉토리 구조 내에서 cjs에 대한 폴더는 없지만 package.json에 cjs에 대한 내용을 가지고있는 것으로 보아 빌드 프로세스 도중 ESM 코드를 CommonJS로 변환해주어 이를 사용하는 경우가 생길 수도 있다. 따라서 특정 상황에서 CommonJS로 해당 라이브러리의 내용을 받고, Vite가 CommonJS문법을 해석하는 데에 있어 문제가 있다고 판단했다.

 

(참고 링크 : https://github.com/facebook/react/blob/main/packages/use-sync-external-store/npm/index.js )

 

이런 상황에서는 Vite가 CommonJS 모듈도 제대로 처리할 수 있도록 특정 플러그인을 추가해주는 것으로 해결할 수 있다.

 

나는 @rollup/plugin-commonjs Plugin이 위와 같은 역할을 해줄 수 있다는 것을 찾았고, 이 플러그인을 vite.config.ts 에 추가해주는 것으로 해당 이슈를 해결했다.

 

export default defineConfig({
  plugins: [
    react(),
    commonjs({
      include: /node_modules/,
    }),
    // ...
  ]
})

 

 

반응형