Ionic CLI 와 Meteor CLI 로 프로젝트 구성하기는 모바일 프로젝트를 진행할 때 사용하면 되고, 이번에는 Angular CLI 와 Meteor CLI를 통해 프로젝트 구성을 어떻게 하는지 살펴본다.
Webpack 기반 프로젝트 초기화
Angular CLI를 통해 프로젝트를 생성한다. @angular/cli v1.5.0이 설치되고, webpack은 v3.8.1 이고, 내부적으로 @angular-devkit, @ngtools/webpack, @schematics등이 사용된다.
$ npm install -g @angular/cli
@angular/CLI 설치후 프로젝트를 생성한다. ng <command>의 상세 내용은 위키를 참조한다.
$ ng new <projectName>
Webpack 환경파일을 수정해야 하므로, eject 명령을 수행하고, 결과로 출력된 가이드에 따라 "npm install" 명령을 수행한다. eject 명령에 대한 다양한 options은 위키를 참조한다. eject시에 옵션을 주면 옵션이 적용된 webpack.config.js가 생성된다.
$ ng eject --aot --watch
====================================================
Ejection was successful.
To run your builds, you now need to do the following commands:
- "npm run build" to build.
- "npm test" to run unit tests.
- "npm start" to serve the app using webpack-dev-server.
- "npm run e2e" to run protractor.
Running the equivalent CLI commands will result in an error.
====================================================
Some packages were added. Please run "npm install".
$ npm install
$ npm run build
eject를 수행한 경우에는 "ng serve" 명령으로 테스트 서버를 뛰울 수 없다. package.json에 적용된 스크립트인 "npm start"를 수행하고 4200 port로 브라우져에서
$ npm start
10% building modules 3/3 modules 0 activeProject is running at http://localhost:4200/
webpack output is served from /
....
Webpack 환경 내역은 크게 entry, output, module (for loader), plugins 로 구성된다. (참조)
- entry: 파일 위치
- output: 결과 위치
- module: css, .ts, .html 파일 관리 및 변환기 -> 자바스크립트 모듈로 만들기 위한 것. postfix가 "-loader" 이다. 로더는 파일단위 처리
- plugins: 압축, 핫로딩, 복사, 옮기기등. 플러그인은 번들된 결과물을 처리
Angular CLI 환경에 Meteor 설정
이전 포스트처럼 루트에 api 폴더를 만들고 이를 Meteor의 백앤드로 사용토록 설정한다.
// webpack.config.js
const webpack = require('webpack');
...
resolve: {
alias: {
'api': path.resovle(__dirname, 'api/server'),
...
}
}
externals: [ resolveExternals ],
plugins: [ ..., new webpack.ProvidePlugin({ __extends: 'typescript-extends' }) ],
node: { ..., __dirname: true }
// 맨 마지막에 넣음
function resolveExternals(context, request, callback) {
return resolveMeteor(request, callback) ||
callback();
}
function resolveMeteor(request, callback) {
var match = request.match(/^meteor\/(.+)$/);
var pack = match && match[1];
if (pack) {
callback(null, 'Package["' + pack + '"]');
return true;
}
}
루트에 있는 tsconfig.json에 Meteor 백앤드 관련 내용을 추가한다.
"compilerOptions: {
"baseUrl": ".",
"module": "commonjs",
...
"skipLibCheck": true,
"stripInternal": true,
"noImplicitAny": false,
"types": [ "@types/meteor" ]
},
"include": [ ..., "api/**/*.ts" ],
"exclude": [ ..., "api/node_modules", "api" ]
src/tsconfig.app.json과 tsconfig.spec.json안에 api에 대한 exclude도 설정해야 한다.
// src/tsconfig.app.json
"exclude": [
...,
"../api/node_modules"
]
// src/tsconfig.spec.json
"exclude": [ "../api/node_modules" ]
관련 패키지를 설치한다.
$ npm install --save-dev typescript-extends
$ npm install --save-dev @types/meteor
$ npm install --save-dev tmp
Meteor Server API 생성 및 설정
Meteor CLI를 설치하고 api 명으로 Meteor 프로젝트를 생성한다.
$ curl https://install.meteor.com/ | sh
$ meteor create api
api 폴더 밑의 필요없는 폴더를 삭제하고 루트에 있는 것으로 대체한다.
$ cd api
// 삭제
api$ rm -rf node_modules client package.json package-lock.json
// 심볼릭 링크
api$ ln -s ../package.json
api$ ln -s ../package-lock.json
api$ ln -s ../node_modules
api$ ln -s ../src/declarations.d.ts
Meteor 백앤드를 Typescript 기반으로 개발하기 위한 패키지를 설치한다.
api$ meteor add barbatus:typescript
api$ cd ..
$ npm install --save babel-runtime
$ npm install --save meteor-node-stubs
$ npm install --save meteor-rxjs
Typescript의 tsconfig.json 파일을 api 폴더안에 생성하고 다음 내역을 붙여넣는다.
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"dom",
"es2017"
],
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"target": "es6",
"skipLibCheck": true,
"stripInternal": true,
"noImplicitAny": false,
"types": [
"@types/meteor"
]
},
"exclude": [
"node_modules"
],
"compileOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
Meteor의 server/main.js를 main.ts로 바꾼다. 위에서 설치한 meteor-rxjs는 클라이언트단의 Meteor를 RxJS Observable기반으로 사용할 수 있도록 한다.
// 예) Meteor 클라이언트단 Collection 구성
import { MongoObservable } from 'meteor-rxjs';
export const Chats = new MongoObservable.Collection('chats');
Meteor Client 준비
Meteor Server <-> Client 연동을 위해 Client를 Bundling한다.
$ sudo npm install -g meteor-client-bundler
번들링시에 Meteor Server 기본 주소는 localhost:3000 으로 설정된다. Meteor Client는 DDP를 이용하기 때문에 번들할 때 --config 옵션 또는 --url 옵션으로 Meteor Server 위치를 지정한다. -s 옵션을 주면 Client<->Server 같은 버전의 패키지를 사용하고 -s 옵션을 주지않으면 config 설정내용을 참조한다. (참조)
$ meteor-client bundle --destination meteor.bundle.js --config bundler.config.json
// config file
{ "release": "1.6", "runtime": { "DDP_DEFAULT_CONNECTION_URL": "http://1.0.0.127:8100" }, "import": [ "accounts-base", "mys:accounts-phone", "jalik:ufs@0.7.1_1", "jalik:ufs-gridfs@0.1.4" ] }
package.json에 번들링 명령을 등록하고 수행한다.
"scripts": {
...,
"meteor-client:bundle": "meteor-client bundle -s api"
}
//번들링 - 최초 한번만 수행한다.
$ npm run meteor-client:bundle
Angular 클라이언트에서 Meteor Client를 사용하기 위해 src/main.ts에서 "meteor-client"를 import한다.
import "meteor-client";
Collection 생성하고 Meteor 기능 사용 테스트
api/server 에 model을 하나 만든다. Angular와 Meteor가 같이 사용하는 모델 타입이다.
// api/server/models.ts
export enum MessageType {
TEXT = <any>'text'
}
export interface Chat {
_id?: string;
title?: string;
picture?: string;
lastMessage?: Message;
memberIds?: string[];
}
export interface Message {
_id?: string;
chatId?: string;
senderId?: string;
content?: string;
createdAt?: Date;
type?: MessageType;
ownership?: string;
}
api/server/collections 폴더를 생성하고 Chat 컬렉션을 생성한다. meteor-rxjs 는 RxJS로 Mongo Client를 wrapping해 놓은 것으로 Rx방식으로 Mongo Client를 사용할 수 있게 한다.
// api/server/collections/chats.ts
import { MongoObservable } from 'meteor-rxjs';
import { Chat } from '../models';
export const Chats = new MongoObservable.Collection<Chat>('chats');
// api/server/collections/messages.ts
import { MongoObservable } from 'meteor-rxjs';
import { Message } from '../models';
export const Messages = new MongoObservable.Collection<Message>('messages');
api/server/main.ts안에 샘플 데이터를 넣는다.
$ npm install --save moment
// api/server/main.ts
import { Meteor } from 'meteor/meteor';
import { Chats } from './collections/chats';
import { Messages } from './collections/messages';
import * as moment from 'moment';
import { MessageType } from './models';
Meteor.startup(() => {
// code to run on server at startup
if (Chats.find({}).cursor.count() === 0) {
let chatId;
chatId = Chats.collection.insert({
title: 'Ethan Gonzalez',
picture: 'https://randomuser.me/api/portraits/thumb/men/1.jpg'
});
Messages.collection.insert({
chatId: chatId,
content: 'You on your way?',
createdAt: moment().subtract(1, 'hours').toDate(),
type: MessageType.TEXT
});
chatId = Chats.collection.insert({
title: 'Bryan Wallace',
picture: 'https://randomuser.me/api/portraits/thumb/lego/1.jpg'
});
Messages.collection.insert({
chatId: chatId,
content: 'Hey, it\'s me',
createdAt: moment().subtract(2, 'hours').toDate(),
type: MessageType.TEXT
});
}
});
다음으로 Angular에 Chat 컬렉션을 사용한다.
// src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { Chats } from '../../api/server/collections/chats';
import { Chat } from '../../api/server/models';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
chats: Chat[];
ngOnInit() {
Chats.find({}).subscribe((chats: Chat[]) => this.chats = chats );
}
}
// src/app/app.component.html 에 추가
<div> {{ chats | json }} </div>
Angular & Meteor 기동
Meteor 기동
$ cd api
api$ meteor
Angular 기동
$ npm start
Webpack dev server는 4200이고, meteor client는 server에 websocket 3000 port로 접속을 한다. Meteor 의 mongo로 접속해서 chats collection을 확인해 본다.
$ meteor mongo
MongoDB shell version: 3.2.15
connecting to: 127.0.0.1:3001/meteor
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
meteor:PRIMARY> show collections
chats
messages
하단에 Chat 내역이 json 형식으로 출력된다.
<참조>
- Meteor Client bundler의 작도방식 by Uri
- Meteor Client Bundler Github
'Meteor > Angular + Meteor' 카테고리의 다른 글
[Meteor 1.6] Clarity CSS Framework 적용하기 (0) | 2017.11.15 |
---|---|
[Meteor 1.6] Ionic + Meteor 기반 프로젝트 만들기 (0) | 2017.11.06 |