Moment: React-Native 릴리슀 λΉŒλ“œ, λ‘œμΌ€μΌ λ³€κ²½ μ‹œ μ‹¬κ°ν•œ 좩돌

에 λ§Œλ“  2019λ…„ 10μ›” 10일  Β·  4μ½”λ©˜νŠΈ  Β·  좜처: moment/moment

react-native 0.59.10을 μ‚¬μš©ν•˜κ³  momentJS에 λŒ€ν•œ λ‘œμΌ€μΌμ„ μ„€μ •ν•  λ•Œ 릴리슀 λΉŒλ“œμ— λŒ€ν•΄μ„œλ§Œ 맀우 μž”μΈν•œ 좩돌이 λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. 디버거가 μ—°κ²°λœ μƒνƒœμ—μ„œλŠ” 이 μΆ©λŒμ„ μž¬ν˜„ν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. 이 μΆ©λŒμ€ iOS와 Android λͺ¨λ‘μ—μ„œ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λͺ¨λ“  μˆœκ°„ μ‚¬μš©μ„ λž˜ν•‘ν•˜λŠ” try-catch 문은 μΆ©λŒμ„ ν¬μ°©ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€!

μž¬ν˜„ν•˜κΈ° μœ„ν•΄

  1. μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ³„ λ‘œμ§μ„ 톡해 μ‹œλ„ν•˜λ €λŠ” λ‘œμΌ€μΌ/μ–Έμ–΄λ₯Ό μˆ˜μ§‘ν•©λ‹ˆλ‹€. 예: ["fr-CA", "en-US", "fr", "en"]
  2. μš°λ¦¬λŠ” Array setterλ₯Ό μ‚¬μš©ν•˜λŠ” λŒ€μ‹  ν•œ λ²ˆμ— ν•˜λ‚˜μ”© λ°˜λ³΅ν•˜μ—¬ λ‹€λ₯Έ 계츑을 ν˜ΈμΆœν•˜κ³  잠재적으둜 throwλ˜λŠ” JS μ˜ˆμ™Έλ₯Ό ν¬μ°©ν•˜κ³  λ‹€μŒ 후보λ₯Ό μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  3. try-catch 블둝 λ‚΄μ—μ„œ moment.locale(localeCandidate) ν˜ΈμΆœν–ˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ—¬μ „νžˆ ​​이 λΌμΈμ—μ„œ μΆ©λŒν•©λ‹ˆλ‹€β‡

이것은 μΆœμ‹œ μ‹œ μΆ©λŒμ΄μ—ˆμ§€λ§Œ 릴리슀 λΉŒλ“œμ—λ§Œ ν•΄λ‹Ήλ©λ‹ˆλ‹€!! 이둜 인해 μœ μš©ν•œ 였λ₯˜ λ©”μ‹œμ§€/λ‘œκΉ…μ„ μΆ”μΆœν•˜λŠ” 것이 맀우 κΉŒλ‹€λ‘œμ›Œμ‘ŒμŠ΅λ‹ˆλ‹€.

Bugsnag 톡합 및 μ‹œμŠ€ν…œ μ½˜μ†” λ‘œκΉ…μ„ 톡해 λ‹€μŒ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

  • iOS: Exception in HostFunction: Error loading module0from RAM Bundle: unspecified iostream_category error
  • μ•ˆλ“œλ‘œμ΄λ“œ: Exception in HostFunction: Module not found: 0
  • ν•˜λ£¨ ν›„ iOS 및 Androidμ—μ„œλ„ Requiring unknown module "./locale/en-us". λ³΄μ•˜μ§€λ§Œ μ΄μƒν•˜κ²Œλ„ 이 였λ₯˜λŠ” μ μ‹œμ— μ²˜λ¦¬λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. react-native/bugsnag 문제일 수 μžˆμŠ΅λ‹ˆλ‹€.
  1. μ΅œμ’… μΆ”μ μ—μ„œ μΆ©λŒμ„ μΌμœΌν‚¨ 단일 지점을 μ°Ύμ•˜μŠ΅λ‹ˆλ‹€.
    https://github.com/moment/moment/blob/96d0d6791ab495859d09a868803d31a55c917de1/moment.js#L1852 -L1853
    λ‚΄κ°€ λ―ΏλŠ” 것은 μ—¬κΈ°μ—μ„œ 온 κ²ƒμž…λ‹ˆλ‹€ : https://github.com/moment/moment/blob/6a06e7a0db2c83fb92aa72bbf6bde955d4c75a16/src/lib/locale/locales.js#L55 -L56

ν•΄κ²° 방법: 이 두 쀄을 주석 μ²˜λ¦¬ν•˜λ©΄ 좩돌이 μ€‘μ§€λ©λ‹ˆλ‹€!

