728x90

개발을 시작할때 한번쯤 공부하지만
세월이 지나면서 잊게되는 HTML 로드 순서.
그치만 웹 개발자라면 잊어서도 안되고 계속해서
공부해야한다.
브라우저는 계속 발전하기 때문에 새로이 업데이트 되는 사항들을 놓치지 말자.

--------------------------------

HTML이 브라우저에 의해 호출되면
기본적으로 위에서 아래의 순서로 파싱된다.

<html>
  <head></head>
  <body>
    <div>
      <p>Hello world</p>
    </div>
  </body>
</html>

위와 같다면 문제없이 위에서 아래로 파싱되며
끝이 난다.

문제는 script 태그를 만났을때다.
브라우저는 HTML을 읽다가 script 태그를 만나면
파싱을 중단하고 script태그를 다운로드 및 파싱한다.

여기서 두가지 문제가 발생한다.

[ 브라우저가 script 태그를 만났을 때, 발생할 수 있는 두가지 문제 ]
1. script 태그가 다운로드 되고 실행되는 것을 기다리느냐, 페이지 로딩이 지연된다.
2. script 태그가 하단의 dom 요소들 보다 먼저 파싱되기 때문에, 
   script 태그에서 dom요소에 접근하여 이벤트 핸들러를 등록하는 등의 행위가 불가능하다.


2번의 문제로 HTML, Javascript를 처음 배울때면
body 가장 밑쪽에 script태그를 배치하라고 배우게된다.


하지만, 그것만으로 모든 문제가 해결될까?
그것은 아니다.
페이지에서 핵심적으로 작용하는 script가 최하단에서 다운로드 및 파싱된다면
사용자가 끔찍한 화면을 본다거나,
에러상황을 마주하게 될 수 있다.

그리고 최신 웹사이트들은
써드파티 라이브러리를 많이 사용하다보니
script 태그를 예전보다 더 적극적으로 많이 사용하게된다.

혹은, 번들러를 통해 빌드하게되면
html에 상당히 많은 script 태그가 자동으로 추가된다.

페이지에 필수적으로 적용되는 script태그를
계속해서 페이지 최하단에 위치시킬것인가?


--------------------------------


그래서 script 태그에는 defer와 async라는 속성이 존재한다.
먼저, defer를 알아보자.

<html>
  <head>
    <script defer src="cdn-subway-tastgood.js" />
  </head>
  <body>
    <div>
      <p>Hello world</p>
    </div>
  </body>
</html>

위 처럼 defer가 적용된 script가 있을때
HTML의 로드 순서는 어떻게될까?

script는 완전히 독립적으로 실행되게 된다.
브라우저는 HTML을 읽다가 script를 만나도
파싱을 중단하지 않고 계속해서 아래로 파싱해나간다.

HTML을 읽다가 script 태그를 마주친 순간부터
script는 백그라운드(Background)에서 다운로드 된다.
defer script의 실행은 domContentLoaded 직전에 실행된다.
(* domcontentloaded 이벤트는 초기 HTML 문서를 완전히 불러오고 분석했을 때 발생하는 이벤트이다.)

따라서, 어느정도 실행 순서가 보장되며
페이지 로딩 속도를 지연시키지 않기 위한 방법이라고 볼 수 있다.


그렇다면 async는 어떨까?

<html>
  <head>
    <script async src="cdn-lotteria-tastgood.js" />
  </head>
  <body>
    <div>
      <p>Hello world</p>
    </div>
  </body>
</html>

async가 적용된 script를 만났을때 역시
파싱이 중단되지 않고 진행된다.
마찬가지로, 백그라운드에서 script가 다운로드된다.

async는 defer와 실행순서에 있어 차이가 있는데,
defer가 domcontentloaded 직전의 실행 시점을 갖는 반면
async는 백그라운드에서 다운로드가 완료된 순가 실행된다.
따라서, async는 그 실행순서가 보장되지는 않는다.

그래서 async는 써드파티 스크립트 중에서도
페이지의 핵심 기능과 독립적인 기능으로 동작하는..
예를들어, 광고나 페이지 방문자수 카운터 등에 사용된다.

728x90
반응형
728x90

에러상황

