기본 콘텐츠로 건너뛰기

2017의 게시물 표시

expo 일기 (/w react-native)

1. EXPO 들어가기 전 react-native-starter-app 으로 시작을 해보니 역시 팀원들끼리 머릿속에 있는 그림이 조금씩 달라서 설정에 좀 애를 먹긴 했다.

일단 실행할 때

npm installreact-native upgrade (ios/android 문제시)react-native link react-native-vector-iconsreact-native run-ios (or run-android) 이와 같이 진행하니 큰 문제는 없었다.
맘에 드는 부분은 directory 구조와 component 구조가 반복적으로 복사해서 써도 좋을 만큼 잘 되있고 theme 도 깔끔했다. 컴포넌트 외부에서 접근하는 database, login 등은 redux로 분리해놓았다. 이 부분은 좀 생각해봐야겠다. 과연 최선인지.
일단 expo를 빈 윈도우 컴터에 npm install -g exp 를 통해 설치하고 expo GUI 툴 없이 진행하기로 함. 뭐야 이거 무서워 스캔하니 잘 된다. 빌드 안해도 되니 넘 좋은 거. 어디보자 react-native-starter-app 로 했을 때 좋았던 걸 뭘 쓸까. firebase 오케이 react-native-calendars 속도가 좀 느린 거 같은데 불만 없는 기능이다. wix 답네 react-native-elements 종합선물. 기본으로 깔고 가자. react-native-gifted-chat 채팅. 좋은데 이번엔 쓸일이 없다. react-native-google-analytics-bridge 아주 좋다. GA는 고객이 더 좋아하겠다. react-native-router-flux 라우터. 태그로 하는 것보다 코드가 더 낫다. 봉인. 안쓸래. react-navigation 쓸린다. 어짜피 같은 기반. react-native-side-menu 사이드 메뉴. 괜찮았다. react-native-vector-icons 아이콘 모음. 없는게 없다. react-native link react-native-vector-icon…

meteor로 nw.js 개발하기.

실제로 nw.js 어플리케이션을 개발하다보면 UI구현하기 막막하고 수동으로 리프레쉬 하는 것도 귀찮아서 Meteor 연동을 하려고 했더니 생각보다 간단했다.

디렉토리 구조는 먼저 이렇게 잡았다.
`- app
  `-client
  `-public
`- dist
  `- 배포용 html,css,js
  `- package.json
