코딩, 개발에 대한 기록 저장소
레이블이 Javascript인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Javascript인 게시물을 표시합니다. 모든 게시물 표시

nvm default 변경

nvm 전체 버전 확인

$ nvm ls-remote
		v0.1.14
        v0.1.15
        v0.1.16
        v0.1.17
        ...
        v22.9.0
       v22.10.0
       v22.11.0   (Latest LTS: Jod)
        v23.0.0
        v23.1.0
        v23.2.0
        v23.3.0

원하는 버전 설치

$ nvm install v20.18.1
Downloading and installing node v20.18.1...
Downloading https://nodejs.org/dist/v20.18.1/node-v20.18.1-darwin-arm64.tar.xz...
#################################################################################################################################################################################################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v20.18.1 (npm v10.8.2)

설치된 버전 확인

$ nvm ls
       v18.16.1
->     v20.18.1
default -> 18.16 (-> v18.16.1)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v20.18.1) (default)
stable -> 20.18 (-> v20.18.1) (default)
lts/* -> lts/jod (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.3 (-> N/A)
lts/gallium -> v16.20.2 (-> N/A)
lts/hydrogen -> v18.20.5 (-> N/A)
lts/iron -> v20.18.1
lts/jod -> v22.11.0 (-> N/A)

nvm default 변경

$ nvm alias default 20.18.1
default -> 20.18.1 (-> v20.18.1)


m1에서 nvm 설치

Homebrew 가 미리 설치되어 있어야 함

brew 를 이용해 nvm 을 설치한다.

$ brew install nvm

.....

You should create NVM's working directory if it doesn't exist:
  mkdir ~/.nvm

Add the following to your shell profile e.g. ~/.profile or ~/.zshrc:
  export NVM_DIR="$HOME/.nvm"
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion

You can set $NVM_DIR to any location, but leaving it unchanged from
/opt/homebrew/Cellar/nvm/0.39.7 will destroy any nvm-installed Node installations
upon upgrade/reinstall.

.....

설치가 완료하고 터미널에 안내에 따라 설정한다.

디렉토리 생성

$ mkdir ~/.nvm

.zshrc 파일 수정

$ vi ~/.zshrc

아래 문장을 아래에 붙여넣은 후 저장
export NVM_DIR="$HOME/.nvm"
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion

변경사항 적용

$ source ~/.zshrc

설치 확인

$ nvm -v

node.js 설치

$ nvm install 18.16

또는

$ nvm install --lts

설치된 node.js 리스트 확인 및 특정 버전 선택

$ nvm ls
$ nvm use <version>


javascript forEach 사용시 주의사항

javascript forEach 사용시 주의사항

angularjs 로 프로젝트를 하던 중 정말 당황한 내용이 있어 정리합니다.

angularjs 라고는 해도 javascript 문법에 해당하며 아마도 자주 사용할 것으로 생각되는 forEach에 대한 내용입니다.

일단 제가 구현하고자 했던 내용은 다음과 같습니다.

  • registry.menus에 여러 menu 메뉴 정보가 배열로 들어 있고 각 menu 별로 id가 지정되어 있는 데이터가 있음
  • 함수의 파라메터로 id를 넘겨 데이터에 있는 menu.id 와 일치하면 해당되는 item을 리턴하도록 구현

저는 일반적인 for문을 생각하고 너무나 당연하게 아래와 같은 함수를 작성했지만 실제 결과는 계속해서 Not found가 로그에 찍혔습니다.

function functionA(id) {
    if (registry) {
        if (id) {
            registry.menus.forEach((menu, index, array) => {
                if (menu.id === id){
                    return menu.item;
                }
            });
            console.error("Not found : " + id);
            return null;
        }
    }
    return null;
}

아무리 console.log로 값을 찍어 보고, name과 menu.name의 타입을 비교해 봐도 id는 동일한데 말입니다.

한두시간정도 고민하다 도저히 이해가 가지 않아 옆자리 후임에게 물어 봤습니다.

본인 : "난 도저히 이해할 수 없다. 이거 왜 그런거냐?"

후임 : "혹시 return menu.items 에서 return 이 forEach만 빠져나오는 것은 아닐까요?"

바로 log를 찍어 봤습니다.

본인 : "..... 너 정말 대단하구나!"

결국 아래와 같이 수정했습니다.

function functionA(id) {
    if (registry) {
        if (id) {
            var item;
            registry.menus.forEach((menu, index, array) => {
                if (menu.id === id){
                    item = menu.item;
                    return;
                }
            });

            if(item){
                return item;
            }
            else{
                console.error("Not found : " + id);
                return null;
            }
        }
    }
    return null;
}

java, c 로 개발하시다 javascript를 접하시는 개발자분들께서 같은 고생 하지 않으시길 빕니다. ^^



nodejs get 방식 처리하기

nodejs로 웹 서버 혹은 API서버를 개발할때 기본이 되는 get방식 파라메터를 처리하는 방법을 정리합니다.

  var uri = req.url;
  var query = url.parse(uri, true).query;

  var param1 = query.param1;
  
  // param1이 없을 경우 처리
  if(isEmpty(param1)){
      param1 = null;
  }


nodejs post 방식 json body 처리하기

nodejs로 웹 서버 혹은 API서버를 개발할때 post방식으로 넘어오는 json body를 처리하는 방법을 정리합니다.

  if(req.is('application/json') === false){
    // json이 아닌 경우 에러처리
    return;
  }
  
  var jsonBody = req.body;
  
  var param1;
  if(jsonBody.hasOwnProperty('param1')){
    param1 = jsonBody.param1;
  }
  else{
    // param1이 없을 경우 처리
    return;
  }


ng-repeat vs data-ng-repeat 무엇이 다른가?

angularJS에 대해 검색을 하다보면 예제에서 "data-"가 붙은 경우가 있고 그렇지 않은 경우가 있습니다. "data-" 가 붙던 붙지 않던 기능들은 정상동작하는데 아무래도 찝찝합니다.

그래서 prefix로 붙는 "data-"에 대해 정리해 보았습니다.

ng-repeat vs data-ng-repeat

일단 동작은 동일 합니다.

다만, HTML5 validator에서 오류가 발생할 수 있는가? 에 대한 차이점이 있습니다.

"data-"를 prefix로 붙이면 오류가 발생되지 않는데, 그 이유에 대해서는 아래 링크에 설명된 태그 확장을 보시면 이해 할 수 있습니다.

https://stackoverflow.com/questions/16589853/ng-app-vs-data-ng-app-what-is-the-difference

결론은 "data-" 를 붙여 써야 한다입니다.

참고 사이트:
https://stackoverflow.com/questions/16589853/ng-app-vs-data-ng-app-what-is-the-difference



node package.json에 레포지토리 정의

npm WARN package.json No repository field

npm installpackage.json에 레포지토리 정의가 되지 않았다면 다음과 같은 경고가 발생함:

- npm WARN package.json myproject.com@1.0.0 No repository field.

해결 방법

프로젝트의 package.json에서 레포지토리를 정의해야 함.

"repository": {
  "type": "git",
  "url": "git://github.com/username/repository.git"
}

레포지토리에 게시하지 않고 개발하는 경우에는 "private": true 설정:

{
  "name": "myproject.com",
  "version": "1.0.0",
  "private": true
}


nodeJS 에서 db 설치, 설정, 사용 예제

nodeJS 에서 DB 설치, 설정, 사용 예제

nodeJS에서 DB를 사용하기 위한 기본 절차를 정리합니다.

MySQL 모듈 설치

MySQL 모듈을 설치합니다.

npm install mysql --save

DB 설정 파일 생성

DB 설정을 작업하기 편하게 다음과 같이 따로 분리하여 사용합니다.


// filename : db.js

var mysql = require('mysql');

var dbConfig = {
  host: 'xxx.xxx.xxx.xxx',
  port: '3306',
  user: 'myName',
  password: 'myPassword',
  connectionLimit: 10,
  waitForConnections: false,
  multipleStatements: true
};

var pool = mysql.createPool(dbConfig);

function getPool() {
  return pool;
}

exports.getPool = getPool;

사용 예

다음은 DB에서 SELECT 쿼리를 실행하는 예입니다.


// db.js 파일이 있는 위치를 지정
var db = require('db');

// db.js의 connection pool에서 connection 요청
db.getPool().getConnection(function(err, dbConn) {

  var sql = 'SELECT COUNT(*) FROM myTable';

  dbConn.query(
    sql,
    function(err, results, fields) {
      // 쿼리 실패시 에러 처리
      if (err) {
        dbConn.release();
        res.status(500);
        return;
      }

      // 쿼리 성공시 처리
      res.status(200);
      dbConn.release();
    }
  );
});


기본적인 DB 연결 예제에서 주의점 3가지 찾기

기본적인 DB 연결 예제

아래는 nodeJS에서 mysql 모듈을 사용하여 my_database 데이터베이스의 my_table 테이블에서 모든 데이터를 가져오는 예제입니다.

아주 기본적인 database 연결 예제입니다.
예제는 nodeJS지만 얘기하려는 내용은 대부분의 프로그래밍 언어에 포함됩니다.

const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'my_database'
});

connection.connect();

connection.query('SELECT * FROM my_table', (error, results, fields) => {
  if (error) throw error;
  console.log('The result is: ', results);
});

실무에 적용한다고 했을 때 이 간단한 예제 안에서 주의해야 할 사항이 3가지 있습니다.
.
.
아시겠나요??
.
.
어느정도 경험 많은 개발자분들은 느낌이 딱 오시겠지만 경험이 적은 개발자분들은 인터넷에서 찾은 예제코드를 그대로 사용하는 경우가 있기 때문에 그 주위사항을 정리하였습니다.

하드코딩된 연결 정보

호스트명, 계정 정보, 데이터베이스명 등이 코드에 직접 하드코딩 되어 있습니다.
이러한 정보는 코드를 Git 같은 소스 코드 관리 시스템에 저장할 때 같이 저장되므로, 누군가 이 저장소를 복제하면 연결 정보를 쉽게 얻을 수 있습니다.
보통 setting파일을 따로 만들어 소스 코드 관린 시스템에 저장이 되지 않도록 ignore 처리를 해놓습니다.

DB root 계정 사용

DB에 연결할 때 root 계정을 사용하고 있습니다. root 사용하면 참 편하죠. 하지만 DB에 접근할 수 있는 모든 권한을 가지기 때문에 유출되면 돌이킬 수 없게 됩니다.
최소한의 권한만 가진 사용자를 생성하여 DB에 접근하도록 설정하는 것이 좋습니다.

DB 연결 종료 코드 누락

DB 연결을 종료하는 코드가 없습니다.
생성된 connectioni의 사용이 완료되면 connection.end()를 호출하여 자원을 돌려줘야 합니다.
그렇지 않으면 DB와 연결이 지속되어 불필요한 자원을 소비하고 나중에는 서버 자원 부족으로 장애가 발생할 수 있습니다.

기타

위 3가지는 정말 중요하다 생각되는 내용이고 아래 내용은 중요할 수도 있고 중요하지 않을 수도 있어서 기타로 뺐습니다.

DB 연결에 대한 예외처리

DB를 사용한다는 얘기는 내부망이든 외부망이든 네트워크로 묶여 있다는 얘기이고, 네트워크는 언제든 끊길 수 있습니다. 따라서 예외처리를 하는 것이 좋습니다.

예)

try {
  connection.connect();
  console.log('Connected!');
} catch (err) {
  console.error('Error connecting to database:', err);
}


javascript에서 함수 만드는 5가지 방법 - (function())() 이해

Javascript에서 (function())() 같은 문법을 이해하기 위해 조사한 내용을 정리합니다.

Javascript에서 함수 만드는 방식

함수선언식(function declaration)

스크립트가 로딩되는 시점에 바로 초기화하고 이를 VO(variable object)에 저장, 따라서 함수 선언의 위치와는 상관없이 소스 내 어느 곳에서든지 호출이 가능

// 함수선언식(function declaration)
function test() {  
    // ...
}

함수표현식(function expression)

스크립트 로딩 시점에 VO에 함수를 저장하지 않고 runtime시에 해석되고 실행

자바스크립트에서 함수는 first-class object 이므로 변수에 할당될 수 있기 때문에 아래와 같은 함수 표현식이 가능

first-class object 의 특징

  • 변수에 저장할 수 있다.
  • 함수의 파라미터로 전달할 수 있다.
  • 함수의 반환값으로 사용할 수 있다.
  • 자료 구조에 저장할 수 있다.
// 기명 함수표현식(named function expression) 
var test = function test() {  
    // ...
}; 

// 익명 함수표현식(anonymous function expression)
var test = function() {  
    // ...
};

// 기명 즉시실행함수(named immediately-invoked function expression)
(function test() {
    // ...
}());

// 익명 즉시실행함수(immediately-invoked function expression)
(function() {
    // ...
}());

// 익명 즉시실행함수(immediately-invoked function expression)
(function() {
    // ...
})();


AngularJS의 페이지 로딩 에러 처리하기 (Page loading error in angularJS)

하이브리드 앱을 AngularJS로 작업하다 보니 네트워크 처리가 여간 귀찮은게 아니었습니다.

그래서 최상위 controller에서 에러에 대한 처리를 하고 각 controller에서는 네크워크 에러 여부만 전달하는 방식으로 고민 하다보니 $exceptionHandler라는 것을 알게 되었습니다.

저의 경우 초반에 exceptionHandler에서 exception를 받기는 하는데 다시 $state 처리가 되지 않아서 고생했습니다. 아마도 exceptionHandler에서는(혹은 사용하는 위치에 따라?) injector를 사용해야 정상동작을 하는 것 같습니다.
그렇지 않으면...많이 보셨던 아래 문구를 또 보시게 됩니다.

Unknown provider: eProvider <- e <- $exceptionHandler <- $rootScope <- $q <- $exceptionHandler

아래는 예제 코드 입니다.

angular.module('MyApp').factory('$exceptionHandler', ['$injector', function ($injector) {
    return function (exception, cause) {
        console.log("======================= exception", exception);
        console.log("======================= cause", cause);
        var state = $injector.get('$state');
        state.go("signin");
    };
}]);

각 controller 에서는 http 통신결과가 200이 아닐 경우 exception를 던지고 끝

if (res.status == 200) {
    if (typeof callback == "function") {
        callback(res.data);
    }
}
else {
    // http 통신이 200이 아닐 경우 처리
    $exceptionHandler(res);
}


AngularJS controller hello world 만들기

AMP 환경 설치

angularJS 설정

angularJS 다운로드

AngularJS 홈페이지 방문하여 zip으로 소스 다운로드
https://angularjs.org/

angularJS 설치

설치까지는 아니고, zip으로 받은 angular 소스의 압축을 풀어
apache web root 에 복사

hello world 코드 작성

html 생성

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="/angular-1.6.4/angular.js"></script>
    </head>
    <body>
        <input ng-model="text">
        <h1>{{text}}</h1>
    </body>
</html>

controller를 사용하여 html 파일 생성

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <script src="/angular-1.6.4/angular.js"></script>
    <script>
        var myApp = angular.module('myApp', []);
        myApp.controller('MainCtrl', ['$scope', function ($scope) {
            $scope.text = 'Hello world';
        }]);
    </script>
</head>
<body>
    <div ng-controller="MainCtrl">
         {{ text }}
    </div>
</body>
</html>

테스트

localhost로 접속하여 테스트


간단하지만 임팩트가 있는것 같다.



AngularJS Service이해하기

개념

서비스는 여러 함수적인 기능을 수행하는 컨트롤러와는 다르게 하나의 객체를 리턴하는 형태가 주를 이룬다.

컨트롤러는 $scope 상의 모델을 조작하거나 UI와 밀접하게 여러 기능들을 수행하는 반면 서비스는 자체가 싱글톤이라는 특성을 사용하여 컨트롤러간의 통신을 제어하거나, 리소스 접근 권한을 가진 객체를 리턴하여 컨트롤러에서 필요한 처리하게 된다.

예제

Javascript

<script>
    var myApp = angular.module('myApp', []);

    myApp.controller('HelloCtrl', function ($scope, HelloService, HelloFactory){
        $scope.title = 'Hello';

        // service 함수 선언
        $scope.addWorldService = function(){
            $scope.title = HelloService.addWorld($scope.title);  
        };
    });

    myApp.service('HelloService', function(){
        this.addWorld = function(title){
            return title + " world";
        };
    });
</script>

HTML

<body>
    <div ng-app="myApp">
        <div ng-controller="HelloCtrl">
            <h1>{{title}}</h1>
            <br/>
            <button ng-click="addWorldService()">via service</button> 
        </div>
    </div>
</body>