Skip to main content

109 posts tagged with "javascript"

View All Tags

· 8 min read

nodejs로 정말 간단한 oauth2, jwt 등의 인증을 사용하지 않는 API를 만들기에는 express가 정말 딱이다.

하지만 조금 더 깔끔한 코드를 원하거나 새롭지만 반복적인 기능을 넣기 위해선 더 큰 프레임워크가 필요했다.

조건

언제나 개발시간은 부족하기에 내가 필요한 기능들을 정리해 보았다.

  • await, async를 아무 세팅 없이 사용해 Promise chaining에서 벗어나고 싶다. (BabelWebpack을 직접 세팅하는 시간 걸리는 짓을 안하고 싶다.)
  • 기본적인 웹 보안기능 (validate, csrf, xss, injection) 및 API Throttle Request 기능이 있어야한다.
  • 소셜 로그인passport를 사용하지 않고 한 줄로 끝내고 싶었다.
  • JWT 인증, Log 기능, Bcrypt 암호화를 직접 붙히고 싶지 않다.
  • ORM에 맞게 E-commerce DB를 구조화했기 때문에 ORM이 꼭 필요하다.
  • 직관적이여야 한다. (Model과 Controller가 완벽히 나뉘는 구조를 원했다.)
  • 문서화가 완벽해야한다.
  • 커뮤니티Github Issue가 활성화 되어있어야한다.
  • 관리자 기능을 SSR로 해야할 가능성이 있어 템플릿 기능이 있어야하며, ejs는 절대 쓰고 싶지 않고 다른 템플릿을 직접 세팅해야하는 일은 더더욱 없어야한다.

이 조건을 거르니 adonisjs 라는 처음 보는 프레임워크가 눈앞에 있었다.

성능

image from hexo

나쁘지 않다. 어차피 nginx에서 reverse proxy 처리에, auto scaling 걸꺼고 그래도 더 빠른 속도를 원하면 golang으로 가야지 왜 이 포스트를 보고있나!

  • 여기서 자세한 내용을 확인할 수 있다.

평판

이 프레임워크를 쓰는 다른 사람은 어떻게 생각할까도 궁금했다.

Node.js broken ecosystem and rise of AdonisJs란 포스팅이 마음을 사로잡았다. 원문 읽을 시간이 없다면 이 글의 요약은 이 것이다.

Why not use Express + Sequelize + Config manager + Passport + dotEnv + NodeMailer + Node Validator +30 other modules. How assembling 100+ modules manually can be better than a beautifully pre-configured framework?

한글로 번역하면 왜 안 쓰시죠? 정도가 되시겠다.

시작하기

요구사항

  • Node >= 8.0
  • NPM >= 3.0

1711 기준 8.9가 LTS 버전이기 때문에 그냥 쓰면 된다.

Cli 설치

요즘 멋진 프레임워크들은 다들 cli를 가지고 있다.

$ yarn global add @adonisjs/cli

앱 설치

$ adonis new 프로젝트명
$ cd 프로젝트명
$ adonis serve --dev

localhost:3333에서 서버가 돌아간다. image from hexo

폴더 구조

.
├── ace
├── package.json
├── public
├── server.js
└── start
├── app.js
├── kernel.js
└── routes.js
파일/폴더설명
aceadonis에서 제공하는 cli 명령어 툴
package.json-
publiccss, js, images와 같은 public 리소스
server.jsHTTP 서버를 부트스트래핑한다. .env 파일의 PORT 변수를 따른다.
start/app.jsadonis 실행시 필요한 기능들을 부트스트래핑한다.
start/kernel.js미들웨어를 등록한다.
start/routes.js라우팅

라우팅

start/routes.js에서 등록한다.

메소드

Route 뒤에 method를 붙히면 된다.

Route.get("/boards", async () => {});

Route.get("/boards/:id", async ({ params }) => {
const board = await Board.find(params.id);
return board;
});

컨트롤러와 연결

Route.get("boards", "BoardController.index");
/* 리소스로 사용시에 */
Route.resource("boards", "BoardController");

/* 리소스에서 create, edit 메소드를 빼고 사용시 */
Route.resource("boards", "BoardController").apiOnly();

