R 시작하기

R 소개

R은 벨 연구소 Becker 등에 의해 개발됐던 S language를 기반으로 통계 계산, 시각화를 위한 프로그래밍 언어를 포함한 개발환경이다. S language를 이용한 Insightful사의 S+는 S 언어를 이용한 상업용 소프트웨어이고, R은 공개소프트웨어 기반의 소프트웨어 이다.

  • 예) Excel, SPSS, SAS, HLM, MPlus 등 통계 프로그램

소개

http://revolution-computing.typepad.com/.a/6a010534b1db25970b01676908ecaf970b-pi

설치

R 의 GUI 도구로 R Studio를 사용할 수 있다.

  1. http://r-project.org 의 CRAN mirror에서 R을 다운받아 설치한다.
  2. RStudio 설치

R 시작하기

R 은 console을 통해 프로그래밍을 하거나 외부 에디터에서 작성한 소스를 컴파일해서 실행 할 수 있다.

macOS에서 R 시작시 다음 같은 경고를 보이면 macOS FAQ를 참고해 설정을 해주어야 한다.

[그림. ]

prompt

R을 실행하면 명령 입력 프롬프트 ‘>’을 볼 수 있다. 프롬프트에서 한 줄에 하나 혹은 한문장의 명령이 입력되고 실행된다.

1
2
3
4
5
6
7
print(“Hello World”)
Factorial(10) # 계산 기능
Rep(x=”hello”, times=5)
Rep(times=5) : Error…
Plot(10,10)
Plot(c(5,7), c(20, 30))
Plot(runif(100), runif(100)) # runif()는 랜덤 넘버 생성 함수

에서 명령을 입력하고 엔터로 실행이 되지만 괄호((),{},[])가 닫히지 않으면 ‘+’ 프로프트에서 계속 입력할 수 있다.

help() 사용

R에서 도움말을 통해 함수, 형식, 등의 정보를 얻을 수 있다.

1
> help(“함수명”)

패키지를 로드하지 않은 함수의 도움말 보기

1
> help.search(“함수명”)

내가 얻은 패키지는 어떤 것인가?

1
> help(package=”알고싶은 패키지명”)

주요 도움말 명령 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> help()                      # 도움말 창
> help(ls) # 함수 ls()에 대한 도움말
> ?ls # 도움말 단축키 ?로 help(ls) 호출
> help(">") # R의 예약어, 연산자 등은 ""로
> help("for") # 묶는다.
> #특정 패키지에 대한 도움말 요청
> help(package="datasets")
> # 일반 검색어를 이용해 도움말 검색
> help.search("Latex")
> ??"Latex"
>
> # 사용 예제 검색
> example(mean)
mean> x <- c(0:10, 50)

mean> xm <- mean(x)

mean> c(xm, mean(x, trim = 0.10))
[1] 8.75 5.50
>

object

다음 같이 hello 변수와 값을 대입하고 hello 변수를 살펴본다.

1
2
3
4
5
6
7
8
9
10
11
12
> hello <- “안녕하세요"            #유니코드 문자열
> hello
[1] “안녕하세요"
> hello2 <- “R"
[] “R"
> Object1 <- 1 # 숫자
> Obect2 <- 2
> Object1 + Object2
[] 3

> Object1 <- TRUE # 논리형
> Object2 <- FALSE

Workspace

R에서 작업공간(workspace)에 사용자가 R을 이용하여 수행하는 자료와 분석 프로시져 등을 포함하게 된다.

  • setwd( … ): 명령으로 워크스페이스 변경
  • getwd(): 현재 워크스페이스 경로
  • list.files(PATH): 경로의 파일 목록을 반환

R의 종료를 위해서는 명령문 프롬프트에서 **q()**를 실행하던가 메뉴로부터 “종료”를 선택한다.
종료시 워크스페이스에 작업된 자료를 저장할 수 있다.

R 객체 이용하기

R의 최소 단위는 벡터

정수(1), 실수(5.8271), 문자(‘A’) 문자열(“hello”)는 스칼라이다.
벡터는 {1,2,3,4,5,6}과 같이 스칼라가 여러 개 모인 것이이다.