μ˜ˆμƒλ˜λŠ” 행동

  • μˆœκ°„μ€ κ°‘μžκΈ° μž‘λ™ν•˜μ§€ μ•Šμ•„μ•Ό ν•˜μ§€λ§Œ 특히 릴리슀 λΉŒλ“œ μ „μš©μ—μ„œλŠ” 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€!
  • Moment의 μ˜ˆμ™ΈλŠ” catch κ°€λŠ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€(catch 문은 μΆ©λŒμ„ λ°©μ§€ν–ˆμ„ κ²ƒμž…λ‹ˆλ‹€). -- (λ¦΄λ¦¬μŠ€μ—μ„œ require() λ₯Ό μ‚¬μš©ν•˜λŠ” 경우 λ°˜μ‘ λ„€μ΄ν‹°λΈŒ 문제일 수 있음)

슀마트폰(λ‹€μŒ 정보λ₯Ό μž‘μ„±ν•΄ μ£Όμ„Έμš”):

  • κΈ°κΈ°: iPhone X, iPhone 11 Pro, Samsung(? -- μ •ν™•νžˆ 무엇을 μΊ‘μ²˜ν•˜μ§€ λͺ»ν•¨), Google Pixel 3, (react-native 0.59.10)
  • OS: iOS 및 μ•ˆλ“œλ‘œμ΄λ“œ
  • iOS JavaScript Core(μ•„λž˜μ— μ–ΈκΈ‰λœ iOS λ²„μ „μš©) 및 jsc-android(+intl) 245459.0.0
  • 버전: iOS 12.4 및 iOS 13.1, iOS 13.1.2 및 iOS 13.2(베타?), Android 28, 기타.

μˆœκ°„λ³„ ν™˜κ²½

  • νƒœν‰μ–‘ ν‘œμ€€μ‹œ 및 μ•„λ§ˆλ„ 런던 μ‹œκ°„
  • μ§€λ‚œ 2μ£Ό(2019-10-09) λ™μ•ˆ ν•˜λ£¨ 쒅일 μ§€μ†μ μœΌλ‘œ μ½”λ“œ 버그가 λ‚˜νƒ€λ‚¬μŠ΅λ‹ˆλ‹€.
  • μ‚¬μš© 쀑인 기타 라이브러리: moment-timezone 및 moment-with-locales, TypeScript, react-native 0.59.10, Apollo-Client 및 기타

ν™˜κ²½μ—μ„œ λ‹€μŒ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ³  좜λ ₯을 ν¬ν•¨ν•˜μ‹­μ‹œμ˜€.

        console.log([
            new Date().toString(),
            new Date().toLocaleString(),
            new Date().getTimezoneOffset(),
            navigator && navigator.userAgent, // react-native might not have a navigator
            moment.version,
        ]);

μ‚°μΆœ:

[
  "Wed Oct 09 2019 18:52:16 GMT-0700 (PDT)",
  "09/10/2019 Γ  18:52:16", // This particular device is configured as fr-FR
  420,
  null,
  "2.24.0"
]

μΆ”κ°€ μ»¨ν…μŠ€νŠΈ

κ΄€λ ¨ ν‹°μΌ“

  • #5214 - 여기에 μ»¨ν…μŠ€νŠΈκ°€ 적고 λ‹€λ₯Έ APIλ₯Ό μ‚¬μš©ν•˜κ³  λ‹€λ₯Έ 였λ₯˜ λ©”μ‹œμ§€κ°€ ν‘œμ‹œλ˜κΈ° λ•Œλ¬Έμ— λ‹€λ¦…λ‹ˆλ‹€. λ°˜μ‘ λ„€μ΄ν‹°λΈŒλ„ μ œμ•ˆν•˜λŠ” 릴리슀 λΉŒλ“œμ—μ„œλ§Œ λ°œμƒν•˜κΈ° λ•Œλ¬Έμ— μœ μ‚¬ν•˜μ§€λ§Œ ios-simulator/iosμ—μ„œλ§Œ μž¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.
  • #3872
  • #2979

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