/* 구미가 당기는 것만 사용시 */
Route.resource("boards", "BoardController").only(["index", "destroy"]);

/* 구미가 안 당기는 것을 제외할 시 */
Route.resource("boards", "BoardController").except(["index", "destroy"]);

그룹화

보통은 기능이 비슷한 것 끼리 그룹화를 해서 가독성을 높인다.

/* /api/boards routes */
Route.group(() => {
Route.get("/boards", "BoardController.index");
Route.post("/boards", "BoardController.store");
}).prefix("api");

컨트롤러

cli에서 쉽게 생성이 가능하다.

$ adonis make:controller BoardController

리소스 컨트롤러

리소스가 대단한 건 아니고 미리 정의 된 메소드 7개로 RESTful API를 빠르게 만들기 위한 것이다.

$ adonis make:controller BoardController --resource

각 메소드들이 연결되는 건 다음과 같다.

  • index: GET boards
  • create: GET boards/create
  • store: POST boards
  • show: GET boards/:id
  • edit: GET boards/:id/edit
  • update: PUT boards/:id
  • destory: DELETE boards/:id

모델

하나의 모델은 하나의 테이블과 매칭된다고 보면 된다.

$ adonis make:model Board

모델 구조

모델 생성 후에 몇 가지 설정을 해줘야한다.

Board.js
class Board extends Model {
// 테이블 명을 변경해야할 경우
// (테이블 명이 모델명의 복수형이 아닐 경우)
static get table() {
return "board";
}

// 기본 커넥션이 변경될 경우
static get connection() {
return "mysql";
}

// PK 컬럼명이 id가 아닐 경우
static get primaryKey() {
return "uid";
}

// PK의 Auto Increment가 아닐 경우
static get incrementing() {
return false;
}

// 비밀번호 같은 컬럼을 보여주지 않아야 될 경우
// 이 경우 모델에서 fetch 또는 first 메소드로 쿼리빌더를 실행해야된다
static get hidden() {
return ["password"];
}

// 생성일 컬럼이 변경될 경우
static get createdAtColumn() {
return "created_at";
}

// 업데이트일 컬럼이 변경될 경우
static get updatedAtColumn() {
return "updated_at";
}
}

위 속성을 제외하고는 문서를 참조해보자.

기존 코드를 내려받을 때

.env.example 파일을 .env로 복사해 환경설정을 해주고 로그를 남기기 위해 tmp 폴더를 생성해준다

/
$ cp .env.example .env
# .env 파일을 수정하고

$ mkdir tmp

여담

이 프레임워크는 라라벨 스타일로 만들어졌기 때문에 (개념이 같다) 모던 PHP 개발자가 되는 건 식은 죽 먹기가 될 수 있다.

· One min read

expose-loader의 설치가 필요 없는 방법을 사용해보자

Vuejs-kr에 좋은 내용이 있지만 웹팩을 통해 jquery를 꺼내는 방법이 더 간단하다.

설치

$ yarn add jquery bootstrap

설정

webpack

build/webpack.base.conf.js
const webpack = require("webpack");

module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
jQuery: "jquery",
}),
],
};

eslint

.enlintrs.js
module.exports = {
globals: {
$: true,
jQuery: true,
},
};

연동

src/main.js
import "bootstrap";

new Vue({});

· One min read

뷰에 데이터가 바인딩 되기전 {{태그}} 구문이 보일 때 다음과 같이 하면 된다.

해결

v-cloak api에 자세하게 나와있다.

<!-- vue가 바인딩 될 영역에 v-cloak attribute를 추가한다 -->
<div id="vue_area" v-cloak></div>
[v-cloak] {
display: none;
}

더 멋진 방법

로딩시에 content 영역에 loading...이라는 문구를 찍어주는 방법으로 여기에 자세히 설명되어있다.

[v-cloak] > * {
display: none;
}
[v-cloak]::before {
content: "loading...";
}

· One min read

커스텀 validation을 추가해야할 때가 있다. created에 \$validator 인스턴스를 확장해주면 된다.

소스