한 개의 스칼라 값을 가진 벡터를 선언한다.

1
> a <- 5

객체에 다른 객체 넣기

1
2
3
4
5
6
7
> object1 <- 1
> object2 <- 2
> object1
[1] 1
> object1 <- object2
> object1
[1] 2

객체에 다른 객체 넣기

1
2
3
4
5
6
> object1 <- 1
> object1 <- 2
> object1 <- object2
> object2 <- 100
> object1
[1] 2

함수 계산 결과를 객체에 넣기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> Excel1 <- read.csv(“example_student.csv”)

> Object1 <- sum(1,8,4,5,9)
Object1 : 27

> A <- c(1,3,5,6,9) # 벡터에 대해
A : 1,3,5,6,9

> A <- 1
Is.vector(a): True

A <- c(1,2,5)
Is.vector(a): True

> A <- c(“첫번째”, “두번째”, “세번째”)
A : ???

Package 관리

외부에서 제공하는 모듈을 Install, Update, Library 명령으로 관리할 수 있다. 패키지 설치는 Install 그리고 사용할 때는 Library 명령을 사용하고 패키지 갱신에 Update 명령을 사용한다.

패키지 관리

패키지 설치과 업데이트

1
2
3
4
> install.packages("패키지명")      # 패키지 설치
> library("패키지명") # 패키지 불러들이기 (사용)
> require("패키지명") #
> update.packges('패키지명') # 패키지 갱신

설치된 패키지 목록 보기

1
2
3
> Library()
> installed.packages()
> Install.packages()[, c(“Packages”, “version”, “License”)]

필수 패키지

1
2
3
4
5
6
7
8
9
10
11
Install.packages(“rgl”) # 3D 그래프 보여주는 패키지
Install.packages(“ggplot2”)
Install.packages(“ggthemes”)
Install.packages(“data.table”)
Install.packages(“devtools”)
Install.packages(“KoNLP”)
Install.packages(“dplyr”)
Install.packages(“plyr”)
Install.packages(“reshape2”)
Install.packages(“scales”)
Install.packages(“stringr”)

Github로 패키지 설치하기

개발자가 베타 버전을 github에 공개하는 경우
Knitr 패키지는 R에서 html, pdf, MS-Word 문서를 만들 수 있음고 https://github.com/yihui/knitr 에서 배포한다.

1
2
3
4
> Install.packages(“devtools”)
Library(“devtools”)

> install_github(“yihui/knitr”)

RStudio UTF8 지원


참조

mongodb - Collection

Collection

mongoDB는
mongoDB는 Collection 이 데이터베이스 테이블과 같은 개념이다. 아래 테이블은 관계형 데이터베이스 MySQL과 MongoDB의 개념을 비교해 주고 있다. [^1]

MySQL MongoDB
Table Collection
Row Document
Column Field
Joins Embedded documents, linking
자세히 보기

MongoDB - Database와 User Authentication

2018-06-21 설치 링크로 대체
{:.right-history}

MongoDB 설치후 데이터베이스 위치, 로그, 인증 등에 관련한 서버 구성과 설정을 정리한다.

MongoDB 2.6 과 MongoDB Community Edition 3.x 버전을 사용했다.

mongoDB 접근제어

mongoDB 는 설치과정 중에 인증과 관련해 설정하는 부분이 없어서 설치 후 누구나 DB에 접속 할 수 있다. 인증을 추가해 데이터베이스 관리자와 데이터베이스 사용자로 구분해서 이용하고, 각 데이터베이스의 사용자는 허가된 역할(Role)을 가지고 데이터베이스에 접근 가능하도록 구성한다.

자세히 보기

mongodb 3.4 on Armbian

2018-06-22 내용 정리, User auth 링크
{:.right-history}

이 문서는 MongoDB Community Edition 3.4 버전을 64bit OSAmd64, Arm64 지원 OS에 설치해 사용하기 위해서 Install MongoDB Community Edition, on-ubuntu를 따라서 진행했다.

