'전체'에 해당되는 글 263건

  1. 개발자들이여! 이제는 전자책(이북)을 읽자!
  2. 자취인, 자취생활 추천 용품 정리 (1)
  3. 팬택 아임백(SKY IM-100S) 구매 후기, 케이스, 액정보호필름 추천
  4. EBS 입트영, 귀트영으로 영어 공부하기
  5. 흡수율 높은 식물성 캡슐의 나우푸드 구연산 마그네슘 개봉기
  6. Grunt, AngularJS 프로파일 설정하기
  7. NPM을 이용하여 프론트엔드 라이브러리 적용하기
  8. AngularJS, 전역 범위($rootScope)에 이벤트 핸들러 등록하기
  9. AngularJS, Hello World 출력하기
  10. Grunt, Webpack을 적용한 빌드 단위 개발하기

개발자들이여! 이제는 전자책(이북)을 읽자!

개발자, 끊임 없는 투자가 필요한 고달픈 직업

세상의 모든 직업이 끊임 없는 공부를 요구하지만 소프트웨어 개발자 만큼 하드코어하게 반강제적 공부를 요구하는 직업도 드물 것이다. 야근과 주말 출근도 벅찬데 계속해서 터져나오는 신기술들은 개발자에게 끊임 없는 학습을 요구한다. 도태되지 않으려면 다양한 수단의 공부 방법이 필요하고 가장 일반적인 방법은 책을 구매하는 것이다. 하지만 노트북 하나도 몇 그램 가벼운 것을 사려고 십수만원을 기꺼어 추가 지불하는 개발자들에게 있어 종이로 된 두꺼운 책(특히 레퍼런스 개발서적은 백과사전보다도 두껍다.)은 영 구매하기 껄끄럽다. 0과 1의 디지털로 먹고 사는 개발자 답게 폼 나게 전자책을 구매해야 하지 않겠는가? 이번 글에서는 개발자의 입장에서 대표적인 전자책 플랫폼을 간단히 비교 정리하고자 한다.

Amazon Kindle(아마존 킨들) ★★★★☆

Amazon Kindle은 영어권에서 가장 유명한 전자책 플랫폼이다. 안드로이드의 경우 Play 스토어에서 앱 설치가 가능하다.


  • Amazon Kindle 앱을 이용하려면 Amazon 계정이 필요하다. 앱에서 이름, 이메일, 비밀번호를 입력하면 바로 계정이 생성된다.
  • 계정 로그인 후 메뉴에서 Kindle Store로 이동하면 전자책을 검색하고 구매할 수 있다. 구매 전 샘플 챕터를 읽어볼 수 있는 점이 돋보인다.
  • Amazone Kindle은 전자책 플랫폼의 선두주자 답게 가장 많은 개발 관련 전자책을 제공한다. 또한 사용자 리뷰가 풍부하여 구매 전 의사 결정에 많은 도움이 된다. 원서를 읽을 수 있는 능력만 된다면 개발자에 있어 최고의 전자책 플랫폼이라고 생각된다.
  • 테스트 검색어로 OAuth를 검색하면 21권이 조회된다. 가장 상위에 조회된 OAuth 2.0(라이언 보이드 저) 원서의 가격을 보면 $10.99(한화 13,300원)이다.

Google Play 북(구글 플레이 북) ★★☆☆☆

Google Play 북Google이 서비스하는 전자책 플랫폼이다. 유일하게 번역서와 원서를 한 플랫폼에서 구매할 수 있는 장점이 있다.


  • 테스트 검색어로 OAuth를 검색하면 무려 40권이나 조회된다. 하지만 연관성이 적은 책까지 검색하여 실질적으로는 Amazon Kindle과 큰 차이가 없다. 한글 번역서는 단 1권이 조회되었는데 OAuth 2.0(라이언 보이드 저)으로 11,000원에 판매되고 있다. 후에 설명할 리디북스보다 2,000원 비싸다.
  • 동일한 책의 영문 원서는 16,522원에 판매되고 있는데 앞서 Amazon Kindle보다 약 3,000원 비싸다. 번역서는 리디북스보다, 원서는 Amazon Kindle보다 비싼 셈으로 포지션이 애매하다.
  • 안드로이드 앱은 검색 결과에 대한 필터 기능을 제공하지 않는다. 이 점에 있어서는 다양한 필터 기능을 제공하는 Amazon Kindle의 완승이다.
  • 또한, 영문 원서의 사용자 리뷰가 거의 없다시피 하다. Amazon Kindle의 완승이다.

리디북스 ★★★☆☆

리디북스는 한국에서 가장 유명한 전자책 플랫폼이다. 특히, 리더로서의 앱의 편의성은 Amazon Kindle보다 뛰어나다고 생각된다.


  • 테스트 검색어로 OAuth를 검색하면 단 1권이 조회된다. 앞서 설명한 플랫폼에서도 검색된 OAuth 2.0(라이언 보이드 저)인데 가격은 9,900원으로 가장 저렴하다. 앞서 Amazon Kindle에서는 원서가 $10.99(환화 13,300원)에, Google Play 북에서 번역서가 11,000원에 판매된 것을 생각하면 리디북스에서 번역서를 구매하는 것이 훨씬 이득이다.
  • 컨텐츠만 풍부하다면 리디북스의 압승이다. 하지만 안타깝게도 리디북스 서비스가 런칭된지 수년이 지났지만 검색 결과가 보여주듯 소프트웨어 개발 관련 서적의 업데이트는 더디기만 하다.

결론

안타깝게도 하나의 플랫폼에서 편리하게 영문 원서와 한글 번역서를 구매하기에는 아직 힘든 듯 하다. 1차적으로 국내서 및 번역서는 리디북스에서 구매하고, 원서는 Amazon Kindle에서 구매하는 것이 최선책으로 보인다.

저작자 표시 비영리 동일 조건 변경 허락
신고

자취인, 자취생활 추천 용품 정리

자취인의 미니멀 라이프를 빛내주는 도구들

얼마 전부터 근무지가 멀어져서 본의 아니게 자취 생활을 시작했다. 출퇴근 시간은 Door to Door 기준 1시간 이하이어야 최소한의 삶의 질을 유지할 수 있다는 나름의 철학이 있어 이사하게 되었다. 이사 후 자취인의 삶을 시작하면서 삶에 유용한 도구들을 구매하기 시작했다. 이번 글에서는 시행착오 끝에 자취인들에게 추천하는 제품들을 꾸준히 정리하고자 한다.