`- package.json 아이디어는 이렇다. nw.js의 시작페이지를 http://localhost:3000으로 두고 배포시엔 meteor client 배포툴인 meteor-build-client를 사용하여 html,css,js 로 분리하는 계획이다.

가장 중요한 nw.js 용 package.json 파일은 아래와 같이 구성한다.
{
  "main": "http://localhost:3000",
  "node-remote": "http://localhost:3000",
  "name": "<앱이름>"
} 이게 전부. 어떻게 보면 Web과 nw.js를 동시에 개발할 수도 있는 환경이기도 한 것이다.
meteor create app 을 해서 meteor용 앱을 만들고 meteor 를 시작한다.
그리고, 위의 package.json이 있는 경로로 돌아가서 nw . 으로 nwjs를 실행한다.

한번 번쩍하더니 잘 된다.
cordova 등에서 index.html 대신 http://localhost:3000을 하는 것도 비슷한 느낌이다.

즐겁게 개발을 일단 마구 하고 실제로 배포하기 위해서는 개발환경이 아니라 html,css,js로 구성된 배포본을 만들어야한다.
npm install -g 해도 되지만 어짜피 Meteor에서만 쓸거
meteor npm install -g meteor-build-client 해버릴거다.

개발은 문제 없어 보이고 배포판을 한번 만들어보자. meteor app 이 있는 경로(meteor run으로 …

Peatio 분투기

흠 요즘은 ruby 할때 puma(https://github.com/puma/puma)를? 패신저는 안쓰남.
https://github.com/peatio/peatio/blob/master/doc/setup-local-osx.md
로컬 환경 먼저 잡자.
brew, rbenv 설치하고 ruby를 2.2.1로 설정하자.
gem install bundler을 설치
Fetching: bundler-1.15.4.gem (100%)
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.

sudo chown -R $USER /Library/Ruby/Gems/ 하고 나면
gem install bundler
Fetching: bundler-1.15.4.gem (100%)
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /usr/bin directory.

또 오류. 에잇 귀찮아 sudo install bundler 해버림.

mysql 설치
brew install mysql 설치하고
mysql.server start 기동.

redis 설치
brew install redis
redis-server /usr/local/etc/redis.conf

rabbitMQ 설치 얘는 /usr/local/sbin 여기에 설치되니
brew install rabbitmq
rabbitmq-server


bitcore 도 다운 받고 https://bitcoin.org/en/download

mkdir -p ~/Library/Application\ Support/Bitcoin
touch ~/Library/Application\ Support/Bi…

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.coffee, mutation.coffee...
        collection.coffee
        permissions.coffee
  routes.coffee
\server의도하고자 하는 바는 이렇다.

component, models 과 같은 기본 요소들은 client/server 양쪽에서 로드할 수 있도록 최상위 lib 디렉토리 아래…

Troubleshooting - Meteor package가 적용이 되지 않을 때

버전 1.5 기준 package.js에서 Package.onUse 에 새 패키지를 추가했는데 인식하지 못하는 경우가 있다.
Package.onUse((api) => {
  api.use([
    'vulcan:core',
    'vulcan:forms',
    'vulcan:accounts' /* <-- 추가함! */
  ]);
...
} 내부패키지건 원격패키지건 안되는 안된다. 이럴 때 meteor add 후 meteor remove 해도 되지만 더 간단한 방법이 있다. meteor update vulcan:accounts 이렇게 update 해주는 방법이 있다. .meteor/package 파일을 건들지 않아서 좋다. 그래도 역시 좋지 않다. Meteor 스럽지 않다. https://github.com/meteor/meteor/issues/7721 현재 1.5.2에서도 해결이 안되었군요. 해결되어 적용되면 다시 글 올리겠습니다.

vulcanJS - 부록 Appendix A. Mutation (delete) 보강

Posts를 만들면서 약간 아쉬웠던 부분은 Delete 부분에 대해서 너무 SmartForm에 의지하여 간단하게 넘어가긴 했다.
showRemove={true} 옵션을 통해 한줄 찍 긋고 Delete라고 나오는 부분을 클릭하는 것도 좋지만
목록에서 지우거나 상세 보기에서 지울 일도 분명 있을 것이다.

역시나 이것도 목록(ex. withList)을 가져올 때 처럼 HoC(Higher-Order Component)를 사용한다.
http://docs.vulcanjs.org/mutations.html#Remove-Mutation 부분을 참조하자.

이번에 구현할 것은 목록마다 remove 버튼을 달고 버튼을 누르면 이벤트를 받아 삭제하도록 구현해보자.
import { registerComponent, withList, withRemove } from 'meteor/vulcan:core'; 먼저 해야할 것은 withRemove를 import에 추가하는 것이다.
그러면 withRemove를 registerComponent시 사용할 수 있다.
withList와 함께 withRemove도 추가하자.
registerComponent('PostsListComponent', PostsListComponent, [
  withList, {
    collection: Posts
  }], [
  withRemove, {
    collection: Posts
  }
]); withRemove도 withList와 동일하게 collection만 지정하면 된다. 준비는 다 되었다. withRemove를 붙여서 this.props는 removeMutation을 갖게 되었다. removeMutation의 사용법은 다음과 같다. this.props.removeMutation({
  documentId: documentId
}).then(/* success */).catch(/* error */); promise를 지원한다. 오류처리는 catch에 정상적 완료 후에 …

vulcanJS - 10. Posts Update/Delete

마지막으로 수정과 삭제를 구현해보면 목록 조회(List), 상세 조회, 쓰기, 수정, 삭제까지 모든 필요한 요소를 아우를 수 있을 것이다.
감이 좋은 분들은 눈치 챘을지도 모르겠지만 사실 수정이란 건 UI면에서 볼때 이미 양식이 채워져있는 신규 쓰기와 별반 다르지 않다.

먼저 해야할 것은 역시나 Component를 만드는 일이다.
$ vulcan g component
? Package name spectrum-simplebb
? Component name PostsEditComponent
? Component type Class Component
? Register component Yes
   create packages/spectrum-simplebb/lib/components/PostsEditComponent.jsx
 conflict packages/spectrum-simplebb/lib/components/index.js
? Overwrite packages/spectrum-simplebb/lib/components/index.js? overwrite
    force packages/spectrum-simplebb/lib/components/index.js PostsEditComponent를 만들었다.
route도 만들자. /posts/edit/:id 이렇게 경로를 만들면 좋겠다. 그러고보니 이전 글에서 만든 상세보기도 /posts/view/:id 형식으로 만들껄 그랬다.
$ vulcan g route
? Package name spectrum-simplebb
? Route name postsEdit
? Route path /posts/edit/:_id
? Component name PostsEditComponent
? Layout name
 conflict packages/spectrum-simplebb/lib/modules/routes.js
? Overwrite packages/spectrum-simplebb/lib/modules/routes.js? overwrite
   …

vulcanJS - 9. Route 연결하기

Route들끼리 연결에 대해 알아보자고 지난 시간에 말씀드렸는데
Vulcan에선 React-router(https://reacttraining.com/react-router/web/api/Link)를 사용하므로 그 규칙을 그대로 따르면 됩니다.
<Link to='경로명'>표시할 이름</Link> 형식으로 씁니다.
PostsSingleComponent 에 <Link to='/'>to Home</Link> 를 추가하여 처음으로 돌아가도록 합시다.
import React, { Component } from 'react';
import { Link } from 'react-router';
import { registerComponent, withDocument } from 'meteor/vulcan:core';
import Posts from "../modules/posts/collection.js";
class PostsSingleComponent extends Component {
  render () {
    return (
      <div>
        <h1>{this.props.document.title}</h1>
        <pre>
          {this.props.document.body}
        </pre>
        <Link to='/'>to Home</Link>
      </div>
    );
  }
}
registerComponent('PostsSingleComponent', PostsSingleComponent, [withDocument, {
  collection: Posts
}]);
export default PostsSingleComponent; 평범합니다. 이…

vulcanJS - 8. Posts View 상세보기

지금까지 Posts 의 목록을 조회하고 생성하는 걸 해보았습니다.
목록을 봤으니 목록 중 하나를 선택하여 상세 내용을 보고 수정/삭제를 할 수 있으면 데이터 처리 한 바퀴를 온전히 돌 수 있다고 볼 수 있습니다.

먼저, 상세보기를 만들어봅시다.
시작은 Component부터 하도록 하지요.
PostsViewComponent라는 걸 만들어 봅시다.
$ vulcan g component
? Package name spectrum-simplebb
? Component name PostsViewComponent
? Component type Class Component
? Register component Yes
   create packages/spectrum-simplebb/lib/components/PostsViewComponent.jsx
 conflict packages/spectrum-simplebb/lib/components/index.js
? Overwrite packages/spectrum-simplebb/lib/components/index.js? overwrite this and all others
    force packages/spectrum-simplebb/lib/components/index.js 슥삭 만들고 Route를 만들어 URL을 통한 접근을 시도해봅니다.
Route이름은 postsView라고 하고 /posts/:_id 와 같은 형식으로 접근하게 해보죠.
$ vulcan g route
? Package name spectrum-simplebb
? Route name postsView
? Route path /posts/:_id
? Component name PostsViewComponent
? Layout name
 conflict packages/spectrum-simplebb/lib/modules/routes.js
? Overwrite packages/spectrum-simplebb/lib/modules/routes.js? ove…

vulcan 추천사

왜 Vulcan인가요?

유명한가요?
이걸 배워도 괜찮은 건가요?
취직은 잘 되나요?
회사에 필요한가요?
많이들 쓰나요?
앞으로 유망한가요?

항상 강의(보통 국비지원인 무료 수강)를 할때마다 자주 들었던 질문인데요.
vulcan은 제 생각엔 이 질문들에 대해 모두 "예"일수도 "아니오"일수도 있다고 생각합니다.

왜냐면 vulcan는 framework이며 제품으로 치면 반쯤은 조립이 된 제품으로 구성한 IKEA 같은 거라서 팝업 스토어나 전시실에 있는 걸 보고 구성하거나 아니면 처음부터 하나하나 자신이 구성하듯이 Apollo, AutoForm(aka. smartForm), Collection2, Email Templating, GraphQL, Meteor, MongoDB, React, Router, Server-sided rendering 등등 각각 검증된 요소들로 웹앱을 만들 수 있습니다.

질문에 대한 답을 드리자면 vulcan 자체는 "아니오"일 수도 있지만 vulcan에 들어가는 요소들은 "예"라고 할 수 있는 것들이 꽤 많습니다.

웹은 프로그래밍 분야 중에서도 제법 오래되고 안정된 분야이면서 동시에 대중적인 인기를 업고 많은 실험과 혁신을 시도하고 있는 분야이기도 합니다.
사용자 입장과 달리 만드는 사람 입장에선 눈에 보이는 부분(frontend)에서부터 보이지 않는 부분(backend)까지 세심하고 정밀하게 고려해야하고 오랜기간 웹에 노출된 노련한 사용자들은 당신이 어떤 부분이 부족한지 금방 알아차립니다.
이 부분은 만드는 사람 입장에선 꽤 괴로운 일입니다. 기술의 변화는 빠르고 학습해야할 양은 늘어나며 구현해야할 디테일은 더욱 엄격하게 평가받습니다.

Vulcan은 대부분 최신(Cutting edge) 기술들로 가득하며 각각 기술에 대해 깊은 이해가 있다면 좀 더 예리하게 만들 수 있지만 최소한의 학습양으로도 당장 작동하는 결과물을 만들 수 있습니다.
Vulcan은 Meteor Pla…

vulcanJS - 7. Posts 쓰기

이번엔 아주 간단합니다.
왜냐면 Posts 쓰기를 할 것이고 우리는 SmartForms를 이용해서 끝낼려고 하거든요.

Component를 또 만듭시다.
이름은 PostsNewComponent가 좋겠군요.
$ vulcan g component
? Package name spectrum-simplebb
? Component name PostsNewComponent
? Component type Class Component
? Register component Yes
   create packages/spectrum-simplebb/lib/components/PostsNewComponent.jsx
 conflict packages/spectrum-simplebb/lib/components/index.js
? Overwrite packages/spectrum-simplebb/lib/components/index.js? overwrite
    force packages/spectrum-simplebb/lib/components/index.js 이제 다 할 줄 아시죠?
vulcan g component 를 써서 진행합니다.
HomeComponent.jsx 에도 추가해야겠네요.
import React, { Component } from 'react';
import { registerComponent, Components } from 'meteor/vulcan:core';
class HomeComponent extends Component {
  render () {
    return (
      <div>
        Find me at packages/spectrum-simplebb/lib/components/HomeComponent.jsx
        <Components.PostsListComponent />
        <Components.PostsNewComponent />
      </div>
    );
 …

vulcanJS - 6. Posts 조회화면 만들기

지난 번 글까지 잘 따라오셨으면 사용자 하나와 Posts 하나를 얻은 상태입니다.
그럼 이제 Posts가 있으니 브라우저 화면에서 보도록 합시다.

먼저 Posts의 목록을 보여줄 Component를 만들어봅니다.
이름은 PostsListComponent가 좋겠군요.
이젠 알아서 하시죠.
$ vulcan g component
? Package name spectrum-simplebb
? Component name PostsListComponent
? Component type Class Component
? Register component Yes 하고 PostsListComponent를 만듭니다.
그리고 HomeComponent.jsx안에 PostsListComponent를 넣어 봅니다.
import React, { Component } from 'react';
import { registerComponent, Components } from 'meteor/vulcan:core';
class HomeComponent extends Component {
  render () {
    return (
      <div>
        Find me at packages/spectrum-simplebb/lib/components/HomeComponent.jsx
<Components.PostsListComponent />
      </div>
    );
  }
}
registerComponent('HomeComponent', HomeComponent);
export default HomeComponent; render가 반환값의 마지막 부분에 <Components.PostsListComponent /> 를 추가합니다. 앗차. import 에서도 Components 를 추가해줍니다.
<Components.PostsListComponent /> 해도 되는 걸까요? import로 PostsListC…

vulcanJS - 5. graphQL 도구 사용해보기.

지난 번 글에서 열심히 Posts 모델을 만들어 보았습니다.
이것들을 실제로 graphQL을 사용하여 다루기 위해 graphQL 도구를 사용해봅니다.
http://localhost:3000/graphiql 를 한번 열어봅시다.

뭔가 깔끔한 것이 떴습니다.
GraphQL은 듣기로 JSON 같은 걸로 지지고 볶는 구조라고 들었습니다.
한번 본능에 이끌려 이것저것 해봅니다.
{} 를 한번 치고 자동완성을 위해 중간중간 ctrl+space도 눌러보고 해봅시다.
http://imgur.com/0c9BkRK 새창에서 열기
의식에 흐름에 따라 query와 mutation이라는게 오른쪽 Documentation Explorer에 있고 자동완성한 내용을 cmd+click해서 내용을 보고 인자를 아무거나 넣고 ctrl+enter로 실행하는 것까지 해봤습니다.
실제로 Full로 Query를 쓰고 Query Variables(아래쪽 Query Variables 클릭하면 확장됨)까지 넣으려면
query postsListQuery($terms: JSON) {
  PostsList(terms: $terms ) {
    _id
    title
    body
    userId
    createdAt
  }
}
* Query Variable
{
  "terms": {
  }
} 위와 같이 하면 됩니다.
오른쪽 결과 창을 보면 내용물이 없습니다.
당연합니다. 모델만 만들었기 때문이죠.
오른쪽 Documentation Explorer를 한번 살펴봅시다.

친절한 익플띵
ROOT TYPES 에 query하고 mutation이 보입니다.
query는
SiteData: Site
UsersList(
  terms: JSON
  offset: Int
  limit: Int
): [User]
UsersSingle(documentId: Stringslug: String): User
UsersTotal(terms: JSON): Int
currentUser: User
PostsList…

vulcanJS - 4. 글쓰기를 위한 graphQL 모델 만들기

조금 어려울지도 모릅니다.
이제까지 쉽게쉽게 왔습니다만 여기서부터 갑자기 이것저것 많이 나옵니다.
그러니 너무 상심하지말고 차분하게 따라가봅시다.

신나는 백엔드의 세계에 오신 걸 환영합니다 :)
글쓰기를 구현하기 위해 Posts라는 모델을 만들어봅시다.
여담이지만 N개의 목록으로 구성하는 것들을 Collection이라고 하는데 보통 복수형인 s를 뒤에 붙여서 만드는 것이 일반적입니다. 첫글자를 대문자로 시작하는 Camel Notation도 사용합니다.
$ vulcan g model 하고 쳐봅니다.
패키지 이름 선택하고 나서 Model name을 입력합니다. resolvers와 mutations는 디폴트 No로 엔터엔터하시고나면 ? Add a custom property to the collection (y/N) 라고 나옵니다.
$ vulcan g model
? Package name spectrum-simplebb
? Model name Posts
? Add custom resolvers No
? Add custom mutations No
? Add a custom property to the collection (y/N) 소스를 수정해서 해도 되지만 우리는 아무것도 아는게 없으니 custom property를 줘서 만들어봅시다.
글쓰기에서 중요한 게 무엇일까요?
잘 생각이 나진 않지만 최소 "제목", "본문글" 정도는 있어야겠다는 생각이 듭니다.
일단 y 하고 title, body를 각각 String 타입으로 생성해봅시다.
? Add a custom property to the collection Yes
? Property name title
? Property is hidden No
? Property label Title
? Property type String
? Property is optional No
? Property viewable by Guests
? Property insertable by Members

vulcanJS - 3. 최초의 router

순서를 무얼 먼저 할까 잠깐 고민해보았는데 역시 화면에 무언가 보이지 않으면 답답하다.
그래서 이번엔 두 가지를 구현해보고자 한다.

component 생성router 생성
별것 아니지만 순서를 잘못 이해하면 혼란스러울 수도 있다.
다행히 본인(^ㅡ^)이 잘 정리해드릴 것이므로 걱정하지 마시라.
1. Component 생성 최초의 화면 구성 요소인 component. 즉 Home을 만들자.
이름은 HomeComponent라고 하자. XxxxComponent 형식으로 작성하면 이름으로 구분이 가서 알아보기 좋다. vulcan g component 라고 쳐서 component를 생성해보자.
$ vulcan g component
? Package name (Use arrow keys)
❯ spectrum-simplebb 인간은 오타의 동물이다. vulcan g component까지만 치고 화살표(라고 해봤자 지금은 하나밖에 없겠지만)로 선택하고 엔터 눌러주자.
? Component name HomeComponent
? Component type (Use arrow keys)
❯ Pure Function
  Class Component Component name으로 HomeComponent를 입력하고 나면 Component type을 고르라고 하는데 어짜피 Meteor는 babel이 있으므로 Class Component를 사용하자. 아래 한번 누르고 Class Component를 선택. 엔터.
그리고 yes yes (y 엔터)하면
$ vulcan g component
? Package name spectrum-simplebb
? Component name HomeComponent
? Component type Class Component
? Register component Yes
   create packages/spectrum-simplebb/lib/components/HomeComponent.jsx
 conflict packages/spectrum-simplebb…

vulcanJS - 2. package를 만들자.

vulcan application은 package 기반이다.
그래서 제일 먼저 해야할 일은 package를 만드는 것.
g(generate) pakcage 명령을 사용하자.
$ vulcan g package spectrum:simplebb
? Package name spectrum:simplebb
   create packages/spectrum-simplebb/package.js
   create packages/spectrum-simplebb/lib/client/main.js
   create packages/spectrum-simplebb/lib/server/main.js
   create packages/spectrum-simplebb/lib/server/seed.js
   create packages/spectrum-simplebb/lib/modules/index.js
   create packages/spectrum-simplebb/lib/components/index.js
   create packages/spectrum-simplebb/lib/modules/routes.js
To activate your package, run: meteor add spectrum-simplebb 어째서인지 spectrum이라는 namespace를 줬는데 spectrum-simplebb로 생성이 된다. 기분이 나쁘다. PR을 언젠가 해야지하는 생각만 하고 손으로 고치자. ./packages/spectrum-simplebb/package.js 를 열고 Package.describe({
  name: 'spectrum-simplebb',
}); 이 부분을 : 을 적용해서 고쳐주자. Package.describe({
  name: 'spectrum:simplebb',
}); 자 그럼 말 안듣고 meteor add spectrum:simplebb 해본다. $ meteor add spectrum:simplebb

Changes to your p…

vulcanJS - 1. vulcan-cli 설치하고 프로젝트 만들기

vulcanJS를 학습하면서 알아낸 점을 기록하는 의미의 튜토리얼을 써본다.

Telescope도 그랬지만 forum 형태의 예제에서 embedly를 사용하는 URL 요소가 글에 들어가는 점이나 일반인들에게는 익숙하지 않은 Markdown 문법 등을 걷어내고 최소형태에서부터 접근해야할 필요성을 느껴서 단순 post만 목록 열람하고 읽고 쓰는 구현을 해보기로 했다.

먼저, vulcanJS를 github를 통해 clone 하고 meteor create --package를 통해 만들수도 있지만 Vulcan-Cli(https://github.com/VulcanJS/vulcanjs-cli)가 있어서 이걸 일단 사용해보기로 한다.

대충 내용을 읽어보니 Rails 생각이 나기도 하고 재밌어 보인다.
npm install -g vulcanjs-cli 혹은 meteor 에서만 한다면
meteor npm install -g vulcanjs-cli 이런 식으로 설치하고 쓰면 된다.
npm 에 global로 설치한 첫번째 경우 기준으로 진행해보겠다.
설치하고 난 뒤 vulcan 을 실행해보면
$ vulcan
vulcan usage:
Synopsis
  vulcan <action> <object> <...>
    <action>   Operation to perform
    <object>   Asset type (contextual to action)
    <...>      Parameters. If not provided, interactively entered
Project initialisation
  vulcan create <appName>
  vulcan init <appName>
Assets creation
  vulcan (generate|g) package <packageName>
  vulcan (generate|g) model <packageName>…