[!] The following Swift pods cannot yet be integrated as static libraries:

The Swift pod `FirebaseCoreInternal` depends upon `GoogleUtilities`, 
which does not define modules. To opt into those targets generating module maps 
(which is necessary to import them from Swift when building as static libraries), 

you may set `use_modular_headers!` globally in your Podfile, 
or specify `:modular_headers => true` for particular dependencies.

새프로젝트에서 위 같은 에러가 발생했다.

use_frameworks를 주석처리하니

dyld: Library not loaded
...

이와 같은 실행 오류가 발생했다.

많은 시행착오를 걸쳐 발견한 해결법은 아래와 같다

 

해결책

 

0) react-native version
version >= 0.70 인 경우 < 0.7 로 변경 (ex 0.65)

 

1) 맥 os 기분, 아래 경로에서 프로젝트 폴더 제거

/Library/Developer/Xcode/DerivedData

 

2) Podfile 확인/수정

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

use_frameworks! :linkage => :static

platform :ios, '12.4'
install! 'cocoapods', :deterministic_uuids => false

target 'myapp' do
  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'myappTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable the next line.
  # use_flipper!()

  post_install do |installer|
    react_native_post_install(installer)
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end

 

3) pod 갱신

Podfile.lock 제거
Pods 폴더 제거

pod install

 

 

4) 실행 및 확인

npm run ios
728x90
반응형
728x90

Cocoapods version 1.9+ allows linking of Swift static libraries, add the following command to your Podfile:

use_frameworks! :linkage => :static

 

전체 코드르 확인

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

use_frameworks! :linkage => :static

platform :ios, '12.4'
install! 'cocoapods', :deterministic_uuids => false

target 'testApp' do
 
end
728x90
반응형
728x90

테스트 코드를 어떻게 작성해 나갈지에 대해 공부해보고 있다.

 

공부하며 알게된 지식을 정리해본다.

 

NOTE 1.

테스트 코드가 나오려면 명세서가 있어야됨
따라서, 요구사항이 주어지면
1. 요구사항을 이해하는데 시간을 들여 요구의 숨겨진 의도는 없는지 이것으로 달성하고자 하는 목표는 무엇인지
충분히 심사숙고한다.
2. 어떻게 달성할지에 대해서 명세서를 직접 작성해보고 그것에 맞춰 테스트 코드를 작성한 뒤 본 코드를 작성한다.
3. 명세를 작성할때는 어떤 경우에 성공하는지, 혹은 어떤 경우에 실패하는지 모든 가능한 상황을 아울러 작성하도록 하며 기대되는 결과값에 기반해 테스트가 정상인지 확인하면 된다.
728x90
반응형
728x90

mac m1에 mongodb를 설치하는 과정에

작은 불편함을 겪었다.

 

각자 원하는 버전 혹은 권장버전의

mongodb 사이트에 접속한 뒤 아래의 과정을 밟아보자.

https://www.mongodb.com/docs/v4.4/tutorial/install-mongodb-on-os-x/

 

1. homebrew가 설치되어 있어야한다.

2. Install the Xcode command-line tools by running the following command in your macOS Terminal

xcode-select --install

3. Tap the MongoDB Homebrew Tap to download the official Homebrew formula for MongoDB

brew tap mongodb/brew

4. To update Homebrew and all existing formulae

brew update

5. To install MongoDB

// 자신이 원하는 버전
brew install mongodb-community@4.4

6. 

brew --prefix

7. 

brew info mongodb-community@4.4

---> 결과
echo 'export PATH="/opt/homebrew/opt/mongodb-community@4.4/bin:$PATH"' >> ~/.zshrc
라는 메시지 확인가능

8. zshrc 수정

export PATH="/opt/homebrew/opt/mongodb-community@4.4/bin:$PATH"

9. 실행

brew services start mongodb-community@4.4

10. 몽고 connect

mongo
728x90
반응형
728x90

react-native 개발을 하다보니

zulu jdk11 버전으로 jdk를 변경하게 되었다

 

jdk1.8등 기타 버전이 아닌

zulu jdk11을 설치하는 방법을 알아본다.

 

1.

brew tap mdogan/zulu

2.

brew install zulu-jdk11