참쑰된 라인은 λŸ°νƒ€μž„μ— λͺ¨λ“ˆμ„ μš”κ΅¬ν•˜λ €κ³  "μžλ™μœΌλ‘œ" μ‹œλ„ν•˜μ§€λ§Œ, λ‘œλ”© λ‘œμΌ€μΌ λ¬Έμ„œ λŠ” JSPMκ³Ό 같은 νŒ¨ν‚€μ§€ κ΄€λ¦¬μžλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 import "moment/locale/fr λ‘œμΌ€μΌμ„ λ‘œλ“œν•  수 μžˆμŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. νŒŒμΌμ„ 가져와야 ν•œλ‹€λŠ” 것을 "μ•ŒκΈ°" μœ„ν•΄ react-native νŒ¨ν‚€μ§€ κ΄€λ¦¬μžκ°€ ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— Packagerκ°€ λ²ˆλ“€λ‘œ ν¬ν•¨λ˜μ–΄μ•Ό ν•˜λŠ” λͺ¨λ“  νŒŒμΌμ„ "λ³Ό" 수 μžˆλ„λ‘ ν•΄λ‹Ή μŠ€νƒ€μΌμ˜ κ°€μ Έμ˜€κΈ°λ₯Ό μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€.

ꢁ극적으둜 μˆ˜μž… 라인은 λ‹€μŒκ³Ό κ°™μ•˜μŠ΅λ‹ˆλ‹€.

import moment from "moment";
import "moment/min/locales"; // Import all moment-locales -- it's just 400kb
import "moment-timezone";

require() 의 μ •ν™•ν•œ κ΅¬ν˜„μ€ μž‘μ—… 쀑인 λŸ°νƒ€μž„μ— μ˜ν•΄ μ£Όμž…λ˜λ©° μ΄λŠ” ν™•μ‹€νžˆ 디버그 및 릴리슀 λΉŒλ“œ 간에 크게 λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

react-nativeμ—λŠ” all-in-one-file, all-in-separate-files 및 RAM Bundlesλ₯Ό ν¬ν•¨ν•˜μ—¬ 릴리슀 λͺ¨λ“œ JavaScript λ²ˆλ“€λ§μ˜ μ—¬λŸ¬ λ‹€λ₯Έ νŠΉμ§•λ„ μžˆμŠ΅λ‹ˆλ‹€. 이듀 각각은 λ˜ν•œ require μž‘λ™ 방식을 λ³€κ²½ν•©λ‹ˆλ‹€. 디버그 require() λŠ” 둜컬 http μ„œλ²„μ—μ„œ μ‹€ν–‰λ˜λŠ” Metro Bundler에 μ—°κ²°ν•©λ‹ˆλ‹€. 이것은 μ•„λ§ˆλ„ webpack/jspm/기타 디버그 μ„œλ²„μ™€ 맀우 μœ μ‚¬ν•  κ²ƒμž…λ‹ˆλ‹€. 이것이 μ•„λ§ˆλ„ 앨리어싱이 ν•΄λ‹Ή ν™˜κ²½μ—μ„œ 문제λ₯Ό μΌμœΌν‚€μ§€ μ•ŠλŠ” 이유일 κ²ƒμž…λ‹ˆλ‹€.

λͺ¨λ“  4 λŒ“κΈ€

참쑰된 라인은 λŸ°νƒ€μž„μ— λͺ¨λ“ˆμ„ μš”κ΅¬ν•˜λ €κ³  "μžλ™μœΌλ‘œ" μ‹œλ„ν•˜μ§€λ§Œ, λ‘œλ”© λ‘œμΌ€μΌ λ¬Έμ„œ λŠ” JSPMκ³Ό 같은 νŒ¨ν‚€μ§€ κ΄€λ¦¬μžλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 import "moment/locale/fr λ‘œμΌ€μΌμ„ λ‘œλ“œν•  수 μžˆμŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. νŒŒμΌμ„ 가져와야 ν•œλ‹€λŠ” 것을 "μ•ŒκΈ°" μœ„ν•΄ react-native νŒ¨ν‚€μ§€ κ΄€λ¦¬μžκ°€ ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— Packagerκ°€ λ²ˆλ“€λ‘œ ν¬ν•¨λ˜μ–΄μ•Ό ν•˜λŠ” λͺ¨λ“  νŒŒμΌμ„ "λ³Ό" 수 μžˆλ„λ‘ ν•΄λ‹Ή μŠ€νƒ€μΌμ˜ κ°€μ Έμ˜€κΈ°λ₯Ό μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€.

ꢁ극적으둜 μˆ˜μž… 라인은 λ‹€μŒκ³Ό κ°™μ•˜μŠ΅λ‹ˆλ‹€.

import moment from "moment";
import "moment/min/locales"; // Import all moment-locales -- it's just 400kb
import "moment-timezone";

require() 의 μ •ν™•ν•œ κ΅¬ν˜„μ€ μž‘μ—… 쀑인 λŸ°νƒ€μž„μ— μ˜ν•΄ μ£Όμž…λ˜λ©° μ΄λŠ” ν™•μ‹€νžˆ 디버그 및 릴리슀 λΉŒλ“œ 간에 크게 λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