밀대청소기

밀대청소기정전기 청소포(정전기 부직포)의 조합은 신세계이자 신이 자취인들에게 내려준 축복이다. 일회용 정전기 청소포밀대청소기의 홈에 끼우면 모든 청소 준비가 끝난다. 머리카락과 먼지로 지저분한 바닥 청소를 순식간에 끝낼 수 있다. 바로 이어서 물걸레 청소포를 끼우고 마무리하면 바닥이 뽀송뽀송해진다. 다 쓴 청소포는 버리면 되므로 수고롭게 걸레를 여러번 빨 필요도 없다.


  • 가장 유명한 제품은 3M 스카치-브라이트 올터치 막대걸래(인터넷 최저가: 11,400원)와 3M 스카치-브라이트 베이직 미세먼저 정전기 청소포(50매)(인터넷 최저가: 3,000원)와의 조합이다.
  • 나는 다이소에서 밀대청소기(품번: 57631, 구입가: 5,000원)와 정전기 청소포(60매)(품번: 57834, 구입가 2,000원)를 구매했는데 가격은 저렴해도 청소하기에 부족함이 없다. 소모품의 특성상 저렴한 것을 많이 사서 자주 청소하는 것이 더 이득이라고 본다.
  • 정전기 청소포는 바닥 청소 뿐만 아니라 가전이나 가구에 쌓인 먼지를 제거하는데도 효과가 탁월하다. 먼지를 정전기로 흡수하기에 걸레 또는 물티슈로 닦을 때의 얼룩도 남지 않는다.
  • 역시 다이소에서 물걸레 청소포(50매)(품번: 58846, 구입가: 2,000원)를 구매했는데 생각보다 물기가 금방 말라서 부직포 만큼 효과가 극적이지는 않지만 걸레를 빨아서 쓰는 것 보다는 편해서 애용한다.

의자

자취 생활에서 없으면 불편한 것이 의자와 책상이다. 특히 의자는 식사할 때, 책을 읽거나 컴퓨터를 사용할 때 등 전천후로 사용된다.


  • JAJU(이마트 자연주의의 새 이름) 브랜드의 어반등받이의자(구입가: 12,950원)를 추천한다. 일단 가격이 깡패인데다 가볍고 등받이까지 있어 은근히 편하다. 오프라인 매장에서 구매할 수 있다.
  • 본격적으로 오래 집중할 의자를 찾는다면 씨디즈 브랜드를 추천한다. 가격대가 높지만 인체공학적이라 오래 앉아도 부담이 없다. 나는 오프라인 매장에서 직접 앉아보고 착용감이 좋은 T550HLDA Black Edition(인터넷 최저가: 286,000원)을 구매했다. 비싸도 덕분에 집중해서 공부하고 연봉 높이면 그게 더 이득이다!

LED스탠드

매일 모니터를 오래 봐야 하는 직업적인 특성상 눈을 보호하는 스탠드는 필수라고 생각한다. 그 중에서도 저전력에 긴 수명을 가져 램프를 교체할 필요가 없는 LED스탠드를 추천한다.


  • 나는 다이아소닉 DL-100PH을 1년 넘게 중이다. 소비전력 11W에 제도용 LED스탠드라서 다양한 각도로 책상을 비출 수 있어 매우 편리하다. 3가지 모드(독서, 수리, 휴식)를 제공하는데 수리 모드에서 최대 밝기 설정시 1,600Lux의 조도를 제공한다.

공기청정기

얼마 전 미국 캘리포니아에 2달간 업무상 출장을 다녀왔다. 미국에 있는 동안 놀란 것은 한국(특히 서울)의 공기가 정말 나쁘다는 것이었다.(세계의 공장 중국을 원망해야 할까?) 수십만원어치의 한약을 먹고도 해결이 안되던 피부 질환이 미국에 있는 동안 깨끗하게 나아버렸다. 그리고 한국에 오자마자 가장 먼저 공기청정기를 구매해서 현재 만족스럽게 사용하고 있다.


  • 나는 삼성전자 블루스카이 AX40K3020UWD(인터넷 최저가 212,600원)를 구매했다. 수용 면적은 12평, 소비 전력은 34W로 혼자 사는 자취인에게는 부족함 없는 스펙이다. CA 인증에 H13 등급의 헤파 필터를 사용하여 99.95%의 미세먼지 제거 능력을 제공한다.
  • 공기청정기는 만능이 아니다. 무엇보다 매일 자주 환기하는 것이 중요하다. 공기청정기는 환기 후의 실내 미세먼지와 유해가스를 제거해주는 보조 수단일 뿐이다.
  • 공기청정기는 환기가 끝난 후에 작동시켜야 한다. 환기와 동시와 공기청정기를 가동하면 공기의 흐름을 방해하는데다 필터의 수명까지 단축시킨다.
  • 요리 중에는 환기(또는 환풍기 가동)만 해야 한다. 요리 중에 공기청정기를 가동하면 역시 필터의 수명이 급격히 단축된다.

온수매트

어렸을 때 부터 전기세 또는 가스비를 아끼겠다고 겨울철 추위 속에 두꺼운 이불을 뒤집어 쓰고 자도 개운하지 않은 그 느낌이 싫었었다. 몇년 전 지인을 통해 온수매트를 알게 되었고 신세계를 경험한 후로 겨울에는 무조건 온수매트를 사용하고 있다.


  • 나는 2014년에 구매한 삼원온스파 온수매트 700C-353를 만족스럽게 사용하고 있다. 최근 제품 중에는 동양이지텍 스팀보이 온수매트 C6300-S162를 추천한다.
  • 보일러의 실내 온도는 항상 살짝 춥게 느껴지는 수준인 20도에 맞추고 생활한다. 실내 활동에서 느껴지는 추위는 옷을 껴입어 해결한다.
  • 온수매트는 전기세의 부담이 있어 취침 목적으로만 사용한다. 취침 전 온수매트를 35도에 맞추고 가동하면 매우 편안한 숙면을 취할 수 있다.(온수매트 위의 매트가 두꺼울수록 열 전달력이 떨어지는 것을 감안해야 한다.) 35도보다 높게 설정하면 뜨거워서 새벽에 계속 잠을 깨게 된다.

