기본 콘텐츠로 건너뛰기

라벨이 coffeescript인 게시물 표시

Firebase coffeescript snippet

firebase 단순 예제 좋은게 없어서 찾다가 문서보고 하나 짰다. 흔한 Firebase 자료구조.png https://console.firebase.google.com 에서 본 Database 구조가 위와 같을 때 config =   apiKey: '<<<<<<<<<>>>>>>>>>>'   authDomain: '<<<<<<<<<>>>>>>>>>>'   databaseURL: '<<<<<<<<<>>>>>>>>>>'   projectId: '<<<<<<<<<>>>>>>>>>>'   storageBucket: '<<<<<<<<<>>>>>>>>>>'   messagingSenderId: '<<<<<<<<<>>>>>>>>>>' firebase.initializeApp config ref = firebase.database().ref('rooms/muka/messages') # database 경로 ref.on 'child_added', (o) ->   # key:0. val();"text":"블라블라"   # key:1. val();"text":"블라블라"...

VulcanJS를 coffeescript로 써본다면? Meteor 스타일로?

요즘은 다들 javascript 환경을 React 하나만을 위해 구성하는 경우가 꽤 많은데 사실 Meteor는 상당히 유연한 javascript platform이며 Meteor를 사용하는 Vulcan 역시도 그렇다. 이번엔 따로 package를 만들지 않고 그냥 vulcan 프로젝트 위에서 해보자. import를 써서 빈틈없이 의존 관계를 명시적으로 정의하는 방법 외에도 어플리케이션 구조에 따른 load-order( https://guide.meteor.com/structure.html#load-order )를 가지고 자동으로 소스코드를 병합하는 방식도 지원한다. (원래는 이게 기본이었음) 작동하는 방식은 간단한데 /client 로 시작하면 client에서 실행. /server 로 시작하면 server 에서 실행하는 것을 기본으로 HTML 템플릿 파일이 항상 먼저 lib/ 디렉토리를 그 다음으로 path가 깊은 곳을 그 다음으로 파일은 전체 경로명에서 알파벳 순으로 main*.* 인 파일은 마지막에 불러오는 규칙을 가지고 있다. 만일 import를 꼭 쓰고 싶으면 import/ 디렉토리 안에 두면 된다. 이 규칙에 따라 이전에 다루었던 요소들을 정리하여 디렉토리를 구성을 다음과 같이 해보았다. \client \lib   \components     \Posts       PostsListComponent.coffee   \lib     \lib       global.coffee     \models       \Posts         \imports           schema.coffee           ..resolver.coffe...

coffeescript - export default를 coffeescript 에선 어떻게?

정답은   return <obj> 가령, vue 같은 곳에서 ( https://atmospherejs.com/akryum/vue-coffee ) <script>   export default {     data() {       return {          "say": "ho"       }     }   } </script> 이와 같이 작성한 코드는 <script lang="coffee">   return data: ->     "say": "ho" </script> 이렇게 쓰면 된다.

Meteor에서 접속(onConnection)/이탈(onClose) 관리에 대해 알아보자.

Meteor에서 로그인과는 상관없이 어떤 유저가 접속해 있고 이탈했는지를 추적하고 싶어서 정리, 서버사이드에서 아래와 같이 작성했다. Meteor.startup ->   console.log "server initiated"   ConnectedUsers.remove {} Meteor.onConnection (o)->   console.log "session [#{o.id}] is connected"   ConnectedUsers.insert userId: o.id   o.onClose (p)->     ConnectedUsers.remove userId: o.id Meteor.methods   "getSessionId": ->     @connection.id Meteor.publish "list.connectedUsers", ->   ConnectedUsers.find() 결론은 이정도이지 않나 싶다. mongodb를 사용하지 않고도 해보았는데 지나치게 publish쪽과 onConnection쪽이 복잡하고 일반화하기 좋지 않아 일단 보류. https://gist.github.com/makrem025/35543cd60aa88ca49fa0  의 예에서 응용하여 onConnection 일때 publish 의 added, remove로 쏘게 하면 되긴 함. 메모리 디비는 사랑입니다 <3 접속자 관리 관련한 기존 package(aka. mizzao:user-status)들은 지나치게 User collection을 괴롭혀서 성능을 떨어뜨린다. 생선을 낚으라고 준 낚시대인데 잡아야 하는 게 상어라면 분질러 버리고 작살을 만드는 게 맞다. ( 뭐? 상어도 낚시로 잡는다고? 낚알못 ) 우리는 뾰족하게 DDP를 통해 접근한 소켓(사용자가 아니다. 이름도 몰라요 성도 몰라 )에 대해 파악하고 이를 확인하는 것이 전부. 실전...

Chrome source map 먼지팁 (coffeescript/typescript/babel)

잘 되다가 갑자기 coffeescript/typescript/babel 등등의 디버깅이 sourcemap 연결 안된다면 크롬 디버거 열고 F1 누르고 Settings > Preferences > Sources > Enable Javascript source maps 를 체크해준다. 그러고 다시 크롬 디버거를 열어보면 Sources 탭에 요렇게 예쁘게 나온다. 갑자기 설정이 풀렸다 싶으면 당황하지 말고 Settings를 확인해보자.

RxJS - ReactiveX 인터뷰

A: 왜 RxJS입니까 B: javascript는 참 쉽고 친숙한 언어죠. A: 별로 그렇게 생각 안합니다만. B: 그래서 좀 어렵고 있어보이는게 뭘까 싶어서... A: 네? B: 함수형이라는게 유행하기도 하고 f(x) 좋쟎습니까? 미스테리~ 미스테리~ 정수정짱짱 으아아 이런 수학선생님이라면 수포자 따윈 A: ... B: 그리고 반응형이라는 말 뭔가 A: 뭔가? B: 대충대충해도 막 알아서 할거 같고... A: 그럴리가요? B: 안그렇겠죠? A: 네 B: 네 (잠시만 기다려주세요) A: 그래도 뭔가 매력이 있으니 이렇게 시간을 내셔서 이것저것 Rx에 대해 글도 쓰고 이야기도 하고 그러시는거 아닌가요? B: 매력이라. 으음. 제가 팔꿈치 터널 증후근이 좀 있어요. 오른손 세끼손가락, 약지손가락이 저립니다. A: 무슨 상관이? B: 그래서 각종 괄호를 쓰는게 너무 힘듭니다. 소중대괄호 만든 사람 죽었으면. Hello world (ASCII): https://esolangs.org/wiki/Parenthesis_Hell A: 이미 옛날에 돌아가셨겠죠. B: 그렇겠네요. 아무튼 그래서 소중대괄호 의존이 적은 커피스크립트를 쓰는데요. A: 빨리 본론을 말씀해주시죠. B: 커피스크립트에서 가로로 80자 이상쓰면 Line exceeds maximum allowed length 라고 경고해요. A: 그래서요? B: 근데 Rx를 쓰면 코드를 가늘게 쓸 수가 있더라구요. A: 호오? B: 그리고 = 쓰는 것도 너무 힘듭니다. A: 네? B: 오른손을 쓰쟎아요. A: ... 그러니까 정리하면 1. 괄호가 힘들다 2. 커피를 쓴다 3. 커피는 길게 쓰면 경고 4. Rx를 쓰면 코드가 가늘다 5. 대입문을 줄이고 싶다. B: 네 하지만 5번은 생각보다 별로... A: B: B: 아! A: ? B: 코드가 가늘어서 좋은 점이. A: 네. B: 핸드폰에서 코드를 보...

amok.js 에서 RxJS와 coffeescript 사용하기

amok은 live reload 가 가능해서 개발을 즐겁게 한다. 프로토타이핑할때 아주 좋다. RxJS 라이브러리를 받고 index.js 도 만들자. curl https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-beta.12/Rx.min.js > Rx.min.js touch index.js index.coffee package.json 을 만들어 놓으면 편하다. npm init 을 해서 엔터 연타하고 script 부분만 수정하자 {   "name": "rxamok",   "version": "1.0.0",   "description": "",   "main": "index.js",   "scripts": {     "start": "amok --browser chrome --interactive --hot Rx.min.js index.js"   },   "author": "",   "license": "ISC" } 이러면 준비 끝. amok 에서 coffeescript를 compile 하는 옵션이 deprecated 되었다고 한다. 하지만 걱정할 것 없다. 저장할때마다 자동으로 coffeescript를 컴파일 할 수 있다. coffee -wco ./ *.coffee 해놓고 편하게 코딩하자. rate = 1000/60 c = document.createElement 'canvas' c.style.position = 'absolute' c.style.top = '0' c.style.left = '0' resize = ->   c.width = w...

spectrum 에게 물어보세요. multiple option을 flat 하게 하고 싶어요.

질문: 쇼핑몰에서 옵션이 여러개 있는데 이걸 조합해서 보여주고 싶어요. 사이즈: s, m, l 색상: blue, red 길이: short, long 대상: girl, boy, woman, man 이라고 했을 때 s blue short woman 이런 식으로요. 답변: reduce 를 사용하세요. 풀이 예제  << 클릭하면 coffee/js 소스랑 결과값 모두 볼 수 있어요. Array::flatMap = (lambda) ->   @concat.apply [], @.map lambda v=[  ['s','m','l']  ['blue','red']  ['short', 'long']  ['girl', 'boy', 'woman', 'man'] ] console.log "result\n",   v.reduce (x1,x2)->     x1.map (o)->       x2.map (p)->         "#{o} #{p}"     .flatMap (o)->o 분류의 갯수는 상관없어요. 두개를 순서대로 합쳐야한다! 싶을 때는 reduce로 어떻게 해봐야지! 하고 시작하는게 좋아요. 먼저 ['s', 'm', 'l'] 하고 ['blue', 'red'] 만 놓고 보자구요. map으로 이중 루프를 돌면서 둘을 조합하면 되겠지요? ['s', 'm', 'l'].map (o)->   ['blue', 'red'].map (p)->     "#{o} #{p}" 근데 이렇게 하면 [["s blue","s r...

generator 연습

co 를 손으로 직접 만들어서 재귀를 통해 next() 를 돌려봤다. 결국 fiber 랑 같은 패턴인게 아닌가 싶은데 그래도 순정이니까 좋은 것.. node-fetch는 http request를 하고 promise를 반환형으로 갖는 독특한 라이브러리인데 yield랑 함께 쓸 수 있다. fetch=require 'node-fetch' r = (generator)->   iterator = generator()   # recurse   iterate = (iteration)->     if iteration.done       iteration.value     else       iteration.value.then (x)-> iterate iterator.next x   iterate iterator.next() r ->   uri = "http://jsonplaceholder.typicode.com/posts/1"   response = yield fetch uri   json = yield response.json()   json?.title .catch (error)-> console.error "ERROR", error.stack .then (x)-> console.log x 

오늘의 코드 - Excel 에서 Collection 까지 (feat. dot2obj)

Meteor.startup ->   if Tours.find().count() is 0     addDefault = (v)->       v.createdAt = Date.now()       v     dot2obj = (obj)->       for k,v of obj         idxes = k.split '.'         if idxes.length>0           delete obj[k]           idxes.reduce (a,b,ci,ar)->             a[b] = ar.length-1 is ci and v or a[b] or {}           , obj       obj     excel = new Excel 'xlsx'     workbook = excel.read new Buffer Assets.getBinary "fixtures.xlsx"     fixtures = excel.utils.sheet_to_json workbook.Sheets['Sheet1']     Tours.insert addDefault dot2obj obj for obj in fixtures     console.log "Tours collection initiated." 이런 코드를 만들었다. Tours 라는 collection이 비어있으면 excel 파일을 읽어서 (...

내가 underscore라이브러리를 별로 선호하지 않는 이유.

node.js 콘솔을 연다 (function() { return 10; })() --> 10 _ --> 10 (응????????) REPL에서 function의 반환값이 _에 저장됨. 그래서 _를 조사하면 10이 나옴. golang에선 _를 blank identifier로 사용. sum := 0 for _, value := range array {     sum += value } 이런 식으로. 논란의 여지는 있지만 단지 길이가 길어서 _를 함수명으로 쓰는 류들에 대해서 별로 좋아하지 않음. 마찬가지 이유로 $를 쓰는 jQuery도 그다지. 결론은 coffeescript 쓰세요. 두번 쓰세요. for in(of) when은 무적입니다. #하지만 둘 다 같은 사람이 만들었음;

amok 에서 vim으로 coffeescript 를 사용하는 법

amok.js  는 아주 빠르고 멋진 코드 갱신을 할 수 있게 하는 작은 툴이다. webpack의 Hot module replacement 와는 차원이 다른 반응속도를 보여준다. 물론, 구조도 더 단순하고 무엇보다 러닝커브가 낮다. uglify 툴로 이전에 언급한 Tracker.js , mithril.min.js , MeteorDDP.js 를 모두 묶어서 util.js 라고 만들고 > uglify -s MeteorDDP.js,Tracker.js,mithril.min.js -o util.js html 파일은 간단하게 만들자 <!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>Mamok</title> </head> <body> <script src="./util.js"></script> <script src="./index.js"></script> </body> </html> index.js 를 바라보게 했는데 사실은 index.coffee를 쓸거다. 'use strict' window.addEventListener 'patch', ->   m.redraw() m.module document.body,   view: -> [     m 'h1', 'Hey, Brother.'     m 'h3', m.trust '<button>hey hey</button>'   ] 아주 짧지만 신통한 구조다. 파일 변경을 감지하...

node.js 를 위한 vim 환경 설정.

tmux를 쓰다보니 vim 환경 설정 셋을 문득 만들어 보고 싶었다. 1. 일단 vim 먼저 받고 sudo apt-get install vim 2. manage your runtimepath 관리용 pathgen 설치 mkdir -p ~/.vim/autoload ~/.vim/bundle; \ curl -Sso ~/.vim/autoload/pathogen.vim \     https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim 3. ~/.vimrc 없을테니 아래와 같이 생성. tab/indent 간격은 2에 탭 대신 space로 쓰기 위해 expandtab 추가 execute pathogen#infect() syntax on filetype plugin indent on set tabstop=2 set shiftwidth=2 set softtabstop=2 set expandtab 4. 아무 js 나 vim 으로 열어서 color 적용여부 확인 5. sensible plugin 설치 git clone git://github.com/tpope/vim-sensible.git ~/.vim/bundle/vim-sensible 6. node bundle 설치 git clone https://github.com/moll/vim-node.git ~/.vim/bundle/node 7. coffeescript bundle 설치 git clone https://github.com/kchmck/vim-coffee-script.git ~/.vim/bundle/vim-coffee-script/ 8. zen code 보다 더 좋은 Emmet 설치 - ctrl+y+, 로 활성화 git clone http://github.com/mattn/emmet-vim.git ~/.vim/bundle/emmet-vim 9. less 도 활성화 ...

Meteor 에서 외부 Application으로 DDP 인증 (2) : SRP 교환

DDP로 인증을 하려면 네트웍상에 평문으로 보내지 않기 위해 SRP(Secure Remote Password) 라는 프로토콜로 변환한다. https://github.com/meteor/meteor/tree/devel/packages/srp package.js 를 보면 biginteger 와 sha256 을 사용한다. 구현해야할 부분은  https://github.com/meteor/meteor/blob/devel/packages/accounts-password/password_client.js#L10 이 곳 참조. password 를 가지고 다음과 같이.     s = new srp.Client password     request = s.startExchange()     if typeof selector == 'string'       selector =         if ~selector.indexof("@")         then username: selector         else email: selector     request.user = selector beginPasswordExchange 를 시작하는 부분의 인자는 request 자체를 사용. request 내용은 A를 키로 하는 SRP 암호문과 user를 키로하는 사용자명이 되겠다. method 쏴준다. A에 srp로 암호화한 문자를 사용. { msg: 'method',   method: 'beginPasswordExchange',   params:    [ { A: '439284960ce6bc7c163262b5629a467cd06bb982432615ec526a1ed204d2f76a1a2...

coffeescript로 만들어보는 html(jade/ejs 아님)사용 boilerplate

express = require 'express' gzippo = require 'gzippo' app = express.createServer express.logger() store = new express.session.MemoryStore api = require './api/apis' tmpl = compile: (source, options)->     (locals)->       source app.configure ()->   app.set 'views', "#{__dirname}/public"   app.use express.cookieParser()   app.use express.session secret: '<sessionkey>', store: store   app.use gzippo.staticGzip "#{__dirname}/public"   app.set 'view options', layout: false   app.set 'view engine', 'html'   app.register '.html',     tmpl # APIs app.post '/api/auth/login', api.login app.get '/api/auth/logout', api.logout app.get '*', (request, response) ->   response.render "index.html" port = process.env.PORT || 3000 app.listen port, ()->     console.log "Listening on " + port

Coffeescript 에서 Array와 Object를 다루는 방법

자바스크립트를 하다보면 JSON Object와 Array를 처리할 일이 참 많다. http://spectrumdig.blogspot.com/2012/01/array-method-iteration.html Array 의 경우 위의 글을 참조. 그런데 Object는 Array처럼 다양하고 Chaining 이 가능한 방법이 없다. 기껏해야 for (var obj in jsonObject) 정도. 게다가 속도문제도 있어서 ( http://jsperf.com/for-vs-foreach/9  참조) 가독성과 코드 단순화도 좋지만 요즘같이 Rich Web Application + Mobile Web 시대에 쓰기엔 효율이 나쁜 방법이긴 하다. coffeescript 의 경우 object 와 array 에 대해 어느정도 비슷한 처리방식을 제안한다. array : <statement> for <variable> in <array> object : <statement> for <variable>,{<variable>} in <object> 와 같은 형식이다. object 의 경우 variable 로 key, value 형식을 쓸 수 있는데 value 를 생략할 수 있다. 예를 들면 아래와 같다. console.log arr for arr in [1,2,3,4,5] console.log k,v for k,v of a:1, b:2, c:3 물론 당연히 두개를 혼합해서 쓸 수도 있다. console.log k,v for k,v of obj for obj in [ {a:1, b:2}, {a:3, b:4 }, {a:1, c:4} ] 결과는 아래와 같다. a 1 b 2 a 3 b 4 a 1 c 4 재미있는 점은 둘 다 공히 when 이라는 조건절을 넣어서 filter 를 할 수 있다. console.log k,v for k,v of a:1,...

Meteor로 진지하게 접근해 보는 Rapid Prototyping web application

일단 진지진지 열매 10개 먹고 시작하자. 1. 빠르게 만들고 2. 적게 코드를 쓰고 3. 시각적으로 보기 좋을 것 필요한 건 뭐? 1. 빠르게 만들 프레임 워크 2. 적게 코드를 쓸 수 있는 언어 3. 시각적인 뼈대를 받쳐줄 템플릿 내가 선택한 건? 1. Meteor 2. Coffeescript + Less 3. Twitter bootstrap 자 시작해볼까? 미리 설치해야할 것들 1. node.js + npm ( http://nodejs.org/#download ) 2. meteor ( http://meteor.com/ ) 3. Coffeescript (npm install -g coffee-script) 4. jQuery plug-in (meteor add jquery) 5. less plug-in (meteor add less) 6. coffeescript plug-in (meteor add coffeescript) 7. bootstrap plug-in (meteor add bootstrap) 4,5,6은 meteor 용 plug-in들인데 매번 less나 coffeescript를 컴파일하지 않아도 클라이언트쪽에서 쓸 수 있다는 점이 엄청 편하다. 글 쓰는 도중 meteor 가 0.3.4로 업데이트 되면서 bootstrap지원이 추가되었다. 만세! 일단 meteor 가 기본으로 생성한 css와 javascript 를 삭제하고 less와 coffeescript 로 교체하자. <프로젝트명>.coffee 파일은 이정도로 시작하자. # make Posts into global variable @Posts = new Meteor.Collection 'Posts' # when client if Meteor.is_client $.extend Template.add, events: 'click #add': -> Posts.i...

coffeescript 설치 및 개발환경 구성

먼저 coffeescript 관련 바이너리를 받자. node 가 깔려있으면 npm install -g coffee-script 해본다 coffee 라고 쳐서 뜨면 ok. Ubuntu 11.10에서 확인. 만일 경로를 못찾으면  http://stackoverflow.com/questions/6985457/cant-install-coffeescript-on-ubuntu-lts  여기 답변처럼 구버전을 깔아본다. wget --no-check-certificate https://registry.npmjs.org/coffee-script/-/coffee-script-1.1.2.tgz npm install -g coffee-script-1.1.2.tgz 순서대로 한다. 현재 1.3.1인데 1.1.2를 깔아쓰는게 굉장히 찝찝하지만 나중에 더 좋은 방법이 있으면 수정해야지. 아마 이 글을 읽는 여러분은 저짓을 안해도 되길 바란다. 해보니까 경로를 못찾아도 vim 실행하는데는 문제가 없으니까 그냥 내버려둔다. 그럼 다음으로 개발환경을 구성할 건데. 뭘 쓰든 상관없지만 vim 환경이 있으면 상당히 편하다. 차례대로 해보자. https://github.com/tpope/vim-pathogen  참조. 먼저 pathogen 을 설치. 복사해서 붙여넣자. wget 을 쓰고 싶으면 curl 대신 wget -o - mkdir -p ~/.vim/autoload ~/.vim/bundle; \ curl -so ~/.vim/autoload/pathogen.vim \     https://raw.github.com/tpope/vim-pathogen/HEAD/autoload/pathogen.vim 그 다음 ~/.vimrc 에 다음 한줄 추가하자. call pathogen#infect() 그 뒤로 진행할지는 알아서. 나는 일단 여기까지만 아까 만들어놓은 bundle 경로로 들어와서 coffee-script pl...