react로 만든 UI 라이브러리를 다른 프로젝트에서 사용하기 위해서 npm link를 이용해 라이브러리르 사용하던 중
react 충돌이 일어나 에러가 발생해 라이브러리를 사용하지 못하는 이슈가 있었습니다.
라이브러리를 불러오게 되면 react에서 흔히 사용하는 useState, useEffect등 아래와 같은 Error가 발생했습니다.
Uncaught TypeError: Cannot read properties of null (reading 'useState')
Hooks can only be called inside the body of a function component.
로컬 환경 기준, npm link로 패키지를 불러올 경우 node_modules에는 심볼릭 링크로 패키지가 연결됩니다.
심볼릭 링크로 연결이 된다면 그 안에 있는 node_modules가 존재해 여러 인스턴스가 중복이 될 수 있습니다.
그로 인해 react에서는 hooks이 중복되어 있다는 에러 메시지를 띄우게 됩니다.
https://ko.legacy.reactjs.org/warnings/invalid-hook-call-warning.html
에 따르면 react가 중복이 되어 있는지 확인 할 수 있는 테스트 예시가 있습니다.
// node_modules/react-dom/index.js에 아래를 추가하세요.
window.React1 = require('react');
// 컴포넌트 파일에 아래를 추가하세요.
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);
여기서 false가 출력이 된다면 react가 중복이 되어 있다는 것입니다.
React에서 말하길 이 문제는 npm link 를 사용할 때 나타날 수 있다고 나옵니다.
제시한 해결책은 사용하려는 프로젝트에서 npm link ../myapp/node_modules/react를 실행하는 방법을 알려줍니다.
이 방법도 되지만 저는 rollup을 이용해 UI 라이브러리를 만들어 rollup의 alias를 이용해 react 외부 의존성을 설정하는 방법 하나와 꼼수를 이용하는 방법을 적어보겠습니다.
rollup에는 다양한 plugin이 존재 하지만 제가 사용할 plugin은 @rollup/plugin-alias 이기에 라이브러리에 설치합니다.
// rollup.config.js
import alias from '@rollup/plugin-alias';
export default {
input: "./src/index.ts",
output: {
file: './dist/bundle.js',
format: 'esm',
sourcemap: true,
},
plugins: [
// ...
alias({
entries: [
{ find: 'react', replacement: './node_modules/react'}
]
})
]
};
rollup config 설정 파일에서 위와 같이 설정을 한다면 중복되는 문제를 해결 할 수 있습니다.
npm link의 문제를 해결하기 위해 이런 저런 방법을 시도해본 결과 가장 쉽지만 잔머리를 굴린 방식이라 참고만 하면 좋을것같습니다.
저는 UI 라이브러리 node_modules에서 설치된 react와 react-dom 패키지를 삭제함으로써 중복되는 문제를 없애버렸습니다..
별거 없지만 로컬에서 UI 라이브러리 수정하고 확인하는 작업이 많을 경우엔 이 방법으로 시간을 많이 줄였습니다.
배포 후엔 내부에서만 사용하기 위해 tar파일로 묶어 정상적으로 패키지를 사용하고 있습니다 ㅎ.