음파칫솔

안경 착용자라면 손수건으로 안경을 닦다가 안경점 앞의 초음파 세척기로 닦을 때의 그 시원한 기분을 기억할 것이다. 음파칫솔은 마치 매일 치아를 스케일링하는 기분을 느끼게 해주는 사기 아이템이라고 단언할 수 있다. 음파칫솔을 한 번이라도 경험하면 다시 일반 칫솔로 돌아가기 싫어진다.


  • 시중에는 다양한 가격대의 음파칫솔이 판매되고 있다. 음파칫솔의 원조는 필립스 소닉케어이다. 해당 시리즈 중에 가장 저렴한 제품을 구매해도 음파칫솔의 효과를 충분히 체감할 수 있다. 나는 심지어 1990년대 생산된 옵티바(필립스로 인수되기 전의 회사명) 소닉케어 제품을 사용 중인데 배터리 충전 시간이 긴 것을 제외하고는 만족스럽게 사용하고 있다. 최근 제품 중에는 필립스 소닉케어 헬시화이트 라벤더 HX6721/06를 추천한다.
저작자 표시 비영리 동일 조건 변경 허락
신고

'생활' 카테고리의 다른 글

자취인, 자취생활 추천 용품 정리  (1) 2016.12.31

팬택 아임백(SKY IM-100S) 구매 후기, 케이스, 액정보호필름 추천

비싼 스마트폰 부담스러워...

IT 업종에 종사하면서 나는 이상할 정도로 최신 기기에 관심이 없다. 월든과 미니멀 라이프를 추구하는 탓인지 기기가 많을수록 배터리 등 챙길 것 들이 많아지는 것 같아 부담스럽다. 스마트폰도 마찬가지이다. 주변의 지인들은 백만원을 호가하는 스마트폰을 잘도 자주 바꾼다. 화장실까지 따라오는 비서와도 같기에 그만큼 비싼 스마트폰은 삶을 풍요롭게 해주기 때문일 것이다. 기능을 백프로 활용할 자신이 없기 때문일까? 귀차니즘에 매번 통신사의 다이렉트 쇼핑몰에서 24개월 약정으로 스마트폰을 구매했다. 신도림에서 암호를 주고 받으며 현금까지 받으며 스마트폰을 구매하는 친구들 눈에는 내가 호갱으로 보일 것이다. 어쨋든 또 나이는 먹어 약정했던 24개월이 종료됬고 아무 생각 없이 티월드 다이렉트를 방문하자마자 가장 저렴해 보이는 팬택 아임백(SKY IM-100S)로 덜컥 기기 변경을 해버렸다.


  • 내가 구매한 시점의 IM-100S의 출고가는 379,500원이다. 2016-10-28부터 최초 출고가에서 7만원 인하된 가격이다.
  • 요금제는 월 56,100원의 BAND 데이터 6.5G(BAND 데이터 51)를 선택했다. 비싼 요금제일수록 공시지원금이 올라간다.
  • 공시지원금과 선택약정할인 중에 공시지원금을 받는 것을 선택했다. 적용된 공시지원금은 313,000원으로 여기에 다이렉트샵 추가지원금 46,900원으로 실제 구매에 든 비용은 19,600원이다.
  • 공시지원금을 받는다는 의미는 개통 후 24개월 이내에 해지시 위약금이 존재한다는 의미이다. 개통 6개월 이내에 해지시에는 공시지원금 전액을 위약금으로 지불해야 한다. 개통 6개월 이후에는 (공시지원금/730)*남은 일수가 적용된다. 개통 24개월 이후에는 위약금이 소멸된다.
  • 공시지원금을 받았을 때 주의점은 24개월 이내에 스마트폰을 분실하였을 경우이다. 이런 경우 중고폰을 구해서 가까운 대리점에서 유심 재발급(신분증 지참 필수)을 신청하여 기존 회선 그대로 사용해야 한다. 새로운 스마트폰으로 기기변경시 해지로 간주되어 위약금을 물어야 한다.
  • 무료로 제공되는 T 기프트를 선택할 수 있어 iRiver EUB-10000 보조배터리를 선택했다. 뭔가 공짜로 얻은 기분이라기 보다는 그만큼 통신사들의 이윤이 많다는 생각이 든다. 제발 기본료 좀 낮추자!

아임백 도착하다!

기기변경 신청 하루 만에 배송이 도착했다. 기기변경은 번호이동과 다르게 직접 개통을 신청하면 된다. 티월드 다이렉트 홈페이지 또는 상담원을 통해 개통을 신청하면 된다.




도착한 아임백의 뒷모습이다. 귀찮아서 앞모습은 찍지 않았다. 첫 인상은 중저가 폰 치고는 야무지고 고급지다는 느낌이다.




함께 주문한 액정보호필름이다. 카페에서 추천 받은 빅쏘(VICXXO) 강화유리필름을 구매했는데 두께가 두터운 것이 저렴한 가격에 비해 나쁘지 않아 보여서 추천한다. 4매에 배송비 포함 7,980원에 구매했다.




유심칩을 끼우기 직전의 모습이다. 저 뾰족한 핀이 있어야 유심을 교체할 수 있다. 잃어버리면 어쩌지?




함께 주문한 케이스를 끼운 모습이다. 스마트폰을 자주 떨구기에 새 제품 냄새가 가시기도 전에 후딱 케이스를 끼웠다. 쌩폰이 진리라고 하지만 난 안전을 택했다. 트라이디아(Tridea) 파워 가드 카본 스타일 케이스로 배송비 포함 11,200원에 구매했다. 착용감이 좋고 외관이 고급스러워 추천한다.




유심칩 부착까지 완료하고 막 앱을 업데이트하는 순간이다. 5.15인치 크기로 살짝 작은 느낌은 있지만 그만큼 한 손에 쥐기 편해 만족스럽다.


