Programing/React-Native

[RN] Node 업그레이드 후 빌드 오류 (error:0308010C:digital)

Poylib 2023. 9. 11. 00:50

History

기존에 사용하던 node 버전은 v16.16.0 인데 꽤 지난 버전이기도 하고 협업과정에 node 버전 차이가 문제가 되기도 해 이번 기회에 업그레이드하기로 했다. node 버전관리는 nvm을 사용하고 있기 때문에 lts 버전을 다운로드하여 버전을 바꿔주었다.

nvm install --lts

설치가 끝난 후 사용할 node 버전을 바꿔주고 별다른 이유가 없다면 default 버전도 변경해준다.

nvm use --lts
nvm alias default v18.17.1	// 여기는 --lts 옵션이 듣질 않으니 직접 버전을 입력해줘야 한다,,,
// 변경사항 확인
nvm ls 
node -v

node 버전을 올리는 것까지는 문제없으나 metro를 실행하면 이런 에러를 받는다.

Failed to construct transformer:  Error: error:0308010C:digital envelope routines::unsupported
...
{
  opensslErrorStack: [
    'error:03000086:digital envelope routines::initialization error',
  ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED',
};

 

Why

Node 17버전 로그에서 힌트를 얻을 수 있다. 17이상 버전에서는 OpenSSL 3.0 을 사용하는데 일부 알고리즘 혹은 key 크기가 기존의 OpenSSL 1.1.1과 호환되지 않을 수 있다고 한다. OpenSSL github의 토론 정보와 종합해 보면 Webpack이 번들링 하는 과정에 사용하는 알고리즘인 MD4가 보안상의 이유로 OpenSSL 3.0에서는 사용되지 않고 node에서 ERR_OSSL_EVP_UNSUPPORTED 이 메시지로 에러처리 해둔 것 같다.

에러를 해결하기 위해 OpenSSL이 무엇이고 webpack과 어떤 상관관계가 있는지는 중요하지 않으니 임시해결책으로 던져준

--openssl-legacy-provider

이 옵션만 알고 가면 되는데 앞서 언급한 MD4 알고리즘을 포함한 레거시 알고리즘의 모음이라고 보면 된다.

 

Sol

1. 어쩌면 간단한 문제

node 버전을 변경시켰기 때문에 기존의 번들과 cache를 지우고 재설치하는 방식으로 해결될 수 있다.

// node modules 삭제
rm -rf node_modules
rm -rf yarn.lock	// for yarn
rm -rf package-lock.json	// for npm

// npm cache
npm cache clean --force

// android build
cd android
./gradlew clean

// xcode build
rm -rf ~/Library/Developer/Xcode/DerivedData/*
// xcode 내 프로젝트 클린 단축키 : CMD + Shift + K

깨끗하게 지우고 다시 패키지 설치

// for yarn
yarn

// for npm 
npm install

// if ios
cd pod && pod install

 

2. --openssl-legacy-provider

node option을 사용하기 위해서 프로텍트 폴더 내 터미널에서

export NODE_OPTIONS=--openssl-legacy-provider

이 명령어를 입력 후 metro를 켜보면 된다.

 

앱을 열 때 같이 사용하도록 script를 만들어줄 수 있는데

package.json 파일에서 기존 명령어에 export NODE_OPTIONS=--openssl-legacy-provider && 를 추가해 주면 된다.

  "scripts": {
	...
    "start": "export NODE_OPTIONS=--openssl-legacy-provider && react-native start",
    "ios": "export NODE_OPTIONS=--openssl-legacy-provider && react-native run-ios",
    "android": "export NODE_OPTIONS=--openssl-legacy-provider && react-native run-android",
    "android:apk": "export NODE_OPTIONS=--openssl-legacy-provider && cd android && ./gradlew app:assembleRelease && cd ..",
  },

 

xcode build error

위 방식으로 metro에 접속은 가능하나, ios 앱을 빌드하고 있다면 xcode에서 앱 빌드시 다시 opensslError를 만날 수 있다.

에러의 원인과 해결방법은 동일하다. xcode에서 프로젝트를 선택한 후 Build Phases 탭에 들어가 Bundle React Native code and images 탭을 열어 위 export문을 추가해 주자. 빌드 클린 ( cmd + shift + k ) 후 재빌드 해보면 된다. 

3. node version downgrade

복잡한 사유로 도저히 해결이 안 된다면 이 이슈가 생기기 전 node 버전인 16 이하로 다운그레이드하는 것도 방법이다. 

nvm install 16
nvm alias default 16
nvm use 16

이후 1의 방법처럼 기존 모듈 및 캐시를 삭제 후 새로 패키지를 설치하면 된다.