2025년 11월 10일
devtool을 devDependencies가 아닌 dependencies에 설치하는 이유
프론트엔드 개발을 하면서 라이브러리에서 공식적으로 지원하는 devtool을 사용해 본 경험이 많이 있습니다.
라이브러리들의 예시를 확인해 볼까요?

이 라이브러리는 tanstack query입니다. devtool임에도 불구하고 dependencies에 설치 해주는 모습이네요. 다른 라이브러리도 확인해 볼까요?

이 라이브러리는 jotai devtool입니다. 위에 tanstack query와 마찬가지 dependencies에 설치하는 모습이네요.
devDependencies에 설치하고 테스트
이 devtool을 devDependencies에 설치하고 테스트를 해보겠습니다.

우선 react router framework mode를 세팅하겠습니다.
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
const queryClient = new QueryClient();
export function Layout({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
<ReactQueryDevtools initialIsOpen={false} />
</html>
</QueryClientProvider>
);
}Dev 서버 테스트
간단하게 세팅 후 dev서버를 실행시켜 확인해 보면

아주 잘 실행되는 모습입니다.
Build 테스트
지금까지만 보면 별 문제가 없습니다. 이제 빌드를 해보겠습니다.

빌드도 잘 되네요!
빌드 결과물은 production mode에서 실행이 가능해야하기 때문에 node_modules를 지워주고
pnpm i -P실행을 시켜보면

이런 에러를 볼 수 있습니다.
원인 분석
사실 원인은 간단합니다. devDependencies는 pnpm i -P로 설치가 되지 않고
//root.tsx
export function Layout({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
<ReactQueryDevtools initialIsOpen={false} />
</html>
</QueryClientProvider>
);
}런타임에서 참조가 있기 때문이죠. 런타임에서 코드를 실행시킬 때 참조가 없기 때문에 에러가 발생합니다.
devDependencies에 설치하고 안전하게 사용하는 방법.
이제 devtool을 devDependencies에 설치하고 안전하게 사용하는 방법에 대해서 알아보겠습니다.
const ReactQueryDevtools = lazy(() =>
import("@tanstack/react-query-devtools").then((module) => ({
default: module.ReactQueryDevtools,
}))
);
const queryClient = new QueryClient();
export function Layout({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
{import.meta.env.DEV && <ReactQueryDevtools initialIsOpen={false} />}
</html>
</QueryClientProvider>
);
}이런식으로 런타임에 참조를 없애버리면 문제가 발생하지 않습니다.