## 자바스크립트에서 세미콜론을 사용해야 할까? 

 

자바스크립트에는 ASI (아마 Auto Semicolon Insert ? ) 기능이 있음. 언제 나온건지는 모름 

 

ASI는 '지능'적으로 세미콜론이 위치해야할 자리에 자동으로 세미콜론을 삽입해준다. 

 

그러나 ASI가 잘못된 위치에 세미콜론을 삽입하는 경우가 있으며, 이는 아래와 같은 예시가 될 수 있다. 

 

function foo() { 
  return 
  { 
  "foo" : "foo"
  } 
}

 

개발자의 의도로서는 foo 함수의 반환값은 foo 라는 속성을 가진 객체를 리턴해야한다. 

그러나 ASI로 인해서 아래와 같은 코드로 만들어질 수 있다. 

 

function foo() { 
  return; 
  {
  "foo" : "foo" 
  }; 
}

 

ASI로 인해 개발자가 의도한 코드와는 다르게 함수에 진입하자마자 종료를 해버리게 된다. 

 

사실 이러한 문제는 아주 간단하게 해결할 수 있는데, 

 

function foo() { 
  return { 
  "foo" : "foo"
  } 
}

 

이렇게 코드를 작성한다면 세미콜론의 위치가 처음 봤던 코드랑은 다를것이다. 

 

간단하게 알아본 코드를 통해 내가 생각하게된 것은

 

세미콜론을 붙일것인가 말것인가는 ASI의 동작 방식을 알고있다면 

 

세미콜론을 사용하지 않아도 개발자가 의도한 방식으로 세미콜론을 생성해줄 것이다. 

 

결론!

 

세미콜론을 사용하는 것은 개발자의 기호이고, 통일만 하면 된다고 생각하며,

 

ASI의 동작방식을 터득했다면 세미콜론을 붙이는 수고를 덜고 블필요한 코드를 작성하지 않을 수 있게 될것이라고

 

생각한다.

 

자바스크립트로 개발해본적도 없지만,,, 이상 간단하게 알아본 자바스크립트 세미콜론에 대한 고찰 끝!

 

다른 의견이나 잘못된 점은 댓글로 알려주시면 감사하겠습니다. ㅎㅅㅎ

안드로이드 앱 개발 중 JNI측에서 발생한 크래시의 경우 크래시가 발생하면서 앱이 종료되고 다시 시작되는데, 이 때 크래시가 발생한 순간의 로그를 안드로이드 스튜디오 로그캣에서 확인할 수 없을 때가 있다.

 

이 로그를 확인하는 방법을 간단하게 알아보자.

 

1. 로그를 추출할 기기가 연결하기

2. adb shell bugreport > [로그저장위치][log.txt]

 

 텍스트파일을 확인하면 JNI측에서 발생한 로그를 확인할 수 있다.

 

 

vcpkg로 boost 설치 후 cmake에서 경로 찾지 못할 때 직접 경로정해주는 방법


CMake Warning at C:/cmake-3.22.0-rc3-windows-x86_64/share/cmake-3.22/Modules/FindBoost.cmake:1015 (message):
  Imported targets and dependency information not available for Boost version
  0.0.0 (all versions older than 1.33)

-DBoost_INCLUDE_DIR="VCPKG_PATH\installed\x64-windows\include" -DBoost_LIBRARY_DIR="VCPKG_PATH\installed\x64-windows\lib"

 

기존 안드로이드 프로젝트에서 free, paid Version 구성 또는 인앱 결제 모델, 구독 결제 모델을 나누는 방법으로 좋은 Flavor에 대해서 알아보겠습니다 ㅎㅅㅎ

 

Flavor란 무엇일까?

Flavor이란 Gradle에서 제공하는 옵션으로, Flavor를 통해 한 프로젝트에서 여러개의 빌드 버전을 생성할 수 있습니다.  필자는 안드로이드 개발 중 구독, 인앱 결제를 제외하고 같은 기능을 수행하는 프로젝트를 병합하기 위해 사용했습니다.

 

Flavor를 통해 여러 빌드를 생성하는 방법

 

 

applicationIdSuffix는 프로젝트 패키지 마지막에 설정될 이름을 설정할 수 있습니다. 이 옵션을 통해 구글 플레이에 각각 다른 패키지 명으로 앱을 추가할 수 있습니다.

manifestPlaceHolder는 AndroidManifest.xml 파일에 변수를 주입할 수 있습니다. 필자의 경우 앱 이름을 manifest에 앱 이름을 설정하는데 사용했습니다.

 

여기까지 설정되었다면 gradle Sync Now를 실행하면 아래와 같이 Build Variants에 Flavor 마다 Debug, Release가 생성된것을 확인할 수 있습니다.