3. 설치 완료 확인

java --version

4.

nano ~/.zshrc

// zshrc 맨 하단
export JAVA_HOME=`/usr/libexec/java_home -v 11`
export PATH=$PATH:$JAVA_HOME/bin

5. 변경된 zsh 적용

source ~/.zshrc

6. 잘 적용됐는지 확인

echo $JAVA_HOME
728x90
반응형
728x90

M1 맥을 새로 샀다.

homebrew를 설치하려니 인텔맥에서는 경험하지못한 에러가 발생했다.

"Warning: /opt/homebrew/bin is not in your PATH."

 

검색해 본 결과 M1 맥에서 발생하는 

설치오류 였고, 간단히 추가적인 입력으로 해결가능했다.

 

M1 맥에서 Homebrew설치하기

1. https://brew.sh/index_ko 접속

2. 코드라인 복사

3. 터미널에 입력

4. 패스워드 입력

5. return키 Press

6. 완료되면, 아래의 절차 이어서 진행

7. 

// 여기서 [user]에는 각 사용자 계정을 입력
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/[user]/.zprofile

8.

eval "$(/opt/homebrew/bin/brew shellenv)"

9. 설치 완료 확인

brew --version
728x90
반응형

'개발, 코딩' 카테고리의 다른 글

git 협업하기 - 실무편  (0) 2022.10.23
Webpack 구성 이해하기  (0) 2022.10.04
Rest API 정리  (0) 2022.09.29
java zulu jdk11 설치  (0) 2022.07.31
[21.08.23] 신규서비스 개발기 - 기획 및 자료조사  (0) 2021.08.23
728x90

채널톡이 그 영향력을 상당히 넓히고있다.

앱에서도 호환성이 제법 훌륭해서 회사에서도

2개 서비스 연속으로 채널톡을 쓰고있다.

 

이 전에는 겪지 못했지만

이번에 빌드 관련해서 이슈를 겪어 문제를 기록

 

ipatool failed with an exception: #<CmdSpec::NonZeroExitException: 
$ /Users/user/Desktop/Xcode.app/Contents/Developer/usr/bin/python3 
/Users/user/Desktop/Xcode.app/Contents/Developer/usr/bin/bitcode-build-tool -v -t 
/Users/user/Desktop/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin -L 
/var/folders/r0/5sczfh113kdczqhflxskvq080000gn/T/ipatool20220722-31944-15jg3ll/thinned-out/arm64/Payload/[project].app/Frameworks --sdk 
/Users/user/Desktop/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk -o 
/var/folders/r0/5sczfh113kdczqhflxskvq080000gn/T/ipatool20220722-31944-15jg3ll/thinned-out/arm64/Payload/[project].app/Frameworks/ChannelIOFront.framework/ChannelIOFront 
--generate-dsym /var/folders/r0/5sczfh113kdczqhflxskvq080000gn/T/ipatool20220722-31944-15jg3ll/thinned-out/arm64/Payload/[project].app/Frameworks/ChannelIOFront.framework/ChannelIOFront.dSYM 
--strip-swift-symbols /var/folders/r0/5sczfh113kdczqhflxskvq080000gn/T/ipatool20220722-31944-15jg3ll/thinned-in/arm64/Payload/[project].app/Frameworks/ChannelIOFront.framework/ChannelIOFront

Status: pid 32693 exit 1
Stdout:
SDK path: /Users/user/Desktop/Xcode.app/Contents/Developer/Platforms

 

시뮬레이터로 실행할때는 문제가 없었지만

ADHOC 빌드를 할 때 위와같은 이슈가 발생했다.

 

이슈를 추적한 결과

원인

아직 뚜렷한 원인이 밝혀진것은 아니나,
Xcode 12 이상의 버전을 사용하려는 경우, 특정 프레임워크와의 외부 종속성 문제로
프로젝트에서 비트코드를 비활성화하는 것 같다고 함.
따라서, 비트코드가 YES로 되어있는경우 빌드 에러가 발생.

해결책

[xcode]
Turn off Bitcode in Targets > Build Settings > Enable Bitcode.
728x90
반응형
728x90

제목 그대로의 상황이다.

방치해둔 서버의 용량이

