meteor logo

[번역] meteor: common mistakes

 

번역 – meteor: common mistakes

원문 : https://dweldon.silvrback.com/common-mistakes

지난 일년동안, 나는 대부분의의 시간을 스텍오버플로우SF devshop 에서 코드리뷰와 질문에 대답하는데 쏟아 부었습니다. 그런 과정에서 (나를 포함해서) 대부분의 미티어개발자들이 미티어를 학습 하면서 저지르는 실수와 오해의 특정 패턴이 있다는걸 알게 되었습니다.이 게시물에서 나는 당신이 그런 실수를 피할 수 있기를 희망하며, 가장 자주 발생하는 것들 중 일부를 소개 하고자 합니다.

Profile 편집

이런 코드를 사용 하시나요?

if (meteor. users (). profile. isAdmin) 
// 중요한 관리 작업을 수행하는 경우 

만약 사용하지 안는다면 유감이네요. 사용자들이 콘솔을 열고 다음과 같이 실행할 수 있습니다 :

Meteor.users.update(Meteor.userId(), {$set: {'profile.isAdmin': true}});

놀랍지 않나요?사용자의 프로파일은 insecure 모듈이 제거 되었다 하더라도 수정 가능합니다.이걸 방지 하기 위해서 다음과 같이 거부 규칙을 적용하세요:

Meteor.users.deny({
  update: function() {
    return true;
  }
});

Publish 되버린 비밀

그룹내의 모든 사용자를 리턴하는 publish 구문이 있다고 가정해 봅시다 :

Meteor.publish('groupUsers', function(groupId) {
  check(groupId, String);
  var group = Groups.findOne(groupId);
  var selector = {_id: {$in: group.members}};
  return Meteor.users.find(selector);
});

이코드의 문제는 무엇일까요? 리엑티브가 적용되지 않을까요?

특정 필드를 지정하지 않는한 몽고디비는 모든 필드를 리턴 할것입니다. 이것은 클라이언트가 모든 로그인 토큰과 암호화된 비밀번호와 다른 모든 사용자에 대한 정보를 볼 수 있다는걸 의미 합니다.

당신은 사용자의 비밀이 누출되는걸 방지하기 위해 사용자정보를 publish 할때는 배포할 필드를 항상 정의 해야 합니다. 수정된 함수는 다음과 같습니다. :

Meteor.publish('groupUsers', function(groupId) {
  check(groupId, String);
  var group = Groups.findOne(groupId);
  var selector = {_id: {$in: group.members}};
  var options = {fields: {username: 1}};
  return Meteor.users.find(selector, options);
});

키와 변수

풍부한 사용자 인터페이스를 만들기 위하여 동적 셀렉터를 사용하는것은 일반적입니다. 자, 사용자가  key의 텍스트 입력의 값(종, 크기, 지역등)으로 동물 컬렉션을 검색 할 수있다고 생각해 봅시다. 다음과 같이 코드를 작성 할 수 있습니다 :

var key = 'species';
var value = 'elephant';

var selector = {key: value};
Animals.find(selector);

그러나 자바스크립트는 이 민감한 문제를 잡아내기 때문에 우리는 올바른 find결과를 리턴 받지 못할것입니다. :

오브젝트리터럴(selector변수값) 에서 key 로 변수 식별자를 사용할경우 식별자가 적용되지 않습니다..

selector 는 실제로 {species: 'elephant'}가 아니라 {key: 'elephant'} 로 적용 됩니다. selector 값이 잘못된 것을 바로잡는 방법은 빈 오브젝트로 selector 초기화 하고 브라켓노테이션(“[ ]” 요거)을 key 로 사용하는 것입니다.

var key = 'species';
var value = 'elephant';

var selector = {};
selector[key] = value;
Animals.find(selector);

구독은 차단하지 못한다

미티어 프레임 워크의 많은 측면이 마법처럼 보이지만 그로 인하여 우리는 어떻게 웹브라우저가 작동하는지를 잃어 버립니다. 간단한 예를 보십시다 : 

Meteor.subscribe('posts');
var post = Posts.findOne();

이 코드에서 야기되는 결과인 postundefined 된다는 에러… 이것은 스텍오버플로우에 20여개의 질문에서의 문제 핵심 원인 이었습니다.