그렇다면 각각 free, pro 버전을 분기하는 방법에 대해 알아보겠습니다.

 

만약 pro 버전과 free 버전을 나누는 부분이라면 pro 버전의 경우 광고가 표시되지 않고, free 버전의 경우 사용시 광고가 표시되는 등의 기능을 제외하고는 모두 같은 기능을 공유하게 될 것입니다.

제가 테스트했던 두가지 방법을 소개해드립니다.

 

1. 버전마다 디렉토리 생성 하여 클래스 파일로 분기하기

우선 프로젝트 구조를 Android 에서 Project로 변경합니다.

 

이후 디렉토리 구조를 위와같이 생성해줍니다.

build.gradle에 선언된 id와 같은 구조로 생성되어야 합니다. (이거때메 조금 헤매었음;;)

저는 free 버전을 main으로 사용하고, pro 버전을 새로 생성하여 테스트 했습니다.

 

pro버전의 AndroidManifest.xml 파일의 불필요한 코드를 제거해줍니다.

pro 버전이지만 패키지 이름이 com.hyeonwoo.free 인것을 주의해주셔야 합니다.

pro로 바꾸면 오류남여;

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hyeonwoo.free">

    <application>
        <activity android:name="com.hyeonwoo.pro.MainActivity">
        </activity>
    </application>

</manifest>

 

이후 각각 flavors에 따라 xml 파일에 표시되는 문자를 변경하여 테스트 해보시면 됩니다.

 

2. 하나의 소스코드로 BuildConfig에 따라 분기하기

분기할 코드의 양이 적다면 이 방법이 더 편리할 수 있어보입니다.

 

위의 디렉토리 구조 생성을 스킵하시고 build.gradle로 이동합니다.

flavorDimensions "version"
    productFlavors {
        free {
            applicationIdSuffix ".free"
            manifestPlaceholders = [appLabel: "free Version"]
            buildConfigField "boolean", "PRO_VERSION", 'false'
        }
        pro {
            applicationIdSuffix ".pro"
            manifestPlaceholders = [appLabel: "[pro Version"]
            buildConfigField "boolean", "PRO_VERSION", 'true'
        }
    }

 

buildConfigField를 사용하여 PRO_VERSION 이라는 boolean 타입 변수를 생성해줬습니다.

이제 한 액티비티에서 빌드 버전에 따라 분기할 수 있습니다.

package com.hyeonwoo.free;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (BuildConfig.PRO_VERSION) {
            Log.d("MainActivity", "Pro Version");
        } else {
            Log.d("MainActivity", "Free Version");
        }
    }
}

빌드스크립트를 사용하시는 경우 각 빌드에따라 signingConfig도 설정하실 수 있읍니당 ㅎㅅㅎ 

마지막으로 데모코드는 제 깃헙에서 확인하실 수 있습니다.

 

https://github.com/gogoadl/Android_FlavorsDemo

 

GitHub - gogoadl/Android_FlavorsDemo: Flavors 적용 데모입니다.

Flavors 적용 데모입니다. Contribute to gogoadl/Android_FlavorsDemo development by creating an account on GitHub.

github.com

질문이나 추가하실 사항이 있다면 댓글남겨주세요!

JavaScript ES6 문법 정리

const and let

ES6에서 추가된 변수 선언 방법입니다.

변수 재 선언

var의 경우 변수를 한번 더 선언했음에도 오류가 발생하지 않습니다.

var foo = "foo"
console.log(foo) // foo
var foo = "pee"
console.log(pee) // pee

let의 경우 변수를 한번 더 선언할 경우 오류가 발생합니다. (const의 경우도 마찬가지로 오류가 발생합니다.)

let foo = "foo"
console.log(foo)
let foo = "pee" // Uncaught SyntaxError: Identifier 'foo' has already been declared
console.log(foo)

const 와 let 차이점

let의 경우 값의 재할당이 가능하지만, const에서는 값을 재할당 할 수 없습니다.

let foo = "foo"
console.log(foo)
// let foo = "pee" // Uncaught SyntaxError: Identifier 'foo' has already been declared
// console.log(foo)
foo = "pee"
console.log(foo)

const foo = "foo"
console.log(foo)
foo = "pee" // Uncaught TypeError: Assignment to constant variable.
console.log(foo)

var의 경우 변수 선언이 사용보다 늦어도 오류가 발생하지 않습니다.

console.log(foo) // undefined
var foo = "foo"

const와 let의 경우

console.log(foo) // Uncaught ReferenceError: Cannot access 'foo' before initialization
let foo = "foo" 

호이스팅