각종 로그와 aws관련 버저닝 파일들로 인해 100%가 되어버렸다.

 

mongo는 더이상 저장이 불가능하자

다운되어 버렸다.

 

나중에 서버의 용량을 확보했지만

이미 다운된 몽고는 돌아오지 않았다.

 

다양한 방법의 실행 끝에

아래와 같은 방법을 통해 해결했다.

 

1. 로그 확인

/var/log/mongodb/mongod.conf

 

위 경로에서 로그를 확인할 수 있다.

 

나는 아래와 같은 에러 로그들을 볼수있었따.

WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
Failed to start up WiredTiger under any compatibility version.
Reason: 13: Permission denied

 

mongo, mongo status 체크를 할때도

아래와 같은 로그를 확인했었다.

Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused

 

2. 해결책

의외로 해결책을 한 한국인 분의 블로그에서 확인할 수 있었다.

chown -R mongodb:mongodb /var/lib/mongodb
chown mongodb:mongodb /tmp/mongodb-27017.sock

 

재실행

systemctl restart monogd
 
상태 확인
systemctl status mongod

mongo
 
728x90
반응형
728x90

애니메이션 뷰는 정말 다양한 상황에

유용하게 쓰인다.

 

구현 방법 또한

상당히 간단해서 누구든 쉽게 구현할수있다.

 

import React, { ReactChild, useEffect, useState } from 'react';
import { Animated } from 'react-native';

export function FadeDownView({ duration, children }: { duration?: number; children: ReactChild }) {
  const value = new Animated.Value(0);

  useEffect(() => {
    Animated.timing(value, {
      toValue: 1,
      duration: duration || 500,
      useNativeDriver: true
    }).start();
  }, [])

  return (
    <Animated.View
      style={{
        opacity: value,
        transform: [{
          translateY: value.interpolate({
            inputRange: [0, 1],
            outputRange: [-24 , 0]
          })
        }]
      }}
    >
      { children }
    </Animated.View>
  )
}

export function FadeLeftView({ duration, children }: { duration?: number; children: ReactChild }) {
  const value = new Animated.Value(0);

  useEffect(() => {
    Animated.timing(value, {
      toValue: 1,
      duration: duration || 500,
      useNativeDriver: true
    }).start();
  }, [])

  return (
    <Animated.View
      style={{
        opacity: value,
        transform: [{
          translateX: value.interpolate({
            inputRange: [0, 1],
            outputRange: [-50 , 0]
          })
        }]
      }}
    >
      { children }
    </Animated.View>
  )
}

export function FadeRightView({ duration, children }: { duration?: number; children: ReactChild }) {
  const value = new Animated.Value(0);

  useEffect(() => {
    Animated.timing(value, {
      toValue: 1,
      duration: duration || 500,
      useNativeDriver: true
    }).start();
  }, [])

  return (
    <Animated.View
      style={{
        opacity: value,
        transform: [{
          translateX: value.interpolate({
            inputRange: [0, 1],
            outputRange: [50 , 0]
          })
        }]
      }}
    >
      { children }
    </Animated.View>
  )
}

export function FadeUpView({ duration, children }: { duration?: number; children: ReactChild }) {
  const value = new Animated.Value(0);

  useEffect(() => {
     Animated.timing(value, {
      toValue: 1,
      duration: duration || 500,
      useNativeDriver: true
    }).start();
  }, [])

  return (
    <Animated.View
      style={{
        opacity: value,
        transform: [{
          translateY: value.interpolate({
            inputRange: [0, 1],
            outputRange: [24 , 0]
          })
        }]
      }}
    >
      { children }
    </Animated.View>
  )
}

 

이런식으로 상,화,좌,우 Fade In 효과를 만들 수 있다.

사용한다면 아래와 같이 쓸수 있을것이다.

 

function SampleView() {
  const [fire, setFire] = useState(false);
  
  return (
    <View>
    <TouchableOpacity onPress={() => { setFire(true); }}>
      <Text>Fire!!!</Text>
    </TouchableOpacity>
    
    {
      !!fire &&
      <FadeDownView duration={300}>
        <Text>위에서 아래로</Text>
      </FadeDownView>
    }
    </View>
  )
}
728x90
반응형