여기서는 Arm을 사용하는 SBC[^2] 컴퓨터에 mongodb 3.4 버전을, Hardkernel Odroid C2를 사용해서 설치를 진행했다.

자세히 보기

Python - Build python source

2015년 쯤 작성한 것으로 Raspberry Pi, Orange Pi, Odroid SBC 보드에서 3.4를 빌드했다. 2017년 현재 배포본, Debian Jessie, Ubuntu Xeniel 등은 3.4, 3.5가 내장되어 배포되고 있다.
Python 3.6 이상 최신 소스를 빌드하는데 참고할 수 있다.

Build Python 3.4

Raspbian Wheezy에는 3.2가 설치되어 있다. Jessie 가 출시된 이후에 3.2에 대한 모듈 의존성 관리가 되지 않고 있어서 3.4 이상이 설치가 필요하다.

SSL/TLS 지원을 하기 위해 libssl, openssl 라이브러리를 설치한다.

1
2
$ sudo apt update
$ sudo apt install libssl-dev openssl

Python3.4를 다운로드하고 컴파일하고 설치한다.
Raspbian Weezy 에는 Python3.2가 있어서, 최신 3.4를 설치하려면 다운로드해서 컴파일 하면 된다.

1
2
3
4
$ wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz
$ tar xvzf Python-3.4.3.tgz
$ cd Python-3.4.3/
$ ./configure

Raspberry Pi 2에서 빌드시 꽤 많은 시간을 사용한다.

1
2
3
4
5
$ ./configure
...
real 2m16.512s
user 1m16.360s
sys 0m20.630s

컴파일하고 빌드시 한 시간 이상 필요하다.

1
2
3
4
5
6
$ make                  # 한 시간 소요
$ sudo make install
...
real 16m40.747s
user 15m51.550s
sys 0m24.030s

크로스컴파일 환경을 사용할 수 있다.

Python - Install virtualenv on macOS X

Python 개발환경을 위해서 macOS에 설치된 python2.7 그리고 brew 같은 유틸리티로 python3.x 를 설치하고, pip를 사용해서 패키지를 관리할 수 있다. 그리고 다양한 모듈과 시스템 모듈의 분리를 위해서 버전 관리 도구인 virtualenvvirtualenvwrapper 를 사용해 가상 개발 환경을 구성하는 방법을 설명한다.

자세히 보기

Python - Install virtualenv on Linux

Python 개발환경을 위해서 시스템에 설치된 python2.7, python3.x 에서 사용하는 패키지 모듈을 pip를 사용해서 패키지를 관리할 수 있다. 그리고 시스템 모듈과 별도의 버전 환경으로 버전 관리 도구인 virtualenvvirtualenvwrapper 를 사용해 파이썬 가상 개발 환경을 구성하는 방법을 설명한다.

자세히 보기

NodeJS와 Nginx 웹 서버

Nginx with nodejs

nginx를 사용해서 일반 웹 서비스와 node.js 애플리케이션을 연동하는 방법을 살펴보자.

Nginx 구성

Nginx 설치가 되었다고 가정한다.

nginx 구성 파일

/etc/nginx 밑에 가상 호스트 환경에 맞게 파일을 구성한다.

/etc/nginx/site-available/myhome.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {

listen 80 default_server;
server_name _;

index index.html index.htm index.nginx-debian.html;

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

proxy_pass http://127.0.0.1:50000/;
proxy_redirect off;

try_files $uri $uri/ =404;
}

log_not_found off;

gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_min_length 1000;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
}