장점

  • 작고 가볍다. 5인치 후반대의 스마트폰을 한동안 사용하다가 아임백을 쓰니 바지 주머니에도 쏙 들어가고 지하철에서 한 손에 들고 뉴스나 전자책을 보기가 편해졌다.
  • 디자인이 예쁘다. 최근의 스마트폰 디자인의 트렌드가 굴곡이라면 아임백은 정반대로 굴곡이 전혀 없는 사각형 디자인을 고수하고 있는데 시각적으로 안정감을 준다.
  • 최신 운영체제를 지원한다. 아임백은 안드로이드 마시멜로 6.0.1을 기본 탑재하고 있다. 마시멜로는 배터리 관리, 통화 품질 측면에서 이전 버전보다 우수하다. 이 점은 아임백이 2년 전 나온 고급형 스마트폰들 보다도 성능이 떨어지는 저가형 스마트폰임에도 차별성을 갖게 해준다.
  • 음성 알람 기능을 제공한다. 알람이 울릴 때 시간, 기온, 날씨 정보를 음성 TTS로 제공하는데 단순한 음악 알람보다 거부감이 없고(어떤 달콤한 음악도 알람으로 만나면 반갑지 않다!) 날씨 정보를 자세하게 알려줘서 깜빡하고 우산을 두고 외출하는 일이 줄어들었다.

단점

  • 성능이 떨어진다. 아임백은 저가형 스마트폰이다. 심지어 아임백보다 3년 전 출시된 베가 시크릿 노트보다도 성능이 떨어진다. 평소 여러 앱을 동시에 실행하거나 게임을 즐긴다면 아임백은 결코 만족스럽지 못할 것이다.
  • 아임백은 눈에 보이는 버튼이 없다. 즉, 물리적인 하드웨어키가 존재하지 않고 화면에 표시되는 소프트키를 대신 제공한다. 익숙해지면 편하지만 안그래도 작은 화면의 하단을 잡아먹어 살짝 답답한 감이 있다. 반대로 입맛에 맞게 버튼 순서를 배치할 수 있다. 예로 화면 캡처 버튼을 추가할 수 있는데 설정 → 하단 바 스타일 → 버튼 항목 변경 → 화면 캡처 순서로 추가하면 된다.

추천 앱

아임백은 저전력 저발열을 장점으로 하지만 동시에 저성능이라는 단점도 가지고 있다. 아임백에 어울리는 가벼운 무료 앱들을 아래 소개한다.

  • Dynamic 키보드: 무료 키보드 앱으로 단모음 키보드, 아이폰 테마를 지원한다. 사용자의 타이핑 습관을 학습하여 사용 후 며칠 후 오타가 줄어드는 것을 경험할 수 있다.
  • QuickPic: 무료 이미지 뷰어 앱이다.
  • Cabinet: 무료 파일 관리자 앱이다.
  • Greenify: 불필요하게 백그라운드에서 실행 중인 앱을 종료할 수 있는 무료 앱이다. 자동실행 방지 목록에 등록해두면 간편하게 원 버튼으로 실행 중인 앱들을 정리할 수 있다.
  • SD Maid: 무료 시스템 청소 앱이다. 시스템 청소를 빙자하여 광고를 덕지덕지 붙인 다른 앱들과의 달리 광고가 없고 깔끔한 것이 특징이다. SD Maid Pro를 추가로 구매하면 모든 기능을 이용할 수 있다.
  • 편한가계부: 복식부기를 지원하는 무료 가계부 앱이다. 별도의 클라우드 저장소를 제공하지 않지만 구글 드라이브를 이용한 데이터 백업을 지원한다. 유료 버전(3,900원)을 구매하면 음성 입력과 PC 입력 기능을 제공한다.
저작자 표시 비영리 동일 조건 변경 허락
신고

EBS 입트영, 귀트영으로 영어 공부하기

개요

직장 생활을 하다보면 야근에 치이고 회식에 치여 매년 다짐만 하는 영어 공부는 잊게 된다. 절박하지 않으니 독하게 동기부여가 될리 없다. 그러던 중 얼마전 장기 미국 출장을 다녀오면서 영어 공부의 필요성을 절실히 느꼈다. 보다 정확히 표현하면 한국과는 차원이 다른 미국의 선진적인 직장문화(라고 쓰고 칼퇴 문화라고 읽는다.)를 접하고 미국 현지 회사에 정직원으로 일하고 싶다는 욕심이 벌컥 생겼다. 한국에 돌아온 후로 어학원 강의를 찾아보다가 직장인으로서 매일 퇴근하고 꾸준히 할 수 있는 방법으로 검증된 EBS 영어 강의를 선택하게 되었다.

EBS어학FM 설치하기

EBS의 어학 강의는 기본적으로 서점에서 교재를 구매하고 매일 제 시간에 라디오 방송을 듣는 것이다. 하지만 언제 어디서나 공부할 수 있는 접근성과 반복성이 가장 중요하다고 판단하고 앱을 설치했다. 아래는 안드로이드 스마트폰 기준이다.

  • Play 스토어(Play Store)에서 EBS어학FM 앱을 설치한다.
  • 앱으로 제공되는 영어 강의는 아래와 같다.
    • 입이 트이는 영어(입트영)
    • 귀가 트이는 영어(귀트영)
    • Easy English
    • Power English
    • 김과장 비즈니스 영어로 날다
    • Easy Writing
    • 김대균 토익킹
    • TOEIC SPEAKING
    • 포켓 English

  • 각 강의는 월 단위로 구매가 가능하다. 2016년 12월 현재 기준으로 강의 구매는 4,500원, 강의+교재 구매는 11,200원이다.
  • 교재 구매는 2016년 12월부터 새로 추가된 서비스이다. 오프라인 교재가 그대로 벡터 방식의 PDF로 제공되는 것으로 시중의 다른 앱들이 제공하는 인터렉티브한 UI를 기대하면 실망할 것이다.
  • 한 번 구매한 강의는 평생 이용이 가능하다. 다만, 강의를 구매한 스토어와 계정이 일치해야 한다.

선택과 집중

  • EBS어학FM의 각 영어 강의는 휴일(빨간 날)을 제외하고 매일 새로운 강의가 올라온다. 언어의 천재가 아닌 이상 사람이 하루에 소화할 수 있는 양에는 한계가 있다. 차라리 선택과 집중을 하는 편이 효율적이다.
  • 직장인들은 야근과 회식에 치여 매일 영어 공부할 시간이 충분하지 않다. 일단 입이 트이는 영어(입트영)부터 시작하자. 욕심내지 말고 교재의 하루 분량을 크게 소리내어 읽고 우리말로 해석하는 과정(문장구역)을 머리 속에 외워질 때까지 반복한다. 눈으로만 읽지 말고 크게 소리내어 읽는 것이 중요하다.
  • 하루에 입트영 하루치를 소화하고 여유가 된다면 다음으로 추천하는 것은 귀가 트이는 영어(귀트영)이다. 공부 방법은 앞과 동일하다.