react-nativeμ—λŠ” all-in-one-file, all-in-separate-files 및 RAM Bundlesλ₯Ό ν¬ν•¨ν•˜μ—¬ 릴리슀 λͺ¨λ“œ JavaScript λ²ˆλ“€λ§μ˜ μ—¬λŸ¬ λ‹€λ₯Έ νŠΉμ§•λ„ μžˆμŠ΅λ‹ˆλ‹€. 이듀 각각은 λ˜ν•œ require μž‘λ™ 방식을 λ³€κ²½ν•©λ‹ˆλ‹€. 디버그 require() λŠ” 둜컬 http μ„œλ²„μ—μ„œ μ‹€ν–‰λ˜λŠ” Metro Bundler에 μ—°κ²°ν•©λ‹ˆλ‹€. 이것은 μ•„λ§ˆλ„ webpack/jspm/기타 디버그 μ„œλ²„μ™€ 맀우 μœ μ‚¬ν•  κ²ƒμž…λ‹ˆλ‹€. 이것이 μ•„λ§ˆλ„ 앨리어싱이 ν•΄λ‹Ή ν™˜κ²½μ—μ„œ 문제λ₯Ό μΌμœΌν‚€μ§€ μ•ŠλŠ” 이유일 κ²ƒμž…λ‹ˆλ‹€.

λ‚΄ μˆ˜μ • μ œμ•ˆ:

A. aliasedRequire μ‚­μ œν•˜λŠ” 것이 더 이상 μž‘μ—… 방식이 μ•„λ‹Œ 경우 + 이에 λŒ€ν•œ μ„€μΉ˜ 지침을 μ‘°μ •ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?
B. react-native λŒ€ λΈŒλΌμš°μ € 감지( navigator λŠ” react-nativeμ—μ„œλŠ” μ‚¬μš©ν•  수 μ—†μ§€λ§Œ μ—¬κΈ°μ—λŠ” λ‹€λ₯Έ 기술이 μžˆμŠ΅λ‹ˆλ‹€.), μš°λ¦¬κ°€ μ²˜ν•œ 상황에 따라 λ‹€λ₯΄κ²Œ μž‘λ™ν•©λ‹ˆκΉŒ? 예λ₯Ό λ“€μ–΄ react-native && DEV이면 λ‘œμΌ€μΌμ΄ 이둠적으둜 μ§€μ›λ˜μ§€λ§Œ 아직 required κ°€ μ•„λ‹Œ 경우 console.errorλ₯Ό μΈμ‡„ν•©λ‹ˆλ‹€(+ μ—…λ°μ΄νŠΈ λ¬Έμ„œ).
C. aliasedRequire λ₯Ό ν•΄λ‹Ή ν•¨μˆ˜μ˜ 둜컬 λ³€μˆ˜μ—μ„œ "μ„Έλ―Έ κΈ€λ‘œλ²Œ"둜 μ΄λ™ν•©λ‹ˆλ‹€. moment.aliasedRequire , 그런 μ‹μœΌλ‘œ μš°λ¦¬λŠ” no-op/do-nothing ν•¨μˆ˜λ₯Ό μ£Όμž…ν•˜μ—¬ aliasedRequire κ°€ react-nativeκ°€ 더 이상 μΆ©λŒμ„ μΌμœΌν‚¬ 수 없도둝 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μœ μ§€ κ΄€λ¦¬μžκ°€ λ‚΄κ°€ κ΅¬ν˜„ν•˜κΈ°λ₯Ό μ›ν•˜λŠ” μ˜΅μ…˜μ„ μ•Œλ €μ€„ 수 있고 Proposals B/C의 경우 μˆ˜λ½ν•˜λ €λŠ” μ •ν™•ν•œ κ΅¬ν˜„μ„ κ°œμ„ ν•˜λŠ” 데 도움이 λœλ‹€λ©΄ μ΄λŸ¬ν•œ μ˜΅μ…˜μ„ κ΅¬ν˜„ν•˜κ²Œ λ˜μ–΄ κΈ°μ©λ‹ˆλ‹€!

@marwahaha -- Moment의 ν”„λ‘œμ„ΈμŠ€κ°€ 무엇인지 ν™•μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚΄ μˆ˜μ • μ œμ•ˆμ— λŒ€ν•œ 의견이 μžˆμœΌμ‹­λ‹ˆκΉŒ? κΈ°μ—¬μž/μœ μ§€λ³΄μˆ˜μžκ°€ 받아듀일 수 μžˆλŠ” κ²½λ‘œμ— λŒ€ν•œ 쑰언을 λ°›μœΌλ©΄ PR을 κ΅¬ν˜„ν•˜κ²Œ λ˜μ–΄ κΈ°μ©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