http 에 대한 구성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 http {
upstream my_node_app {
server 127.0.0.1:8000;

server {
listen 80;
server_name localhost domain.com;
access_log /var/log/nginx/my_node_app.log;
location ~ /static/ {
root /home/node/my_node_app;
if (!-f $request_filename) {
return 404;
}
}
location / {
proxy_pass http://my_node_app;
proxy_redirect off;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
}
}

nginx 구성을 재시작한다

1
2
3
$ cd /etc/nginx/sites-enabled
$ sudo ln -s /etc/nginx/sites-available/test.conf test.conf
$ sudo service nginx reload

Nginx with Node.js

nodejs 를 연동하기 위한 Proxy 구성을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {

listen 80;
server_name test.example.com;

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

proxy_pass http://127.0.0.1:52222/;
proxy_redirect off;
}

log_not_found off;

gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_min_length 1000;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
}

SSL

Nginx를 이용해 SSL 제공을 해주자.

Private SSL 설정

1
2
3
4
5
6
7
$ sudo mkdir /etc/nginx/ssl
$ cd /etc/nginx/ssl
$ sudo openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
$ sudo openssl rsa -passin pass:x -in server.pass.key -out server.key
$ sudo rm server.pass.key
$ sudo openssl req -new -key server.key -out server.csr
$ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Nginx 설정

/etc/nginx/site-available/yoursite.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
server {
listen 443 default;
server_name erp.yclean.co.kr;

access_log /var/log/nginx/oddo.access.log;
error_log /var/log/nginx/oddo.error.log;

ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
keepalive_timeout 60;

ssl_ciphers HIGH:!ADH:!MD5;
ssl_protocols SSLv3 TLSv1;
ssl_prefer_server_ciphers on;

proxy_buffers 16 64k;
proxy_buffer_size 128k;

location / {
proxy_pass http://127.0.0.1:8069;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}

location ~* /web/static/ {
proxy_cache_valid 200 60m;
proxy_buffering on;
expires 864000;
proxy_pass http://127.0.0.1:8069;
}
}

server {
listen 80;
server_name erp.yclean.co.kr;

add_header Strict-Transport-Security max-age=2592000;
rewrite ^/.*$ https://$host$request_uri? permanent;
}

http 리다이렉트

http://serverfault.com/questions/250476/how-to-force-or-redirect-to-ssl-in-nginx

1
2
3
4
5
server {
listen 80;
server_name signup.mysite.com;
rewrite ^ https://$server_name$request_uri? permanent;
}

The best way as it described in the official how-to is by using the return directive:

1
2
3
4
5
server {
listen 80;
server_name signup.mysite.com;
return 301 https://$server_name$request_uri;
}

site file 활셩화

1
2
3
$ sudo ln -s /etc/nginx/sites-available/yourOdooSite.com /etc/nginx/sites-enabled/yourOdooSite.com

$ sudo /etc/init.d/nginx restart

CORS

CORS(Cross-Origin resource sharing)은 웹 페이지 도메인 밖의 다른 도메인에서 제한된 웹 페이지를 자원을 허용하도록 하는 메커니즘이다.[^2]

You need to enable CORS on the server (localhost:8080). Check out this site: http://enable-cors.org/

All you need to do is add an HTTP header to the server:

1
Access-Control-Allow-Origin: http://localhost:3000

전체적으로 열어 주려

1
Access-Control-Allow-Origin: *

다음 같이 nginx 설정을 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
et $cors '';
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)') {
set $cors 'true';
}

if ($cors = 'true') {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
# required to be able to read Authorization header in frontend
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;
}

if ($request_method = 'OPTIONS') {
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

Nginx와 Proxy 서비스

Nginx를 앞단에 두고 Proxy를 이용해 nodeJS, Djang, Angular 등의 서비스를 이용할 때, nginx나 backend 둘 중 한 곳에서 CORS를 활성화 해주면 된다.

Nginx에서 CORS

Nginx에서 CORS를 허용하려면 아래 설정을 사용할 수 있다. [^1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}
}

이와 비슷한 방법으로

https://gist.github.com/m4ttbrock/7337183

CORS node.js

https://enable-cors.org/server_expressjs.html

if your app is created with simple node.js set it in your response headers like

1
2
3
4
5
6
7
8
9
10
var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

if your app is created with express framework
use a CORS middleware like

1
2
3
4
5
6
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}

cors module

cors 모듈을 이용할 수 있다.

https://github.com/expressjs/cors

Enable All CORS requets
1
2
3
var cors = require("cors");