subscribe는 마치 정원의 호스와 같습니다. – 당신이 물을 틀어도 잠시후에 물이 흘러 나오듯이 말이지요. subscribe 를 실행한다고 해서 브라우저의 다른 코드를 멈추게 할수 없습니다. 따라서 find 한다고 해서 즉시 결과를 얻을수 없습니다. (왜냐면 어싱크니까)이것 때문에 언제 데이터가 실제로 도착하는지 추측하기가 어렵다. 다행히 이문제를 추적할 2가지 방법이 있습니다 :

  1. iron router 를 사용할경우 waitOn을 이용하여 subscribe 이후 싯점을 알수 있습니다.
  2. 템플릿 코드 내에 데이터가 있는지 guards 를 사용 하여 해결합니다.
    (이거 번역하다 링크에 보니 주옥같은 포스트가 또있네요. ㄴㄱㅁ)

UI 요구 사항에 따라 위에 두 가지 기술의 조합을 사용하는 것을 추천 합니다. subscribe 를 기다리는것은 페이지 랜더링을 강제로 지연 시키는 반면에 guards 는 단계적으로 데이터를 클라이언트 화면에 랜더링 할수 있게 합니다.

추론 : 미티어에서 “Cannot read property of undefined” errors 는 subscribe 시점과 사용시점에 대한 적절하지 못한 이해 에서 올수 있다.

정렬하여 publish 하기

클라이언트로 문서를 publish 할 때, 클라이언트는 minimongo 라고 하는메모리 저장소에 동일한 컬렉션으로 다른 문서와 통합 및 재배열 합니다. 여기서 중요한 점은 “재배열된다” 는 것입니다.

많은 새 미티어 개발자들은 배포된 데이터는 정렬되어 있을것 이라고 생각합니다.그래서 이런 질문  “난 정렬된 순서로 publish 했는데 왜 클라이언트에서 그렇게 안보이나?” 을 할꺼라고 예상됩니다. 거기에는 다음과 같은 간단한 법칙의 답변이 있습니다 :

만약 클라이언트에서 문서들이 정렬되야 하는경우 클라이언트에서 정렬해라

만약에 정렬 순서가 변하는 경우 (limit 같은걸 쓰는경우) 가 아니라면 publish 함수에서 정렬은 필요 하지 않습니다.

그럼에도 불구하고 데이터 전송 속도 때문에 서버사이드 정렬을 유지 해야 하는 경우가 있습니다. 에를들어 수백개의 블로그 글중 가장 최근의 10개의 게시물을 보여 줘야 하는경우. 이런 경우 최근 문서를 클라이언트에 먼저 내려 보낸다면 템플릿 랜더링 횟수를 최소화 할수 있습니다.

데이터 속성

데이터 속성을 사용하여 DOM에 있는 모든 당신의 어플리케이션 속성을 사용할수 있는 핵(hack)을 기억하나요?새로운 개발자들로 부터 아래와 같은 코드를 끊임없이 지켜 봐왔습니다 :

<template name="nametag">
  <div data-name="{{name}}">{{name}}</div>
</template>
Template.nametag.events({
  click: function(e) {
    console.log($(e.currentTarget).data().name);
  }
});

미티어는 이런 미친짓을 멈추게 합니다.
헬퍼나 , 이벤트 핸들러나 템플릿은 같은 context 를 공유 하기 때문에 다음같은 코드를 작성 할수 있습니다 :

<template name="nametag">
  <div>{{name}}</div>
</template>
Template.nametag.events({
  click: function(e) {
    console.log(this.name);
  }
});

경고 : 만약에 데이터 속성을 필요로 하는 jQuery 플러긴을 사용하는경우 필요 할수 있습니다.

 

 

역자 주 : 실제로 많은 질문을 받은 내용이기도 해서 잽싸 번역 해봅니다.
그런데.. 저 블로그가 통째로 주옥 같아서 괜히 하나만 건드렸나 싶기도 하고..
아무튼 즐거운 미티어 코딩하세요~!!

  • Facebook
  • Google Plus
  • Twitter
  • LinkedIn
  • Pinterest
  • Tumblr
  • Instapaper
  • Delicious