관련 링크

저작자 표시 비영리 동일 조건 변경 허락
신고

'취미 > 영어' 카테고리의 다른 글

EBS 입트영, 귀트영으로 영어 공부하기  (0) 2016.12.18

흡수율 높은 식물성 캡슐의 나우푸드 구연산 마그네슘 개봉기

개요

만성적인 야근과 스트레스에 시달리는 직장인에게 마그네슘은 이제 선택이 아닌 필수 미네랄이 되었다. 수년전 잦은 야근으로 전에 없던 눈 밑 떨림 현상과 불면증, 빈뇨 증상을 겪고 인터넷을 열심히 조사해보다 마그네슘의 효능을 알게 되었고 지금까지 꾸준히 복용하고 있다. 이번 글에서는 이번에 새로 구입한 나우푸드 구연산 마그네슘(식물성 캡슐 120정) 제품을 소개하고자 한다.

마그네슘의 효능

마그네슘의 효능에 대한 자세한 설명은 우리집 주치의 자연의학의 저자 이경원 박사의 아래 글을 추천한다.

외관

아래는 이번에 구매한 나우푸드 구연산 마그네슘(식물성 캡슐 120정)의 외관이다.



  • 구매는 쿠팡직구를 이용하였다. 해외직구라고 하면 일주일 이상을 기다리던 과거와 달리 정말 빠른 배송에 놀랐다. 주문일로부터 배송까지 4일이 소요되었다. 구매가는 개당 10,200원에 여러 개를 구매하여 배송비 무료 혜택을 받았다.
  • 앞면에 큰 글자로 쓰여진 Magnesium Citrate구연산 마그네슘을 의미한다. 구연산 마그네슘은 시중에 흔히 유통되는 산화 마그네슘(Magnesium Oxide)에 비해 흡수율이 좋고 부작용이 적어서 인기가 많다. 산화 마그네슘 섭취시 부작용은 설사 증상이 있다. 혹시 적정량 이하의 마그네슘을 복용하고도 설사를 경험해 봤다면 구연산 마그네슘 구매를 추천한다.
  • 뒷면의 성분표 또한 Magnesium(from Magnesium Citrate) 문구로 구연산 마그네슘 임을 확인할 수 있다.(산화 마그네슘의 경우 Magnesium(from Magnesium Oxide)라고 표기되어 있다.

개봉

제품을 개봉한 모습이다.



  • 제품은 총 120정의 캡슐로 구성되었으며 1일 권장 복용량은 3정으로 40일을 복용할 수 있다. 식물성 캡슐이라 소화가 빠르고 몸에 부담도 없다. 복용하기 가장 적당한 시기는 밤에 잠에 들기 전이다.

후기

40일간 복용 후 사용기를 갱신할 예정이다.

관련 글


저작자 표시 비영리 동일 조건 변경 허락
신고

Grunt, AngularJS 프로파일 설정하기

개요

Java 진영, 특히 Spring 기반의 개발자들은 배포 환경에 따라 설정을 달리 적용할 수 있는 Profile 개념에 익숙할 것이다. 프론트엔드 JavaScript 진영에서 Profile 단위의 개발은 필요하지만 적용 방법은 익숙하지 않을 것이다. 이번 글에서는 Grunt 기반의 AngularJS 프로젝트에서 Profile 개념을 적용하는 방법을 소개하고자 한다.

package.json

프로젝트 루트에 package.json에 아래 내용을 추가한다.

{
    ...
    "devDependencies": {
        "grunt": "1.0.1",
        ...
        "grunt-replace": "1.0.1", 
        ...
}
  • 위와 같이 기존 Grunt 기반 AngularJS 프로젝트에 grunt-replace 모듈을 추가하고 커맨드 창에서 npm update를 실행한다.
  • grunt-replace 모듈은 원본 파일에서 사용자가 정의한 특정 패턴의 문자열을 찾아내어 바꿔치기하는 기능을 제공하는 Grunt의 모듈이다. 이 모듈을 활용하여 AngularJSConstant에 정의된 문자열을 배포 환경에 따라 변경하는 작업을 작성할 것이다.

Gruntfile.js

프로젝트 루트에 Gruntfile.js에 아래 내용을 추가한다.

module.exports = function (grunt) {

    grunt.initConfig({
        ...
        replace: {
            dev: {
                options: {
                    patterns: [{
                        json: grunt.file.readJSON('./profile_dev.json')
                    }]
                },
                files: [{
                    expand: true,
                    flatten: true,
                    src: ['src/app.js'],
                    dest: 'build/'
        },
        ...
    });
    ...
    grunt.loadNpmTasks('grunt-replace');
    ...
    grunt.registerTask('dev', ['replace:dev']);
}
  • 개발 환경을 dev 키워드로 식별하고 개발 환경으로 빌드할 경우 /profile_dev.json을 읽어 들여 소스 코드에서 해당 내용을 변경할 것이다.
  • 위 설정은 /src/app.js의 키워드를 모두 변경하고 /build/app.js로 저장한다.

profile_dev.json

프로젝트 루트에 profile_dev.json을 아래와 같이 작성한다.

{
    "PROTOCOL": "http",
    "HOSTNAME": "127.0.0.1",
    "PORT": "8080"
}
  • 각 배포 환경에 해당하는 설정 정보를 JSON 파일로 정의힌다. 빌드 과정에서 환경에 따라 해당 파일의 내용이 주입될 것이다.

app.js

/src/app.js를 아래와 같이 작성한다.

var app = angular.module('app', []);
app.constant('SERVER_INFO', {
    PROTOCOL: '@@PROTOCOL',
    HOSTNAME: '@@HOSTNAME',
    PORT: @@PORT
});

app.controller('testController', ['SERVER_INFO', function(SERVER_INFO) {
    console.log(SERER_INFO);
}]);
  • 위 소스 코드는 개발 및 운영 환경에 따라 값이 달라질 상수 값들을 AngularJSConstant로 등록하여 ControllerService에 주입하는 예이다.
  • 상수 값들은 @@KEY의 형식으로 식별 패턴을 부여하여 앞서 적용한 grunt-replace 모듈에 의해 빌드 과정에서 원래의 값으로 변경될 수 있도록 한다.

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

NPM을 이용하여 프론트엔드 라이브러리 적용하기

개요

대개 jQuery, Bootstrap과 같은 프론트엔드 영역의 라이브러리(또는 프레임워크)를 프로젝트에 적용시 해당 라이브러리를 직접 다운로드하거나 CDN을 활용하는 방식을 사용해왔다. 이러한 방법은 최근의 백엔드 영역의 빌드 자동화에 비하면 대단히 낙후된 방법으로 이를 극복하기 위해 서버 영역에서는 WebJars, 클라이언트 영역에서는 Bower 등이 등장하였다. 이번 글에서는 Node.js의 패키지 매니저인 NPM을 이용하여 프로젝트에 프론트엔드 라이브러리를 적용하는 방법을 소개하고자 한다.

package.json

NPM을 이용하여 프론트엔드 모듈을 설치하기 위해 프로젝트 루트에 package.json을 아래와 같이 작성한다.

{
    "name": "helloworld-app",
    "version": "0.0.1",
    "devDependencies": {
        "grunt": "~1.0.1",
        "webpack": "~1.13.2",
        "webpack-dev-server": "~1.15.1",
        "grunt-webpack": "~1.0.14",
        "grunt-contrib-copy": "~1.0.0",
        "jquery": "~3.1.0",
        "bootstrap": "~3.3.7",
    }
}
  • jquery, bootstrap 프론트엔드 모듈을 사용하기 위해 의존성 정보를 작성하였다. 작성 후 커맨드 창에서 npm install를 실행하면 프로젝트 루트의 node_modules 디렉토리에 앞서 정의한 모듈이 설치된다.

Gruntfile.js

앞서 설치한 프론트엔드 모듈을 개발환경 또는 배포환경에 적용하기 위해 프로젝트 루트에 Gruntfile.js을 아래와 같이 작성한다. (Gruntfile.js는 프로젝트 빌드 도구인 Grunt의 작업 설정 파일이다.)

module.exports = function (grunt) {

    grunt.initConfig({
        copy: {
            build: {
                files: [
                    {
                        expand: true,
                        cwd: 'node_modules',
                        src: ['bootstrap/dist/**'],
                        dest: 'build/assets'
                    }
                ]
            }
        },
        webpack: {
            build: {
                entry: './src/app.js',
                output: {
                    path: 'build',
                    filename: 'app.js'
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-webpack');
    grunt.registerTask('dev', ['copy:dev', 'webpack:dev']);
}
  • copy 작업은 grunt-contrib-copy를 이용하여 node_modules에 존재하는 Bootstrap의 배포 파일(CSS, 글꼴, 이미지 등)을 지정한 경로에 복사한다. src 옵션에 복수개의 복사 대상 경로를 지정할 수 있다.
  • webpack 작업은 grunt-webpack을 이용하여 모듈 개념을 도입하여 작성한 사용자의 JavaScript 파일을 컴파일한다.
  • 뒤에 설명할 소스 코드까지 작성을 완료하고 커맨드 창에서 grunt build 명령을 실행하면 위 작성한 작업들이 순서대로 실행된다.

index.html

애플리케이션의 시작점인 /src/index.html을 아래와 같이 작성한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="utf-8">
    <title>Hello, World</title>
    <link rel="stylesheet" href="assets/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="assets/bootstrap/dist/css/bootstrap-theme.min.css">
    <script src="app.js"></script>
</head>
<body>
</body>
</html>
  • 앞서 작성한 grunt-contrib-copy 작업에 따라 개발환경에 복사된 BoostrapCSS 파일을 로드하도록 작성하였다.
  • CSS는 기존의 방식대로 로드하지만 JavaScriptNPM 모듈의 장점을 활용할 것이다.

app.js

Webpack으로 빌드할 /src/app.js를 아래와 같이 작성한다.

window.$ = window.jQuery = require('jquery');
require('bootstrap');
  • NPM을 이용한 프론트엔드 모듈 관리의 장점은 위와 같이 Webpack이 제공하는 require() 구문을 이용하여 설치된 모듈을 참조할 수 있어 재사용성이 증가한다는 것이다. 위 2개 문장 만으로 JavaScript에서 jQueryBootstrapAPI를 전역 범위에서 사용할 수 있다.
  • 사용자가 작성한 JavaScript 파일은 반드시 UTF-8 인코딩으로 저장해야 한다. Webpack은 빌드 대상이 되는 파일들을 모두 UTF-8 인코딩으로 간주하기 때문에 다른 인코딩을 사용할 경우 글자가 깨진채 빌드된다.
저작자 표시 비영리 동일 조건 변경 허락
신고

AngularJS, 전역 범위($rootScope)에 이벤트 핸들러 등록하기

var app = angular.module('someApp', ['ui.router']);
app.run(['$rootScope', '$state'], function ($rootScope, $state) {

  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams, options) {
    if ( ... ) { // 인증이 요구되는 스테이트일 경우
      $state.transitionTo('user.login');
      event.preventDefault();
  });
}]);
  • AngularJSrun() 메써드에 전달한 함수는 앱의 최초 부트스트래핑 과정에서 실행된다. 마치 Javamain() 함수와 유사한 기능을 한다. run() 메써드의 실행 시점은 config()controller() 사이이다. 앱의 전체 스코프에 필요한 이벤트 핸들러 등을 작성할 때 유용하다.
  • AngularJS$rootScope로 불리우는 단 1개의 스코프와 자손에 해당하는 복수개의 $scope를 제공한다. $rootScope의 범위는 바로 ng-app 디렉티브가 명시된 범위와 일치한다.
  • $rootScope와 모든 자손 스코프에는 특정 이벤트에 대한 이벤트 핸들러 함수를 등록할 수 있다. 위의 경우 URL 라우팅의 스테이트 전환시 발생하는 $stateChangeStart에 대한 이벤트 핸들러를 등록한 예이다.

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

AngularJS, Hello World 출력하기

개요

AngularJS는 최근의 트렌드라 할 수 있는 SPA(Single Page Application) 개발을 지원하는 현재 가장 유명한 MVW(Model-View-Whatever) 프레임워크이다. 마지막 WWhatever인 것은 무엇이든 올 수 있다는 의미이다. 최근의 트렌드는 이 부분을 ViewModel 방식으로 구현하는 것이다.

사전지식

AngularJS를 접하기에 앞서 JavaScript 빌드 도구인 Grunt, Webpack에 대한 사전 이해가 필요하다. 아래 글을 참고한다.

package.json

프로젝트 루트에 package.json 파일을 아래와 같이 작성한다.

{
    "name": "helloworld-app",
    "version": "0.0.1",
    "devDependencies": {
        "grunt": "~1.0.1",
        "webpack": "~1.13.2",
        "webpack-dev-server": "~1.15.1",
        "grunt-webpack": "~1.0.14",
        "grunt-contrib-uglify": "~2.0.0",
        "grunt-contrib-copy": "~1.0.0",
        "grunt-contrib-connect": "~1.0.2",
        "jquery": "~3.1.0",
        "angular": "~1.5.8",
        "angular-ui-router": "~0.3.1"
    }
}
  • grunt 모듈은 Grunt 프로젝트 빌드 환경을 구성하기 위해 필요하다.
  • webpack, webpack-dev-server, grunt-webpackWebpack을 이용한 모듈 기반의 JavaScript 작성을 위해 필요하다.
  • angular, angular-ui-router는 프로젝트 소스 코드에서 사용할 라이브러리이다. <script src="..."></script> 태그를 사용하지 않고 Webpack 기반의 스코프 범위를 갖는 동적 로드를 할 것이다.

앞서 정의한 모듈을 설치한다. 프로젝트 루트에 node_modules 디렉토리가 생성된다.

$ npm install

Gruntfile.js

프로젝트 루트에 Gruntfile.js를 아래와 같이 작성한다.

module.exports = function (grunt) {

    grunt.initConfig({
        webpack: {
            dev: {
                entry: "./src/app.js",
                output: {
                    path: "dev",
                    filename: "app.js"
                }
            }
        },
        uglify: {
            dev: {
                files: {
                    'dev/app.js': ['dev/app.js'],
                }
            }
        },
        copy: {
            dev: {
                files: [
                    {
                        expand: true,
                        cwd: 'src',
                        src: ['**', '!*.js'],
                        dest: 'dev/'
                    }
                ]
            }
        },
        connect: {
            dev: {
                options: {
                    port: 8080,
                    base: 'dev',
                    keepalive: true,
                    debug: true,
                    open: true
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-webpack');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.registerTask('dev', ['webpack:dev', 'uglify:dev', 'copy:dev', 'connect:dev']);
}
  • 앞서 설치한 Webpack 모듈을 통해 /app.js를 시작점으로 모듈 단위로 복수개의 파일로 작성된 JavaScript간의 종속 관계를 분석하여 1개로 합쳐진 /js/app.js를 생성한다.

index.html

프로젝트 루트에 index.html을 아래와 같이 작성한다.

<!DOCTYPE html>
<html lang="ko" ng-app="helloworld-app">

<head>
    <meta charset="utf-8">
    <title>Hello, World</title>
    <script src="app.js"></script>
</head>

<body>
    <div ui-view></div>
</body>

</html>
  • html 엘러먼트의 애트리뷰트로 명시된 ng-appAngularJS의 디렉티브라고 부른다. 보통 html 또는 body 엘러먼트에 명시하는데 어떤 엘러먼트에 명시해도 상관 없다. ng-app이 명시된 엘러먼트 범위가 곧 AngularJS의 영향을 받는 제어 범위가 된다.
  • JavaScriptjs/app.js 1개 만을 로드한다. 현재 시점에는 존재하지 않는 파일이며 뒤에 설명할 Webpack 빌드 도구를 이용하여 생성할 것이다. angular, angular-ui-router, 개발자가 작성한 복수개의 JavaScript 파일이 포함된다.
  • ui-view 디렉티브가 명시된 엘러먼트는 요청 주소에 따라 일치하는 ViewAJAX로 동적 로드할 부분이다. 본 예제에서는 /#hello 요청이 들어올 경우 hello.html을 출력할 것이다.

hello.view.html

프로젝트 루트에 hello.view.html을 아래와 같이 작성한다.

<div>
  {{message}}
</div>
  • HTML의 모든 구성 엘러먼트를 갖지 않은 것은 위 내용이 앞서 설명한 ui-view 디렉티브가 명시된 영역에 AJAX 요청에 의해 동적으로 출력될 것이기 때문이다.
  • {{message}}AngularJS가 제공하는 템플릿으로 다음에 뒤에 설명할 ViewModel에 의해 값이 출력될 것이다. 이처럼 브라우저에 출력될 HTML 템플릿을 View라고 부른다.

hello.viewmodel.js

프로젝트 루트에 hello.viewmodel.js을 아래와 같이 작성한다.

var viewmodel = function ($scope) {
    $scope.message = 'Hello, World!';
}
module.exports = viewmodel;
  • $scope에 위와 같이 변수를 작성하면 곧 Model이 된다. message라는 문자열 값을 가지는 Model 변수를 작성한 것인데 앞서 View에서 작성한 {{message}}에 주입되어 화면에 출력될 것이다. 개발자는 직접 DOM을 조작할 필요 없이 Model 변수의 값만 조작하면 AngularJS에 의해 자동으로 DOM에도 반영된다.
  • 단순한 예제라서 설명하지 않았지만 $scope에 함수를 작성할 수도 있다.
  • module.exports는 이 파일이 CommonJS 모듈 임을 Webpack에게 알려주는 역할을 한다. 이렇게 모듈을 구분하여 작성하면 이 모듈을 필요로 하는 다른 소스 코드에서 사용함으로서 모듈의 재사용성을 효율적으로 높일 수 있다.

hello.route.js

프로젝트 루트에 hello.route.js을 아래와 같이 작성한다.

var route = function ($stateProvider) {

    var helloState = {
        name: 'hello',
        url: '/hello',
        templateUrl: 'hello.view.html',
        controller: 'helloViewModel'
    }
    $stateProvider.state(helloState);
}
module.exports = route;
  • 앞서 작성한 View, ViewModel을 연결시켜주는 라우팅 역할을 한다. Spring Web MVC에 익숙한 개발자라면 @Controller를 생각하면 이해하기 쉽다.
  • 위는 /#hello 주소 요청을 hello.view.html 뷰와 helloViewModel 뷰모델로 연결시켜주는 역할을 한다.

app.js

프로젝트 루트에 app.js을 아래와 같이 작성한다.

window.$ = window.jQuery = require('jquery');
var angular = require('angular');
var angularUiRouter = require('angular-ui-router');
var helloRoute = require('./hello.route');
var helloViewModel = require('./hello.viewmodel');
var app = angular.module('helloworld-app', [angularUiRouter]);

app.config(['$stateProvider', helloRoute]);
app.controller("helloViewModel", ['$scope', helloViewModel]);
  • AngularJS 앱의 시작점이 되는 소스 코드이다. AngularJS 라이브러리인 angular, angular-ui-router를 차례대로 로드하고 앞서 개발자가 작성한 모듈을 로드하여 등록한다.
    • 만약 jQuery를 사용한다면 위와 같이 jqueryangular에 앞서 로드되어야 한다. 또한 다른 모듈에서도 이용할 수 있도록 전역 범위를 갖는 window 객체에 저장해야 한다.
  • 본 파일을 시작으로 분산되어 있는 복수개의 모듈들은 종속 관계를 가진다. 뒤에 설명할 Webpack에 의해 1개의 파일로 합쳐질 것이다. 현재 시점에서 브라우저에서 앱을 실행하면 브라우저가 알아듣지 못해 오류가 발생한다.

빌드

이제 Grunt, Webpack을 이용하여 빌드할 차례이다. 아래와 같이 Grunt 작업을 실행한다.

$ grunt dev
  • 앞서 Gruntfile.js에 설정한대로 빌드 과정을 거쳐 분산된 여러 모듈이 1개의 app.js로 통합되고 테스트 가능한 웹 서버가 실행되는 것을 확인할 수 있을 것이다.

관련 글

저작자 표시 비영리 동일 조건 변경 허락
신고

Grunt, Webpack을 적용한 빌드 단위 개발하기

Webpack이란?

서버 사이드에서 Node.js로 개발해본 개발자라면 require 구문을 통한 모듈 단위의 개발에 익숙할 것이다. Webpack은 서버 사이드에서만 사용되던 모듈 단위 개발을 클라이언트 사이드에서도 가능하게 해주는 빌드 도구이다. 이번 글에서는 Grunt 빌드 환경에서 Webpack을 적용하는 방법을 설명하고자 한다.

모듈의 예

JavaScript에서 모듈을 작성하는 방식은 AMD, CommonJS 2가지로 구분된다. 다음은 CommonJS 방식으로 작성한 모듈의 예이다. 아래와 같이 hello 이름을 갖는 모듈을 작성하고 hello.js로 저장한다.

var hello = 'hello';
module.exports = hello;

앞서 생성한 hello 모듈을 사용하는 world.js를 작성한다.

var hello = require('./hello');
console.log(hello);

package.js 작성

프로젝트 루트에 package.json을 아래와 같이 작성한다.

{
  "name": "sample-app",
  "version": "0.0.1",
  "devDependencies": {
    "grunt": "~1.0.1",
    "webpack": "~1.13.2",
    "webpack-dev-server": "~1.15.1",
    "grunt-webpack": "~1.0.14"
  }
}
  • GruntWebpack을 적용하기 위해서는 webpack, webpack-dev-server, grunt-webpack 모듈을 프로젝트에 설치해야 한다.

앞서 정의한 모듈을 설치한다. 프로젝트 루트에 node_modules 디렉토리가 생성된다.

$ npm install

Gruntfile.js 작성

프로젝트 루트에 Gruntfile.js을 아래와 같이 작성한다.

module.exports = function(grunt) {

  grunt.initConfig({
    webpack: {
      sample: {
        entry: "./src/js/app.js",
        output: {
          path: "build/js",
          filename: "app.js"
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-webpack');
}
  • /src/js/app.js를 프로젝트의 시작점으로 지정하여 사용된 모듈 간의 종속 관계를 분석하여 하나의 /build/js/app.js를 생성한다. 이를 통해 개발자는 Node.js에서와 동일한 방법으로 프론트엔드 영역에서도 모듈 개념을 적용할 수 있다.

Grunt 작업 실행

앞서 정의한 작업을 아래와 같이 실행한다. 후속 작업으로 uglify를 실행하면 운영 환경에 맞게 축약된 파일을 얻을 수 있다.

$ grunt webpack:sample

써드파티 라이브러리 모듈 적용

Webpack을 도입하면 NPM과의 조합을 통해 써드파티 라이브러리 또한 모듈 적용이 가능하다. 전통적으로 프론트엔드에서 써드파티 라이브러리를 로드하는 방법은 아래와 같다.

<script src="/assets/js/jquery.js"></script>

Webpack을 도입하면 HTML 상에 명시할 필요 없이 JavaScript 만으로 아래와 같은 모듈화가 가능하다. 우선 package.js에 사용할 써드파티 라이브러리를 명시해야 한다.

{
  ...
  "devDependencies": {
    ...
    "jquery":"~3.1.0"
  }
}

npm install을 실행하여 라이브러리 의존성 설치까지 완료하면 아래와 같이 Webpack이 제공하는 모듈 방식의 라이브러리 사용이 가능하다.

window.$ = window.jQuery = require('jquery');

모듈에 별명 지어주기

때때로 특정 모듈에 명시적으로 별명일 지어줄 필요가 있다. 이 경우 resolve.alias 설정을 해주면 된다. jquery 모듈을 예로 들면 아래와 같다.

webpack: {
    dev: {
        ...
        resolve: {
            alias: {
                'jq': require('path').join(__dirname, 'node_modules/jquery/dist/jquery.min.js')
            }
        }
    }
}

위 설정은 jquery 모듈에 jq라는 별명을 지어준다. JavaScript에서는 아래와 같이 모듈을 로드할 수 있다.

window.$ = window.jQuery = require('jq');

관련 글

저작자 표시 비영리 동일 조건 변경 허락
신고