app.use(cors());
Enable CORS for a Single Route
1
2
3
app.get("/products/:id", cors(), function (req, res, next) {
res.json({ msg: "This is CORS-enabled for a Single Route" });
});
Configuring CORS
1
2
3
4
5
6
7
8
var corsOptions = {
origin: "http://example.com",
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};

app.get("/products/:id", cors(corsOptions), function (req, res, next) {
res.json({ msg: "This is CORS-enabled for only example.com." });
});

참조

[^1]: CORS on Nginx
[^2]: Cross-origin resource sharing

NodeJS - Patterns

원문 https://darrenderidder.github.io/talks/ModulePatterns/ 요약

Node.js Module Patterns

이것은 같단한 모듈을 hello-module.js 소스에 선언한 것이다.

1
2
// hello-module.js
console.log("Hello World");

선언된 소스는 require() 로 들여올 수 있다:

1
require("hello-module.js");

Define a global

모듈 foo.js 를 글로벌

1
2
3
4
// foo.js
foo = function () {
console.log("Im foo");
};

모듈 foo.js를 들여와 전역에 선언된 함수 foo()를 사용한다.

1
2
require("foo.js");
foo();

그러나 글로벌 영역을 오염 시키지 않는다.

export an anonymous function

module 객체에 export 한다.

1
2
3
4
// bar.js
module.exports = function () {
console.log("Im bar");
};

모듈 bar.js를 들여와 전역에 선언된 함수 foo()를 사용한다.

1
2
var bar = require("./bar.js");
bar();

export a named function

module 객체의 이름 속성으로 export 한다.

1
2
3
4
// bar.js
module.fiz = function () {
console.log("fiz");
};

모듈 bar.js를 들여와 전역에 선언된 함수 foo()를 사용한다.

1
2
var fiz = require("./fiz.js").fiz;
fiz();

export an anonymous object

1
2
3
4
5
6
7
// buz.js
var Buz = function() {};

Buz.prototype.log = function() {
console.log('buz');
}
export.modules = new Buz();

모듈 buz.js를 들여와 객체의 메서드를 호출한다.

1
2
var buz = require("./buz");
buz.log();

export a named object

1
2
3
4
5
6
7
// buz.js
var Baz = function() {};

Baz.prototype.log = function() {
console.log('baz');
}
export.Baz = new Baz();

모듈 baz.js를 들여와 속성 메서드를 호출한다.

1
2
var baz = require("./baz.js").Baz;
baz.log();

export an anonymous prototype

module.exports 에 객체를 노출한다.

1
2
3
4
5
6
7
// doo.js
var Doo = function() {};

Doo.prototype.log = function() {
console.log('doo!');
}
export.exports = new Doo();

모듈 doo.js를 들여와 객체의 메서드를 호출한다.

1
2
3
var Doo = require("./doo.js");
var doo = new Doo();
doo.log();

export a named prototype

module 에 이름 속성을 노출한다.

1
2
3
4
5
6
7
// qux.js
var Qux = function() {};

Qux.prototype.log = function() {
console.log('qux!');
}
export.Qux = Qux;

모듈 qux.js를 들여와 객체의 메서드를 호출한다.

1
2
3
var Qux = require("./qux.js").Qux;
var qux = new Qux();
qux.log();

module.exports

modules.exports는 exports로 가명을 가지고 있다. 이름 있는 속성을 사용할 때 아래 같이 선언한다.

1
2
3
4
> module.exports.fiz = 'Fiz';
> exports.buz = 'buz';
> module.exports === exports;
true

exports 에 직접 대입하면 exports alias를 덮어 쓰게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> module.exports.qux = "qux";
> exports
{ qux: "qux" }
> exports === module.exports
true
> exports = "wobble wibble wubble!";
> exports === module.exports
false
> exports
"wobble wibble wubble!"
> module.exports
{ qux: "qux" }
// module.exports is canonical

pros, cons

  • Named exports: 한 모듈에 여러 개체 및 속성을 노출할 수 있다.
  • Anonymouse exports: 간단한 클라이언트 인터페이스로 적합