자바스크립트에서는 소스코드를 실행하기전에 소스코드 평가 과정이라는 것을 거치게 됩니다.
이 때 모든 변수와 함수의 선언을 스코프 최상단으로 올리게 되는데, 이를 호이스팅이라고 말합니다.

위 처럼 var이 undefined로 오류가 발생하지 않고 실행된 이유는 호이스팅 때문인데,
위의 var을 사용한 변수 선언은 실제로 아래와 같이 표현됩니다.

var foo
console.log(foo) // undefined
foo = "foo"

그렇다면 let과 const는 호이스팅이 발생하지 않을까?

let, const도 호이스팅이 발생합니다.
그러나 var 처럼 undefined의 할당은 이루어지지 않고, 변수의 선언만 이루어집니다.
이게 구글링을 하다보면 호이스팅 발생한다는 사람들도 있고 아니라는 사람들도 있는데;;
Javascript 공식문서에서 호이스팅이 발생한다고 설명하고 있습니다.
다른 글들에 속지마시길!

화살표 함수

ES6에서 새로 등장한 함수를 선언하는 방법으로 전통적인 함수표현의 간편한 대안이다. (더 간결하다.)

ES5 함수 선언

var foo = function fooFunction(x) { return x * x } 

ES6 화살표 함수 선언

var foo = x => { return x * x }

const(or var or let) 변수명 = (매개변수1, 매개변수2) => { 함수 몸통 }

  • 매개변수가 없을 경우 : () (빈 소괄호를 이용)
  • 매개변수가 하나일 경우 : 매개변수 (소괄호 생략 가능)

람다식을 아신다면 람다식과 비슷하다고 볼 수 있을 것 같습니다.

템플릿 리터럴