const option = {
created: function () {
this.$validator.extend("customRule", {
getMessage: function (field, args) {
return "오류 메세지";
},

validate: function (value, args) {
// 체크 로직
return true;
},
});
},
};

모듈형태거나 전역설정이면 import { Validator } from 'vee-validate'; 후에 Validator.extend로 접근하면 된다.

사용법

추가한 룰 이름으로 v-validate 속성에 넣어주면 끝이다.

<input type="text" name="help" v-validate="'required|customRule'" />

스크립트 상에서 추가

attach 메소드로 붙히면 된다.

this.$validator.attach("help", "customRule");

다른 사용법은 공식문서를 참조하자

· One min read

Devtools inspection is not available because it's in production mode 란 메세지와 함께 Vue 개발자 도구가 표시되지 않을 경우에 script 상단에 아래 구문을 추가한다.

해결

Vue.config.devtools = true;

개발자 도구에 Vue 탭이 없을 때

ctrl+shift+i 키를 Vue 탭이 보일 때 까지 반복해서 눌러준다.

· One min read

다음 우편번호 검색 API 처럼 일본 우편번호 검색도 간단히 구현할 수 있다. 여기에서 내용을 확인할 수 있지만, 더 쉽게 써보자.

소스

<input type="number" id="zip" />
<button type="button" onClick="search_addr();">住所検索</button>

<input type="text" id="address" />
<!-- 스크립트를 로드 -->
<script src="//api.zipaddress.net/sdk/zipaddr.min.js" async></script>
<script>
var searchAddr = function () {
var $zip = $("#zip");
var zip = $zip.val();

// 일본 우편번호는 7자리로 고정되어있다.
// sample 6800001
if (zip && zip.length === 7) {
ZA.request(zip, function (data, err) {
var $address = $("#address");
if (err) {
$address.val("");
$zip.focus();
return alert(data.message);
}
$address.val(data.fullAddress);
$address.focus();
});
} else {
alert("郵便番号に誤りがあります。");
$zip.focus();
}
};
</script>

여담

주소지명으로 검색하는 API 는 찾아볼 수 없었다. 역시 주소검색은 다음

· 2 min read

최근 소스들을 까보다가 발견했는데, npm에 등록된 패키지를 CDN으로 바로 활용 가능한 서비스가 있다. 바로 unpkg이다. 리젼은 여기서 확인 가능하다.

사용

사용법은 엄청나게 간단하다. node_modules 폴더 안에 있는 구조를 URL에 그대로 입력만 해주면 된다. 몇 가지 예로 확인해보자.

<!-- React -->
<script src="https://unpkg.com/react@15.3.1/dist/react.min.js"></script>
<!-- Lodash -->
<script src="https://unpkg.com/lodash@4.17.4/lodash.min.js"></script>
<!-- Bootstrap css -->
<script src="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css"></script>

node_modules 안의 경로가 생각나지 않는다 라면 폴더 경로까지만으로 웹에서 접근해보자. 예를 들어 Bootstrap4라면 https://unpkg.com/bootstrap@4.0.0-alpha.6/ 까지만 들어가면 폴더 구조가 보인다.

여담

블로그의 스크립트도 unpkg로 바꿨는데, 로딩속도가 1초 가까이 줄어든 느낌이다.

이슈

unpkg로 스크립트를 가져오는 도중에 503 timeout 에러가 발생해서 블로그가 동작하지 않았었다. 같은 방법으로 동작하지만 좀 더 reliable한 서비스인 jsdelivr를 사용하자.

· 3 min read

Bower의 시대가 끝났다. 홈페이지를 들어가보면 다음과 같은 문구가 보인다.

..psst! While Bower is maintained, we recommend yarn and webpack for new front-end projects!

Yarn을 사용해보자.

설치

2020년에는 npm 사용을 추천드립니다. 더 이상 느리지 않습니다.

NPM으로 설치할 수도 있는데 추천하는 방법은 Installer이니 다운받고 설치해주면 된다! NPM으로 설치시에는 환경변수 등록을 거쳐야한다.

설치 후 Bash에서 확인해보자.

$ yarn --version
0.24.5

사용법

