Patch-package 라이브러리, node_modules 를 커스텀하고 관리하자!

Lee Yongin·2024년 1월 3일
0

리액트 네이티브

목록 보기
5/6
post-thumbnail

Patch-package Library

쓰는 이유

react native 프로젝트를 진행하면서, 의존성 관련 문제로 빌드오류가 자주 발생했다. 이를 해결하기 위해 npm 패키지의 특정 코드를 수정해야 하는 일이 있다. 이런 변경사항을 유지하고 관리할 때 유용한 라이브러리임을 알게 되었다.

설치하기

package.json에 아래와 같이 코드를 추가한다.

"scripts": {
  "postinstall": "patch-package" //추가
 }

루트 프로젝트 폴더에서 patch-package및 postinstall-postinstall을 설치한다.

yarn add patch-package postinstall-postinstall

활용방법

npm package에 수정사항이 생겼을 때 코드를 수정하고 react-native라는 이름으로 패치파일을 생성하면, patches라는 폴더에 파일이 저장된다. 그러면 이 파일을 기반으로 Git에서 관리되고 다른 팀원이 yarn을 설치했을 때 그대로 적용이 된다.

yarn patch-package package-name 
yarn patch-package react-native //예시 

나는 react-native-vector-icon의 의존성 문제를 해결하기 위해 stackoverflow의 코드를 추가한 후 패치파일로 저장해주었다. 그러면 아래와 같이 파일이 만들어진다.

diff --git a/node_modules/react-native/sdks/hermes/hermes-engine.podspec b/node_modules/react-native/sdks/hermes/hermes-engine.podspec
new file mode 100644
index 0000000..f21488b
--- /dev/null
+++ b/node_modules/react-native/sdks/hermes/hermes-engine.podspec
@@ -0,0 +1,81 @@
+# 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.
+
+require "json"
+require "open3"
+
+# sdks/hermesc/osx-bin/ImportHermesc.cmake
+import_hermesc_file=File.join(__dir__, "..", "hermesc", "osx-bin", "ImportHermesc.cmake")
+
+# package.json
+package_file = File.join(__dir__, "..", "..", "package.json")
+package = JSON.parse(File.read(package_file))
+version = package['version']
+
+# We need to check the current git branch/remote to verify if
+# we're on a React Native release branch to actually build Hermes.
+currentbranch, err = Open3.capture3("git rev-parse --abbrev-ref HEAD")
+currentremote, err = Open3.capture3("git config --get remote.origin.url")
+
+source = {}
+git = "https://github.com/facebook/hermes.git"
+
+if version == '1000.0.0'
+  Pod::UI.puts '[Hermes] Hermes needs to be compiled, installing hermes-engine may take a while...'.yellow if Object.const_defined?("Pod::UI")
+  source[:git] = git
+  source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip
+elsif currentremote.strip.end_with?("facebook/react-native.git") and currentbranch.strip.end_with?("-stable")
+  Pod::UI.puts '[Hermes] Detected that you are on a React Native release branch, building Hermes from source...'.yellow if Object.const_defined?("Pod::UI")
+  hermestag_file = File.join(__dir__, "..", ".hermesversion")
+  hermestag = File.read(hermestag_file).strip
+  source[:git] = git
+  source[:tag] = hermestag
+else
+  source[:http] = "https://github.com/facebook/react-native/releases/download/v#{version}/hermes-runtime-darwin-v#{version}.tar.gz"
+end
+
+module HermesHelper
+  # BUILD_TYPE = :debug
+  BUILD_TYPE = :release
+end
+
+Pod::Spec.new do |spec|
+  spec.name        = "hermes-engine"
+  spec.version     = version
+  spec.summary     = "Hermes is a small and lightweight JavaScript engine optimized for running React Native."
+  spec.description = "Hermes is a JavaScript engine optimized for fast start-up of React Native apps. It features ahead-of-time static optimization and compact bytecode."
+  spec.homepage    = "https://hermesengine.dev"
+  spec.license     = package["license"]
+  spec.author      = "Facebook"
+  spec.source      = source
+  spec.platforms   = { :osx => "10.13", :ios => "11.0" }
+
+  spec.preserve_paths      = ["destroot/bin/*"].concat(HermesHelper::BUILD_TYPE == :debug ? ["**/*.{h,c,cpp}"] : [])
+  spec.source_files        = "destroot/include/**/*.h"
+  spec.header_mappings_dir = "destroot/include"
+
+  spec.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermes.xcframework"
+  spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"
+
+  spec.xcconfig            = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "CLANG_CXX_LIBRARY" => "compiler-default", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" }
+
+  if source[:git] then
+    spec.prepare_command = <<-EOS
+      # When true, debug build will be used.
+      # See `build-apple-framework.sh` for details
+      DEBUG=#{HermesHelper::BUILD_TYPE == :debug}
+
+      # Set HERMES_OVERRIDE_HERMESC_PATH if pre-built HermesC is available
+      #{File.exist?(import_hermesc_file) ? "export HERMES_OVERRIDE_HERMESC_PATH=#{import_hermesc_file}" : ""}
+      #{File.exist?(import_hermesc_file) ? "echo \"Overriding HermesC path...\"" : ""}
+
+      # Build iOS framework
+      ./utils/build-ios-framework.sh
+
+      # Build Mac framework
+      ./utils/build-mac-framework.sh
+    EOS
+  end
+end

잊지 말자

패치파일이 생긴 후에 적용을 잘 시키려면 node_modules 폴더를 삭제하고 재설치 후 빌드까지 해봐야 한다.

설치

yarn

pod 삭제 후 재설치

cd ios
rm -rf Podfile.lock Pods
pod install
yarn ios

빌드

yarn ios //ios폴더
./gradlew clean //android 폴더
./gradlew build //android 폴더
profile
f1을 좋아하는...🏆 f1처럼 빠르고 정확한 걸 좋아하는 안드로이드 개발자

0개의 댓글