문자열을 연결하기 위해 더하기(+) 연산자를 사용할 필요없이
백틱(`)을 사용하여 문자열 내에서 변수를 사용할 수 있습니다.

이전 문법 

function foo(name, age) {
    return name + "의 나이는 " + age + "입니다." 
}
console.log(foo("찬해형", 27)) // 찬해형의 나이는 27입니다.  

템플릿 리터럴 이용

const foo = (name, age) => {
    return `${name}의 나이는 ${age}입니다.`
}
console.log(foo("찬해형", 27)) // 찬해형의 나이는 27입니다.

기본 매개변수

매개 변수를 쓰지 않은 경우 함수의 매개변수에 기본값이 정의되어 있다면 기본값을 사용하도록 합니다.
const foo = (age = 5) => {
return 나이는 ${age}
}
console.log(foo()) // 나이는 5

배열 및 객체 비구조화 할당

비구조화를 통해 배열 또는 객체의 값을 새 변수에 더 쉽게 할당할 수 있습니다.

비구조화 할당을 사용하지 않을 경우 각각 변수 생성 후 object의 key에 접근하여 할당해야합니다.

const object = {
chanhae: "찬해",
inho: "인호",
hyeonwoo: "현우",
seungje: "승제"
}

const ch = object.chanhae
const ih = object.inho
const hw = object.hyeonwoo
const sj = object.seungje

console.log(ch)
console.log(ih)
console.log(hw)
console.log(sj)

비구조화 할당을 사용할 경우 코드가 훨씬 간단해집니다.

const object = {
chanhae: "찬해",
inho: "인호",
hyeonwoo: "현우",
seungje: "승제"
}

const {chanhae, inho, hyeonwoo, seungje} = object

console.log(chanhae)
console.log(inho)
console.log(hyeonwoo)
console.log(seungje)

만약 객체 내의 key값과 다른 이름으로 사용하고 싶다면 아래와 같이 합니다.

const {chanhae: ch, inho, hyeonwoo, seungje} = object

console.log(ch)
console.log(inho)
console.log(hyeonwoo)
console.log(seungje)

// 콜론과 함께 사용할 이름 지정. 
// 만약 객체의 key값과 다르게 사용하면 undefined가 반환됩니다.

비구조화 할당은 배열에서도 같은 방법으로 적용 가능합니다.

나머지 매개변수 및 확장 연산자

나머지 매개변수

현재 인덱스부터 마지막까지 하나의 변수에 할당하고 싶을 때 사용가능합니다.

const arr = ["찬해", "인호", "승제", "현우"]

const [ch, ih, ...rest] = arr

console.log(ch) // 찬해
console.log(ih) // 인호
console.log(rest) // ["승제", "현우"]

만약 arr의 값이 변경되면 나머지 매개변수 연산을 통해 얻은 배열의 값이 변경될까?

나머지 매개변수 사용
// 배열의 값을 변경하기위해 let 으로 선언
let arr = ["찬해", "인호", "승제", "현우"]
// 나머지 매개변수 이용하여 배열 복사
let [ch, ...rest] = arr
// 승제 자리 찬해로 변경
arr[2] = "찬해"

console.log(arr) // ["찬해", "인호", "찬해", "현우"]
console.log(rest) // ["인호", "승제", "현우"]

let arr = ["찬해", "인호", "승제", "현우"]

rest에 arr 바로 대입
let rest = arr

arr[2] = "찬해"

console.log(arr) // ["찬해", "인호", "찬해", "현우"]
console.log(rest) // ["찬해", "인호", "찬해", "현우"]

나머지 매개변수 연산에서는 arr의 값이 변경되어도 rest배열의 값은 변경되지 않았으므로, 깊은 복사가 일어난것을 알 수 있습니다.
배열을 그대로 변수에 대입할 경우, arr의 값이 변경되면 rest 배열의 값도 변경되었습니다.

전개 연산자

const arr = ["찬해", "인호"]
const arr2 = ["승제", "현우"]

const newarr = [...arr, ...arr2]
console.log(arr) // ["찬해", "인호"]
console.log(arr2) // ["승제", "현우"]
console.log(newarr) // ["찬해", "인호", "승제", "현우"]

배열을 이어 붙일 때 전개연산자를 통해 쉽게 이어붙일 수 있다.
객체에서도 가능!

const obj = {ch: "찬해", ih: "인호"}
const obj2 = {sj: "승제", hw: "현우"}

const newobj = {...obj, ...obj2}
console.log(obj) // { ch: "찬해",ih: "인호" }
console.log(obj) // { sj: "승제",hw: "현우" }
console.log(newobj) // { ch: "찬해",ih: "인호", sj: "승제", hw: "현우" }

프로미스

비동기 코드를 사용할 때 쓰기 좋은 ES6문법입니다.
이전에는 라이브러리로 이용할 수 있었으나, ES6부터 언어 차원에서 지원하게 되었다.
책에서는 ES5에서 기본으로 제공한다고 나와있는데.. 구글링하면 다 ES6부터라고 함;;
스택 오버플로우 문서찾아보니 ES6부터 지원하는게 맞는것 같음!

프로미스를 사용하지 않고 비동기 함수를 수행하는 방법

var async1 = function(param, callback) { callback(param*2); }
var async2 = function(param, callback) { callback(param*3); }
var async3 = function(param, callback) { callback(param*4); }

var start = 1;

async1(start, result => {
    async2(result, result => {
        async3(result, result => {
            console.log(result); // 24
        });
    });
});

보는것과 같이 callback 함수가 중첩되면서 들여쓰기 때문에 코드 가독성이 매우 떨어집니다.

function async1 (param) {
return new Promise(function(resolve, reject) { // 프로미스 객체 생성, resolve는 성공, reject는 실패
    resolve(param*2); // 요청이 성공했을 때 resolve를 보낼 수 있음. 만약 에러가 발생했다면 reject()로 오류전달
    });
}
function async2 (param) {
    return new Promise(function(resolve, reject) {
        resolve(param*3);
    });
}
function async3 (param) {
    return new Promise(function(resolve, reject) {
        resolve(param*4);
    });
}

var start = 1;
async1(start)
    .then(async2)
    .then(async3)
    .then(result => {
        console.log(result); // 24
    })
    .catch((err) => {
        console.log(err)
    });

프로미스 요청은 then 메소드로 비동기 요청을 이어붙일 수 있습니다. 이전 promise가 resolve되었다면 그 다음 promise가 실행됩니다.
여러개의 프로미스 체인중 하나라도 reject되었다면 마지막에 달린 catch()로 내려가서 에러를 처리합니다.

fetch 메서드로 promise 체인 사용해보기

function request() {
fetch('https://api.github.com/orgs/nodejs', {
    method: 'GET', // url에 get 요청 보냄.
})
.then(response => { // response 받은 값을 리턴
    return response.json();
})
.then(data => { // 리턴받은 값을 로그로 찍음
    console.log(data);
});
}

request();

실행가능한 코드는 모두 JSFiddle에서 테스트 했습니다.

Reference

https://velog.io/@kimhscom/JavaScript-%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-ES6-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC

https://velog.io/@recordboy/%EC%A0%84%EA%B0%9C-%EC%97%B0%EC%82%B0%EC%9E%90Spread-Operator

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

https://han41858.tistory.com/11

'TIL' 카테고리의 다른 글

함수 호출 규약(Calling Convention)과 마샬링(marshalling)  (1) 2023.10.17
[키워드 정리] VNC VS RDP, ICMP  (0) 2022.03.09
2021.09.11  (0) 2021.09.11
2021.09.09  (0) 2021.09.10
2021.09.08  (0) 2021.09.08

JSX = Javascript + XML

Javascript와 XML구문을 결합해 사용하는 코드를 JSX 라고한다.

자바스크립트 표준에 JSX 구문이 없지만, 포함된 것 처럼 동작할 수 있는 이유는 ESNext 자바스크립트 컴파일러인 바벨(babel)이 플러그인 구조로 동작하기 때문이다,

바벨은 ESNext 자바스크립트 코드를 만나면 파이프라인 형태로 동작하여 이해할 수 있는 구문만 컴파일하여 자바스크립트로 변환한다.

페이스북은 JSX 구문을 컴파일 하고자 @babel/plugin-trnasform-react-jsx 라는 바벨 플러그인을 제공한다.

 

jsx 구문이 있는 타입스크랍트 코드는 .tsx 여야하며, 다음 임포트 문이 필요하다.

import React from 'react'

 

React.createElement 사용은 아래의 형태로 구현하는데, 이를 JSX 형태로 변환해보자.

Virtuala_DOM_Object = React.createElement(component_name, attribute_object, child_component)

<component_name>child_component</component_name> // JSX

그러므로 JSX 객체는 실제로는 createElement를 호출하는 것이다.

 

표현식과 실행문 그리고 JSX

 

표현식 : 1, true, "Hello World!"처럼 값으로 평가되는 어떤 것.

실행문 : if, switch/case, for 같은 그 자체로는 값이 아닌 것.

 

JSX문 안에서는 실행문을 사용하면 오류가 발생한다.

<SafeAreaView>

{console.log("test")} // error

</SafeAreaView>



<SafeAreaView>

if (isLoading) {

do something.. // error

}

</SafeAreaView>

 

오류가 발생하는 이유는 JSX 코드를 구성하는 한줄 한줄이 모두 React.CreateElement 호출 코드로 변환되어야 하는데, console.log는 변환이 불가능하므로.

 

오류를 해결하는 방법으로는 이러한 구문을

+ JSX 문 바깥에 두는 방법

+ 조건문을 단축 평가 코드로 바꿔 문제 해결

ex)

<SafeAreaView>

{isLoading && <Text>loading</Text>}

{!isLoadiong && <Text>Hello World!</Text>}

</SafeAreaView>

+ JSX 문을 변수에 담아 문제 해결

ex)

const children = isLoading ? (

<Text>loading..</Text>

) : (

<Text>Hello World!</Text>

)

 

컴포넌트와 속성 이해하기

faker 외부 패키지 : 가짜 데이터를 만드는 패키지

자바스크립트로 만들어진 패키지이므로, 타입스크립트에서 사용하려면 @types/faker 타입 라이브러리 사용

 

사용자 컴포넌트

객체지향 프로그래밍에서 컴포넌트는 UI를 담당하는 클래스를 의미합니다.

오랫동안 리액트와 리액트 네이티브 프레임워크에서는 객체지향 방식인 클래스 컴포넌트를 사용했습니다.

 

그러다 함수로 구현되는 함수 컴포넌트가 도입되었고, 버전 16.8 에서 리액트 훅 기능이 새로 도입되면서 함수 컴포넌트 + 리액트 훅을 사용할것을 장려하고 있습니다.

 

클래스 컴포넌트

 

반드시 Component 클래스를 상속 받아야한다.

render method는 반드시 null, undefined, React.createElement 호출로 얻은 반환값이나 JSX 문 중 하나를 반환해야한다.

 

화살표 방식 함수 컴포넌트

 

클래스 컴포넌트의 render 메소드는 함수형 컴포넌트에서는 함수 몸통에 구현하면된다. (같은 역할을 한다.)

요즘 많이 사용되는 리액트 훅을 사용할 수 있다. (클래스 컴포넌트는 사용할 수 없음.)

 

속성이란?

속성이란 클래스의 멤버변수를 의미한다.

재렌더링이란 리액트와 리액트 네이티브에서 바뀐 속성값을 화면에 반영하는 것을 의마한다.

리액트와 리액트 네이티브에서 속성은 클래스 속성 + 재렌더링을 의미한다.

 

 

이제서야 함수형 컴포넌트와 클래스 컴포넌트 구분할 수 있겠다.... 화이팅하자

'TIL' 카테고리의 다른 글

[키워드 정리] VNC VS RDP, ICMP  (0) 2022.03.09
JavaScript ES6 문법 정리  (0) 2021.10.17
2021.09.09  (0) 2021.09.10
2021.09.08  (0) 2021.09.08
[TIL] python OpenCV - threshold 함수로 경계선 얻기  (0) 2021.07.26

npm run ios 빌드오류

React Native- Failed to build IOS project. We ran "xcodebuild" command but it exited with error code 65

위와 같은 오류가 발생했고, 구글링 과정에서 ios/pods/podfile 수정을 통해 해결할 수 있다고 해서 변경했다.

use_flipper ~

post_install do |installer|

flipper_post_install(installer)

end

 

이부분 삭제하고 저장.

 

수정 후

pod deintegrate

pod install

 

여기까지 수행하고 오류 그대로 발생. 그러나 오류코드 하단에

 

nvm is not compatible with the "npm_config_prefix" environment variable: currently set to "opt/homebrew"

Run 'unset npm_config_prefix' to unset it

 

이라는 메세지가 있어서

unset npm_config_prefix

수행 후 빌드 성공했다.

리액트 네이티브 개발에서 사용하는 명령

  • npm i

package.json 파일에 명시된 패키지를 node_modules 디렉터리에 설치

설치한 패키지는 android나 ios 디렉터리의 네이티브 모듈에서 동작하는 파일을 가진다.

  • npm pod-install

objc와 같은 c계열 언어는 원격 저장소에서 패키지를 내려받아 설치하는 기능이 없다.

따라서 pod 프로그램을 통해 패키지를 설치해야하므로 사용

  • npm start

npm run android, npm run ios 명령은 네이티브 부분 앱을 빌드하여 에뮬레이터에 설치하고 자동으로 실행한다.

에뮬레이터에 설치된 앱은 처음 실행될 때 메트로 서버에서 ES5자바스크립트 코드를 내려받는다.

그러므로 위의 명령을 실행하기 전에 npm start로 메트로 서버를 실행한다.

npm 과 npx

npm : Package Manager (관리)

npx : Package Runner (실행)

 

npx는 npm의 5.2.0 버전부터 새로 추가된 도구. 따라서 npm과 비교대상이 아닌 npm을 좀 더 편하게 사용하기 위해서 npm에서 제공해주는 하나의 도구.

 

등장 배경

 

npm 패키지 설치할 때 두가지 케이스가 있다.

  1. 전역으로 패키지를 설치하여 의존성 라이브러리들을 전체적으로 관리하는 방법
  2. 특정 프로젝트에만 의존성 라이브러리를 설치하는 방법

npx를 언제 사용할까?

  • npm run-script를 사용하지 않고 로컬에 설치된 패키지를 사용할 경우
  • 일회성 명령으로 패키지를 실행할 경우 -> 로컬에 설치된 패키지가 없다면 install및 호출을 한번에 해준다.
  • gist_based scripts를 실행할 경우 -> gist라는 곳에 스크립트를 올리고 npx {gist url}로 쉽게 코드 실행이가능하다.
  • 특정 노드 버전의 스크립트를 실행할 경우

npm run ios 빌드오류

React Native- Failed to build IOS project. We ran "xcodebuild" command but it exited with error code 65

위와 같은 오류가 발생했고, 구글링 과정에서 ios/pods/podfile 수정을 통해 해결할 수 있다고 해서 변경했다.

use_flipper ~

post_install do |installer|

flipper_post_install(installer)

end

 

이부분 삭제하고 저장.

 

수정 후

pod deintegrate

pod install

 

여기까지 수행하고 오류 그대로 발생. 그러나 오류코드 하단에

 

nvm is not compatible with the "npm_config_prefix" environment variable: currently set to "opt/homebrew"

Run 'unset npm_config_prefix' to unset it

 

이라는 메세지가 있어서

unset npm_config_prefix

수행 후 빌드 성공했다.

'TIL' 카테고리의 다른 글

JavaScript ES6 문법 정리  (0) 2021.10.17
2021.09.11  (0) 2021.09.11
2021.09.08  (0) 2021.09.08
[TIL] python OpenCV - threshold 함수로 경계선 얻기  (0) 2021.07.26
[TIL] python OpenCV - 1  (1) 2021.07.26

Git Flow

 

회사에서 사용하는 Git Flow 사용에 대해 오해가 있었다. 맨날 나만몰라...🥲

 

오늘 처음으로 팀 미팅이 있었는데, 회사의 개발 전략에 대해서 소개했었다.

Git Flow에 대해 소개하는 시간이 있었는데, Origin Remote Repository와 Remote Branch의 개념이 헷갈렸었다. 하 소개하는놈이

Github 의 React Repository의 경우로 생각하면 Upstream Remote Repositry의 경우 레포지토리의 주인인 Facebook이 React Repository의 Upstream Remote Repository일 것이다.

이를 내가 fork 할 경우 내 계정에 생성된 React 레포지토리가 Origin Remote Repository가 될것이다.

여기서 내 github에 있는 레포지토리를 clone 해서 로컬 PC에 저장하면 Local Repository가 된다고 보면된다.

 

항상 좋은 분위기로 정답을 이끌어주는 찬해형에게 감사를... ㅠ

 

Expo VS React-Native

 

Expo의 장점

- Expo앱을 개인 핸드폰에 설치하여 장치에서 쉽게 테스트, 디버깅이 가능하다

- Xcode, Android Studio 설치와 개발자 계정, signing.. 등의 번거로운 과정없이 바로 개발 가능하다. (이 부분은 구글링을 통해 검증하지 못했다.)

 

Expo 단점

- RN의 완전한 기능을 사용할 수 없다. (EXPO에서 제공하는 API만 사용가능하다.)

- OAuth2.0, Map API 사용에 어려움이 있다.

- 빌드시간이 오래걸린다. (찬해형 피셜 최악이었다고한다.)

 

사실 Expo의 장점에 대해서 크게 이점이라고 다가오는게 없었기도 했고, 구글의 방대한 자료(한국어 한정)에서도 Expo 사용에 긍정적인 반응이 크게 없었던것으로 봐서는 RN만으로 개발을 하는게 안전하지 않을까 싶다.

 

팀에 꼭 필요한 사람이 되자.

오늘 발표 절어서 매우 부끄러우니 다음에는 더 잘 할 수 있도록 하자.

좀더 노력하자. (맨날 핑계대지말고 좀 하자)

 

 

Reference

https://velog.io/@max9106/React-Native-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8Creact-native-%EB%91%90-%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95-c4k0gxe0tc

 

[React Native] 리액트 네이티브(react native) 두 가지 방법 #1 Expo CLI

리액트 네이티브 개발 방법 리액트 네이티브는 아래와 같이 2가지 개발 방법이있다. Expo CLI React Native CLI Expo란? 쉽게 말해, 리엑트 네이티브로 하는 개발을 쉽게 할 수 있게 해주는 것이다. 리엑

velog.io

https://floydkim.github.io/2019-05-04-React-Native-EXPO%EC%99%80-%EC%9D%B4%EB%B3%84%ED%95%98%EA%B8%B0/

 

React native : expo와 이별하기

EXPO와 이별하기 React-Native를 이용해 모바일 앱을 만들 때, EXPO는 개발자가 앱 코딩을 빨리 시작할 수 있도록 도와줍니다. EXPO 없이 React-Native만으로 개발을 시작하려면 Xcode나 Android Studio를 설치하

floydkim.github.io

https://medium.com/official-podo/expo%EB%A1%9C-%EC%95%B1-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B8-%ED%9B%84%EA%B8%B0-vs-vanilla-react-native-fc20c8dac937

 

expo로 앱 만들어본 후기(vs vanilla react-native)

함께해서 즐거웠고 다신 만나지 말자✋

medium.com

 

'TIL' 카테고리의 다른 글

2021.09.11  (0) 2021.09.11
2021.09.09  (0) 2021.09.10
[TIL] python OpenCV - threshold 함수로 경계선 얻기  (0) 2021.07.26
[TIL] python OpenCV - 1  (1) 2021.07.26
외부에서 내 컴퓨터 접속하기 (apache, 포트포워딩)  (1) 2021.03.29

문제 설명

개발자가 사용하는 언어와 언어 선호도를 입력하면 그에 맞는 직업군을 추천해주는 알고리즘을 개발하려고 합니다.

아래 표는 5개 직업군 별로 많이 사용하는 5개 언어에 직업군 언어 점수를 부여한 표입니다.

점수SI CONTENTS HARDWARE PORTAL GAME

5 JAVA JAVASCRIPT C JAVA C++
4 JAVASCRIPT JAVA C++ JAVASCRIPT C#
3 SQL PYTHON PYTHON PYTHON JAVASCRIPT
2 PYTHON SQL JAVA KOTLIN C
1 C# C++ JAVASCRIPT PHP JAVA

예를 들면, SQL의 SI 직업군 언어 점수는 3점이지만 CONTENTS 직업군 언어 점수는 2점입니다. SQL의 HARDWARE, PORTAL, GAME 직업군 언어 점수는 0점입니다.

직업군 언어 점수를 정리한 문자열 배열 table, 개발자가 사용하는 언어를 담은 문자열 배열 languages, 언어 선호도를 담은 정수 배열 preference가 매개변수로 주어집니다. 개발자가 사용하는 언어의 언어 선호도 x 직업군 언어 점수의 총합이 가장 높은 직업군을 return 하도록 solution 함수를 완성해주세요. 총합이 같은 직업군이 여러 개일 경우, 이름이 사전 순으로 가장 빠른 직업군을 return 해주세요.


제한사항

  • table의 길이 = 5
    • table의 원소는 "직업군 5점언어 4점언어 3점언어 2점언어 1점언어"형식의 문자열입니다. 직업군, 5점언어, 4언어, 3점언어, 2점언어, 1점언어는 하나의 공백으로 구분되어 있습니다.
    • table은 모든 테스트케이스에서 동일합니다.
  • 1 ≤ languages의 길이 ≤ 9
    • languages의 원소는 "JAVA", "JAVASCRIPT", "C", "C++" ,"C#" , "SQL", "PYTHON", "KOTLIN", "PHP" 중 한 개 이상으로 이루어져 있습니다.
    • languages의 원소는 중복되지 않습니다.
  • preference의 길이 = languages의 길이
    • 1 ≤ preference의 원소 ≤ 10
  • preference의 i번째 원소는 languages의 i번째 원소의 언어 선호도입니다.
  • return 할 문자열은 "SI", "CONTENTS", "HARDWARE", "PORTAL", "GAME" 중 하나입니다.

입출력 예

tablelanguagespreferenceresult

["SI JAVA JAVASCRIPT SQL PYTHON C#", "CONTENTS JAVASCRIPT JAVA PYTHON SQL C++", "HARDWARE C C++ PYTHON JAVA JAVASCRIPT", "PORTAL JAVA JAVASCRIPT PYTHON KOTLIN PHP", "GAME C++ C# JAVASCRIPT C JAVA"] ["PYTHON", "C++", "SQL"] [7, 5, 5] "HARDWARE"
["SI JAVA JAVASCRIPT SQL PYTHON C#", "CONTENTS JAVASCRIPT JAVA PYTHON SQL C++", "HARDWARE C C++ PYTHON JAVA JAVASCRIPT", "PORTAL JAVA JAVASCRIPT PYTHON KOTLIN PHP", "GAME C++ C# JAVASCRIPT C JAVA"] ["JAVA", "JAVASCRIPT"] [7, 5] "PORTAL"

입출력 예 설명

입출력 예 #1

각 직업군 별로 점수를 계산해보면 아래와 같습니다.

아래 사진은 개발자 언어 선호도 나타낸 표입니다.

아래 사진은 개발자가 선호하는 언어의 직업군 언어 점수를 나타낸 표입니다.

따라서 점수 총합이 41로 가장 높은 "HARDWARE"를 return 해야 합니다.

입출력 예 #2

각 직업군 별로 점수를 계산해보면 아래와 같습니다.

아래 사진은 개발자 언어 선호도 나타낸 표입니다.

아래 사진은 개발자가 선호하는 언어의 직업군 언어 점수를 나타낸 표입니다.


점수 총합이 55로 가장 높은 직업군은 "SI" 와 "PORTAL"입니다.
따라서 사전 순으로 먼저 오는 "PORTAL"을 return 해야 합니다.

 

나의 풀이

첫번째 파라미터로 오는 배열을 보면 첫번째 값에는 직업군, 그 이후에는 언어가 오게되므로 우선 하나의 문자열을 분리시켰다.

그 이후 점수 총합과 직업군을 저장하기위해 key, value로 값을 저장하는 hashMap을 사용하여 점수 총합과 직업을 저장했다.

만약 점수가 같은 직업이 있다면 정렬을 통해 사전순서가 빠른 직업군을 리턴하도록 했다.

 

코틀린 언어가 익숙하지 않아서 조금 헤매었는데 풀고나니 조타 ㅎㅅㅎ

+ 프로그래머스와 내 로컬환경의 컴파일옵션이 달라서 그런지 내 노트북에서는 잘 컴파일 되었는데 프로그래머스에서 실행하면

오류가 많이 떠서 수정하는데 시간이 좀 걸렸다. 

import kotlin.collections.HashMap

class Solution {
   fun solution(table: Array<String>, languages: Array<String>, preference: IntArray): String {

        var hashMap = HashMap<String, Int>()
        for (i in table.indices) { // 첫번째 배열 아이템 나누기
            var tableArr = table[i].split(" ")
            var sum = 0

            for (j in languages.indices) {
                var idx = tableArr.indexOf(languages[j])
                if (idx != -1) {
                    var size = tableArr.size - idx
                    sum += size * preference[j]
                }
            }
            hashMap.put(tableArr[0],sum)
        }
        var maxVal = hashMap.values.max()
        var answers = hashMap.filter { it.value == maxVal }
        return answers.keys.min()!!
    }
}

+ Recent posts