npm 사용법과 아주 유사하다. 기존 NodeJS 패키지에서 yarn 명령어만을 입력하면 완벽히 호환이 되고, 새로운 프로젝트라면 yarn init 명령어를 실행하면 된다. package.json을 사용하기 때문에 그냥 명령어만 바뀌었다고 생각하면 된다. (패키지들도 npm의 것을 공유한다.)

명령어 비교

install이 add로, uninstall이 remove로, update가 upgrade로 바뀐게 사실상 끝이다. 자세한 옵션은 CLI Docs를 참조하자.

npmYarn
npm installyarn install
(N/A)yarn install --flat
(N/A)yarn install --har
(N/A)yarn install --no-lockfile
(N/A)yarn install --pure-lockfile
npm install [package](N/A)
npm install --save [package]yarn add [package]
npm install --save-dev [package]yarn add [package][--dev/-D]
(N/A)yarn add [package][--peer/-P]
npm install --save-optional [package]yarn add [package][--optional/-O]
npm install --save-exact [package]yarn add [package][--exact/-E]
(N/A)yarn add [package][--tilde/-T]
npm install --global [package]yarn global add [package]
npm update --globalyarn global upgrade
npm rebuildyarn install --force
npm uninstall [package](N/A)
npm uninstall --save [package]yarn remove [package]
npm uninstall --save-dev [package]yarn remove [package]
npm uninstall --save-optional [package]yarn remove [package]
npm cache cleanyarn cache clean
rm -rf node_modules && npm installyarn upgrade

Global 경로

  • Windows: %LOCALAPPDATA%/Yarn/config/global

환경 변수 설정

설정을 확인한 뒤 prefix 경로를 PATH에 추가해주면 된다.

$ yarn config list
{ prefix: 'C:\\Users\\{NAME}\\npm' }

결론

bower_components 안녕 이젠 node_modules만 있겠구나

· 3 min read

170323에 Angular2의 stable 버전이라고 할 수 있는 Angular4가 나왔다. Angular2하고 있었는데 나도 모르는 사이에 버전이 4가 되었나, 1에서 2가 그렇게 많이 바뀌었는데 Angular4는 얼마나 바뀐걸까?

Angular2부터는 npm으로 관리되기에 소스의 버전을 따라서 명명을 해 비롯된 것으로 큰 변경점이 없으니 안심해도 된다.

버전별로 보면 이렇다.

  • Angular1 : 기존 javascript로 코딩하던 \$scope를 사용했던 버전
  • Angular1.x : Component가 도입된 버전
  • Angular2 : 처음으로 ts가 사용되고 새로운 앵귤러가 된 버전
  • Angular3 : 아무도 모르게 사용을 했었다. package.json에서 @angular/router를 보자 3버전대일 것이다.
  • Angular4 : 성능이 개선되었고 모든 Angular 모듈이 4버전

변경점

모든 변경점은 앵귤러 블로그에서 확인할 수 있다.

  • 컴파일시 가벼워졌다.
  • 애니메이션 패키지가 angular/core에서 angular/animation으로 분리되었다.
  • ngIf에서 else 구문을 쓸 수 있다.
  • angular universial의 기능이 angular/platform-server로 통합되었다.
  • typescript 2.1, 2.2버전 호환이 되었다.
  • angular-cli가 1버전으로 업그레이드 되어 1버전의 cli로 프로젝트 생성시 angular4 버전으로 생성이 된다.

업그레이드

# angular 및 typescript
$ npm install @angular/common@latest @angular/compiler@latest @angular/compiler-cli@latest @angular/core@latest @angular/forms@latest @angular/http@latest @angular/platform-browser@latest @angular/platform-browser-dynamic@latest @angular/platform-server@latest @angular/router@latest @angular/animations@latest typescript@latest --save

# zone.js
$ npm install zone.js@0.8.5 --save

# angular-cli
$ npm install @angular/cli@1.0.0 --save-dev

충돌

  • angular animation 기능을 사용한다면 platform-browser/animation의 BrowserAnimationsModule을 추가적으로 넣어줘야할 수도 있다.
  • typescript가 업그레이드 되면서 사용하지 않는 메소드나, 오류가 발생할 수 있는 스코프에 대해 linting이 더 강력해진 느낌이었다.