Nodejs 기본. NodeJS

안녕하세요 여러분! 이 기사에서 우리는 플랫폼을 계속해서 이해할 것입니다. NodeJS그리고 얘기해 전역 개체.

당신은 이미 이 개념에 익숙해야 합니다. 우리가 글을 쓸 때 자바스크립트브라우저에서 코드를 작성한 다음 전역 개체를 사용합니다. 창문. 안에 NodeJS전역 개체도 있으며 간단히 호출됩니다. 글로벌.

게다가 창문, 글로벌코드의 어느 곳에서나 일부 내장 속성과 메서드를 사용할 수 있습니다. 예를 살펴보겠습니다.

아마도 브라우저 전역 개체에도 존재하는 가장 유명한 방법 중 하나일 것입니다. 창문- 이것 콘솔.로그(). 다음과 같이 작성할 수 있습니다.

그리고 코드는 대괄호 안의 텍스트를 콘솔에 표시합니다.

지정된 시간 후에 일부 작업을 수행할 수 있는 또 다른 잘 알려진 방법은 다음과 같습니다.

// 7초(7000밀리초) 안에 코드 실행
setTimeout(함수() (
console.log("안녕하세요, 세상!");
}, 7000);

있다면 추측하는 것은 어렵지 않다고 생각합니다 세트타임아웃(), 그러면 다음이 있어야 합니다. 세트간격().

// 매초마다 "Hello, world"를 표시합니다.
setInterval(함수() (
console.log("안녕하세요, 세상!");
}, 1000);

NodeJS시스템에서 유용한 정보를 받을 수 있습니다. 예를 들어 전역 개체 속성을 사용하여 현재 있는 폴더의 전체 경로를 찾을 수 있습니다. __dirname.

Console.log(__dirname);

코드가 실행되는 파일의 이름도 얻으려면 다음과 같이 작성하면 됩니다.

JavaScript에는 전역 개체(Global Object)라는 특수 개체가 있으며, 이 개체와 해당 속성은 프로그램 어디에서나 전역 변수에 액세스할 수 있습니다.

JavaScript 브라우저는 일반적으로 전역 창 개체이고, Node.js 전역 개체는 전역 개체이며, 모든 전역 변수(전역 자체 제외)는 전역 개체가 소유합니다.

Node.js에서는 애플리케이션에 전역 속성을 포함하지 않고도 전역 속성에 직접 액세스할 수 있습니다.

전역 개체 및 전역 변수

가장 기본적인 전역 역할은 전역 호스트 변수입니다. ECMAScript 정의에 따르면 다음 조건은 전역 변수입니다.

  • 외부 변수가 정의됩니다.
  • 전역 객체 속성;
  • 변수가 암시적으로 정의됩니다(정의되지 않은 변수에 직접 할당).

전역 변수를 정의하면 해당 변수도 전역 개체의 속성이 되며 그 반대의 경우도 마찬가지입니다. Node.js에서는 모든 사용자 코드가 현재 모듈의 일부이고 모듈 자체는 외부 컨텍스트가 아니기 때문에 외부 컨텍스트에서 변수를 정의할 수 없습니다.

메모:전역 변수가 네임스페이스를 오염시켜 통신 코드의 위험을 증가시키므로 전역 변수 도입을 피하기 위해 항상 var를 사용하여 변수를 정의하십시오.

__파일 이름

__filename은 현재 실행 중인 스크립트의 파일 이름을 지정합니다.출력 파일이 있을 위치의 절대 경로이지만 명령줄 옵션과 파일 이름 지정이 반드시 동일할 필요는 없습니다. 모듈에 있는 경우 반환된 값은 모듈 파일의 경로입니다.

// 전체 출력량 __filename 의 내용 console.log(__filename);

$ 노드 main.js /web/com/w3big/nodejs/main.js

__dirname

__dirname은 현재 위치한 스크립트 디렉터리를 나타냅니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

// 출력 전체 내용 __dirname 의 내용 console.log(__dirname);

main.js 실행 파일의 코드는 다음과 같습니다.

$ 노드 main.js /web/com/w3big/nodejs

setTimeout(CB, ms)

setTimeout(C - 바이, ms): SetTimeout() 함수는 한 번만 지정됩니다.

타이머를 나타내는 핸들 값을 반환합니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

함수 printHello())( console.log("Hello, World!"); ) // setTimeout(printHello, 2000);

main.js 실행 파일의 코드는 다음과 같습니다.

$ node main.js 안녕하세요, 월드!

클리어타임아웃(t)

ClearTimeout(t)는 타이머를 생성하기 위해 setTimeout()을 전달하기 전에 전역 함수를 중지하는 데 사용됩니다.매개변수 T 함수 setTimeout()을 사용하여 계산기를 만듭니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

함수 printHello())( console.log("Hello, World!"); ) // var t = setTimeout(printHello, 2000); // 清除定时器 클리어타임아웃(t);

main.js 실행 파일의 코드는 다음과 같습니다.

$nodemain.js

setInterval(CB, ms)

setInterval(C - 바이, ms)전역 함수는 지정된 밀리초(ms) 숫자(CB) 후에 지정된 함수를 실행합니다.

타이머를 나타내는 핸들 값을 반환합니다. 기능을 사용할 수 있습니다. ClearInterval(T)은 타이머를 지웁니다.

setInterval() 메서드는 ClearInterval()이 호출되거나 창이 닫힐 때까지 계속해서 함수를 호출합니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

함수 printHello())( console.log("Hello, World!"); ) // setInterval(printHello, 2000);

main.js 실행 파일의 코드는 다음과 같습니다.

$ node main.js 안녕하세요, 월드! 안녕하세요, 월드! 안녕하세요, 월드! 안녕하세요, 월드! 안녕하세요, 월드! ......

위 프로그램은 2초에 한 번씩 "Hello, World!"를 출력하고 버튼을 누를 때까지 계속 실행됩니다. CTRL + C.

콘솔

콘솔 표준 출력을 제공하기 위한 콘솔은 Internet Explorer의 JScript 엔진이 제공하는 디버깅 기능이며 나중에 사실상의 표준 브라우저가 되었습니다.

Node.js는 이 표준을 따르며 표준 출력 스트림(STDOUT) 또는 표준 오류 스트림(STDERR) 출력 문자에 사용되는 콘솔 개체의 일관된 동작과 습관을 보장합니다.

콘솔 방식

아래는 콘솔 객체입니다:

아니요.방법 및 설명
1 console.log([데이터] [, ... ])
출력 스트림의 표준 인쇄 가능 문자의 경우 개행 문자로 끝납니다. 이 메서드는 여러 매개변수를 사용합니다. 매개변수가 하나만 있는 경우 출력은 이 매개변수의 문자열입니다. 인수가 여러 개인 경우 C 언어 명령(E())의 출력 형식 등을 지정합니다.
2 console.info([데이터] [, ... ])
명령의 P 역할은 정보 메시지를 반환하며, console.log 명령은 큰 차이를 만들지 않습니다. 크롬 외에 텍스트만 출력되고 나머지는 파란색 느낌표가 표시됩니다.
3 console.error([데이터] [, ... ])
오류 메시지를 출력합니다. 포크 오류가 발생하면 콘솔이 빨간색으로 표시됩니다.
4 console.warn([데이터] [, ... ])
경고 메시지가 표시됩니다. 콘솔에 노란색 느낌표가 표시됩니다.
5 console.dir(OBJ[, 옵션])
검사(inspection)에 사용되는 객체이며 읽기 쉬운 표시 및 인쇄 형식입니다.
6 console.time (바로가기)
시간 출력, 시작 시간.
7 console.timeEnd(바로가기)
종료 시간은 시간의 끝을 나타냅니다.
8 console.trace(메시지 [, ...])
코드는 현재 스택에서 호출 경로를 구현합니다. 이 테스트 함수를 실행하는 것은 유용합니다. 라인에서 console.trace에 의해 조인된 함수를 테스트하고 싶을 뿐입니다.
9 console.assert(값[, 메시지][, ...])
변수 또는 표현식이 true인지 확인하려면 두 개의 매개변수가 필요합니다. 첫 번째 매개변수는 표현식이고 두 번째 인수는 문자열입니다. 첫 번째 인수가 false인 경우에만 출력은 두 번째 인수가 되며 결과가 없습니다.
console.log(): 표준 출력으로 인쇄하고 줄 바꿈으로 끝납니다.

console.log는 여러 매개변수를 허용합니다. 매개변수가 하나만 있는 경우 해당 매개변수의 출력 문자열입니다. 인수가 여러 개인 경우 C E()에 명령 출력 형식 등을 배치합니다.

첫 번째 매개변수는 문자열이고 매개변수는 없으며 개행 문자만 인쇄합니다.

Console.log("안녕하세요."); console.log("byvoid%diovyb"); console.log("byvoid%diovyb", 1991);

안녕하세요. byvoid%diovyb byvoid1991iovyb

  • console.error(): console.log()를 사용하면 동일한 작업을 수행하지만 표준 오류로 출력됩니다.
  • console.trace(): 현재 호출 스택의 표준 출력으로 오류를 스트리밍합니다.
console.trace();

운영 결과는 다음과 같습니다.

추적: 개체에서. (/home/byvoid/consoletrace.js:1:71) Module._compile (module.js:441:26) at Object..js (module.js:459:10) at Module.load (module.js: 348:31) Function._load(module.js:308:12)에서 Array.0(module.js:479:10)에서 EventEmitter._tickCallback(node.js:192:40)에서

다음과 같은 코드로 main.js 파일을 만듭니다.

Console.info("程序开始执行:"); var 카운터 = 10; console.log("내용: %d", counter); console.time("실행 시간"); // // 执行一些代码 // console.timeEnd("获取数据"); console.info("程序执行完毕")

main.js 실행 파일의 코드는 다음과 같습니다.

$ node main.js 程序开始执行: 计数: 10 获取数据: 0ms 程序执行完毕

프로세스

프로세스는 전역 변수이고 속성은 전역 개체입니다.

Node.js 객체의 현재 프로세스 상태를 설명하는 데 사용되며 운영 체제에 간단한 인터페이스를 제공합니다. 일반적으로 자신만의 명령줄 프로그램을 작성하고 이를 처리하게 됩니다. 다음은 회원들이 이의를 제기하는 과정에서 가장 일반적으로 사용되는 방법 중 일부를 소개합니다.

아니요.이벤트 및 설명
1 출구
프로세스를 종료할 준비가 되면 발생합니다.
2 전에나가기
이 이벤트는 노드에 빈 이벤트 루프가 있고 다른 작업이 수행되지 않을 때 시작됩니다. 일반적으로 종료 노드를 구성하는 프로세스는 없지만 "beforeExit" 리스너를 비동기식으로 호출하여 노드가 계속되도록 할 수 있습니다.
3 잡히지 않은 예외
예외가 이벤트 루프로 다시 끓어오르면 이 이벤트를 발생시킵니다. 예외에 모니터를 추가하면 기본 동작(스택 인쇄 및 종료)이 발생하지 않습니다.
4 신호는 다음과 같은 경우에 트리거됩니다.
이벤트프로세스가 신호를 받았을 때.
SIGINT, SIGUSR1 등과 같은 표준 POSIX 신호 이름 목록을 검토합니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

Process.on("exit", function(code) ( // setTimeout(function() ( console.log("该代码不会执行"); 0); console.log("退take码为:", code) ;)); console.log("程序执行结束");

main.js 실행 파일의 코드는 다음과 같습니다.

$ 노드 main.js 유형: 0

출력 상태 코드

종료 상태 코드는 다음과 같습니다.

상태 코드제목 및 설명
1 잡히지 않은 치명적인 예외
포착되지 않은 예외가 있으며 처리되지 않았거나 uncaughtException 핸들러의 도메인입니다.
2 미사용
보유
3 JavaScript 내부 오류 분석
Node 프로세스가 시작되면 JavaScript 오류 구문 분석 소스 코드가 호출됩니다. 아주 드물지만 Node.js일 때만 가능합니다.
4 내부 JavaScript 오류 점수
소스 노드를 실행하는 JavaScript 프로세스는 함수를 평가할 때 실패를 반환합니다. 아주 드물지만 Node.js일 때만 가능합니다.
5 치명적 오류
V8에는 치명적인 결과를 초래하는 수정 불가능한 오류가 있습니다. 일반적으로 Stderr를 인쇄합니다. 내용: 치명적인 오류
6 비기능 내부 예외 처리기
포착되지 않은 예외, 내부의 예외 처리기가 어떻게든 함수에 설정되어 있고 호출할 수도 없습니다.
7 내부 런타임 처리기 예외 실패
포착되지 않은 예외 및 자체적으로 처리하는 예외 처리기가 예외를 발생시킵니다. 예를 들어, process.on("uncaughtException") 또는 domain.on("error")이 예외를 발생시키는 경우입니다.
8 미사용
보유
9 잘못된 인수
알 수 없는 매개변수이거나 값에 대한 매개변수일 수 있습니다.
10 내부 JavaScript 런타임 실패
JavaScript 소스 코드는 Node 프로세스에서 오류가 발생할 때 생성되며, 매우 드물게 Node가 개발될 때만 생성됩니다.
12 잘못된 디버그 인수
--debug 옵션 설정 및/또는 --debug-BRK가 잘못된 포트를 선택했습니다.
> 128 신호 출력
노드가 SIGKILL 또는 SIGHUP과 같은 치명적인 신호를 수신하는 경우 반환 코드는 128에 신호 코드를 더한 값입니다. 이는 표준 Unix 방식으로, 출력 신호의 하이 코드입니다.

프로세스 속성

이 프로세스는 시스템을 더 잘 제어할 수 있는 많은 유용한 속성과 상호 작용의 용이성을 제공합니다.

수량속성 및 설명
1 표준 출력
표준 출력 스트림.
2 STDERR
표준 오류 스트림.
3 STDIN
표준 입력 스트림.
4 ARRGV
ARGV 속성은 작성 시 명령줄 스크립트를 실행하기 위한 다양한 옵션의 배열을 반환합니다. 첫 번째 멤버는 항상 노드이고 두 번째 멤버는 스크립트 파일 이름이며 나머지 멤버는 스크립트 파일 매개변수입니다.
5 execPath
현재 스크립트 실행 바이너리 노드의 절대 경로를 반환합니다.
6 execArgv
스크립트 파일의 노드 실행 가능 명령줄 매개변수 사이에서 실행되는 명령줄 스크립트 아래에 있는 배열 구성원을 반환합니다.
7 환경
현재 쉘 환경 변수의 멤버인 객체를 반환합니다.
8 종료 코드
종료 코드를 지정하지 않고 프로세스에 process.exit() 종료가 표시되는 경우 프로세스의 종료 코드입니다.
9 버전
v0.10.18과 같은 노드 버전.
10 버전
노드 및 종속성의 버전을 포함하는 속성입니다.
11 구성
현재 노드를 포함하는 객체는 실행 가능한 javascript 옵션 구성 파일을 컴파일하는 데 사용됩니다. 이는 "config.gypi" 파일에서 생성된 것과 동일한 run./configure 스크립트입니다.
12 PID - 조절기
현재 프로세스 번호.
13 이름
프로세스 이름, 기본 "노드" 값을 사용자 정의할 수 있습니다.
14 아치
현재 CPU 아키텍처: "arm", "ia32" 또는 "64".
15 플랫폼
플랫폼이 "Darwin", "FreeBSD", "Linux", "SunOS" 또는 "win32"인 프로그램을 실행합니다.
16 메인모듈
require.main 대체 방법. 여러 가지 점에서 런타임 시 기본 모듈이 변경되면 require.main이 계속 이전 모듈로 돌아갈 수 있습니다. 둘 다 동일한 모듈에 속하는 것으로 간주됩니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

// 출력하기 process.stdout.write("Hello World!" + "\n"); // 일반적으로 process.argv.forEach(function(val, index, array) ( console.log(index + ": " + val); )); // 获取执行路局 console.log(process.execPath); // 平台信息 console.log(process.platform);

main.js 실행 파일의 코드는 다음과 같습니다.

$ node main.js Hello World! 0: 노드 1: /web/www/node/main.js /usr/local/node/0.10.36/bin/node darwin

분석법 참조 가이드

이 프로세스는 대화형 시스템을 보다 효율적으로 제어할 수 있는 많은 유용한 방법을 제공합니다.

아니요.방법 및 설명
1 중단()
그러면 인터럽트 노드 트리거 이벤트가 발생합니다. 이로 인해 노드가 종료되고 덤프 파일이 생성됩니다.
2 ChDir(디렉토리)
작업을 종료할 수 없는 경우 프로세스의 현재 작업 디렉터리를 변경합니다.
3 귀 ()
현재 프로세스의 작업 디렉터리를 반환합니다.
4 종료([코드])
지정된 코드로 프로세스를 종료합니다. 이 매개변수를 생략하면 코드 0이 사용됩니다.
5 겟기드()
프로세스 그룹 식별을 얻습니다(getgid(2) 참조). 그룹이 이름이 아닌 디지털 ID를 구매한 경우.
6 setgid(ID)
그룹 식별 프로세스 설정(setgid(2) 참조) ID는 숫자 또는 그룹 이름을 사용할 수 있습니다. 그룹 이름을 지정하면 디지털 ID를 기다리는 동안 차단이 허용됩니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
7 getuid()
사용자의 식별 프로세스를 가져옵니다(getuid(2) 참조). 이는 사용자 이름이 아닌 숫자로 된 사용자 ID입니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
8 UIP(ID)
프로세스 설정 사용자 ID(UIP(2) 참조). 디지털 식별자 또는 이름 문자열을 검색합니다. 그룹 이름을 지정하면 디지털 ID를 기다리는 동안 차단이 허용됩니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
9 그룹 가져오기()
그룹 ID 배열을 반환하는 프로세스입니다. POSIX 시스템은 이를 보장하지 않지만 Node.js는 존재를 보장합니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
10 세트 그룹
프로세스 그룹 ID를 설정합니다. 작동할 수 있으며 필요한 것은 수퍼유저 권한이 있거나 CAP_SETGID 기능이 있는 것뿐입니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
11 initgroups(사용자, extra_group)
독서/등 /group을 실행하고 그룹 액세스 목록을 초기화하면 그룹의 모든 구성원을 찾습니다. 작동할 수 있으며 필요한 것은 수퍼유저 권한이 있거나 CAP_SETGID 기능이 있는 것뿐입니다.
참고: 이 기능은 POSIX 플랫폼에서만 사용할 수 있습니다(예: Windows 및 Android가 아닌 경우).
12 죽이기(IDP [신호])
프로세스에 신호를 보냅니다. ID는 프로세스 식별자이고, 신호는 전송되는 신호를 나타내는 문자열입니다. 신호 이름은 "SIGINT" 또는 ""SIGHUP과 같은 문자열입니다. 이 매개변수를 생략하면 신호는 "SIGTERM"이 됩니다.
13 메모리 사용량()
노드의 메모리 상태 바이트에 사용되는 프로세스를 설명하는 객체를 반환합니다.
14 nextTick(콜백)
현재 함수 콜백 이벤트 루프가 끝난 후.
15 U마스크([마스크])
프로세스 마스크 파일을 설정하거나 읽습니다. 하위 프로세스는 상위 프로세스로부터 이 마스크를 상속받습니다. 마스크 인수가 true이면 이전 마스크를 반환합니다. 그렇지 않으면 현재 마스크를 반환합니다.
16 지출()
노드가 이미 시작된 시간(초)을 반환합니다.
17 시간()
현재 프로세스의 시간 분해능으로, [초] 배열 나노초로 지정됩니다. 이는 과거 사건과 관련이 있습니다. 이 값은 날짜와 관련이 없으므로 시계 드리프트에 영향을 주지 않습니다. 주요 목적은 정확한 기간 동안 프로그램의 성능을 측정하는 것입니다.
결과가 현재 process.hrtime()에 전달되기 전에 참조 및 시간 간격 측정을 위해 둘 사이의 시간 차이를 반환합니다.

다음과 같은 코드로 main.js 파일을 만듭니다.

// 출고전目录 console.log("当前目录: " + process.cwd()); // 출력전版本 console.log("当前版本: " + process.version); // 출력 정보 console.log(process.memoryUsage());

NODE.JS– js를 실행하기 위한 소프트웨어 도구입니다.

Nodejs = V8 + I/O + 라이브러리

V8: 빠르고 현대적이며 경제적입니다.

장점

  • 자바스크립트
  • 클라이언트와 서버의 공통 코드
  • 기본 웹 작업
  • 동시에 많은 연결과 작업
  • 작동하는 프로토타입을 쉽게 만들 수 있음
  • 편리한 npm 패키지 관리자
  • 지역 사회

설치

설치할 때 nodejs는 PATH 변수(+ npm), [관리 - 환경 변수]에 자신을 씁니다. 명령줄에서 확인할 수 있습니다:
경로 설정

일반적으로 파일은 nodejs에서 시작됩니다. 간단한 스크립트를 작성하고 명령줄을 통해 실행해 보겠습니다.


스크립트가 실행되고 결과가 명령줄에 표시됩니다.

Nodejs 문서

nodejs 모듈

내장된 nodejs 모듈이 어떻게 작동하는지 이해하려면 nodejs 웹사이트(소스 코드)에서 소스 코드 아카이브를 다운로드해야 합니다. 그리고 lib 디렉터리로 이동합니다. (dir 명령 - 명령줄을 통해 파일 목록을 가져옵니다. 모든 하위 폴더의 파일을 나열해야 하는 경우 "dir" 대신 "dir /s"를 사용합니다.) 패키지에서 nodejs를 설치한 경우 lib 폴더에서 파일을 찾을 수 없습니다.

Nodejs에는 다양한 수준의 모듈이 있습니다. 안정. (예를 들어 0 – 사용하면 안 됩니다. 1, 2 – 사용할 수 있지만 모듈 API가 변경될 수 있습니다.)

함수가 늘어나고(프로젝트가 개발 중) 시간이 지남에 따라 USER 생성자 함수를 별도의 파일로 옮겨야 합니다. 여기가 모듈이 작동하는 곳입니다.

모듈은 nodejs가 프로젝트를 구성하기 위해 제공하는 일종의 방법입니다.

프로젝트가 커지는 경향이 있어 프로젝트를 여러 파일로 분할하려는 욕구가 생깁니다. 여기서 모듈이 작동합니다.

필요하다

HTML 페이지의 경우 스크립트 태그는 스크립트를 포함하는 데 사용됩니다. Nodejs에는 특별한 require 명령이 있습니다.

Var user = require("./user");

이 예에서는 동일한 디렉터리에 있는 파일(user.js)에 액세스합니다(확장자(.js)는 선택 사항임).

//require("./user"); // .js는 지정할 필요가 없습니다. // 이 경우 파일은 실행되지만 USER 변수는 없습니다. // 이것이 nodejs의 스크립트 태그와 주요 차이점입니다. // node.js에서는 함수와 변수가 각 모듈은 // 이 파일(모듈 자체)에 대해 전역적이며 // 연결될 때 자동으로 사용할 수 없게 됩니다. (require("./user")) // 그런데 어떻게 액세스할 수 있나요? // 각 모듈에는 특수 변수가 있습니다. 내보내기 - 이것은 객체이고 // 여기에 넣은 내용은 결과로 반환됩니다. require var user = require("./user.js"); // 결과: 사용자 = ( 사용자: 함수 )

nodejs 모듈식 시스템과 브라우저 스크립트의 첫 번째 차이점은 브라우저에 두 개의 스크립트 태그가 있는 경우 그 중 하나의 전역 수준에서 정의된 함수를 다른 쪽에서는 사용할 수 있지만 nodejs에서는 사용할 수 없다는 것입니다. nodejs에서 함수와 변수는 주어진 파일에 대해 전역적입니다(필요할 때는 사용할 수 없습니다). 따라서 nodejs를 사용하면 진정으로 독립적인 모듈을 작성할 수 있습니다. 그러나 모듈을 사용하려면 다음을 사용합니다. 수출 시스템. 각 모듈에는 특별한 내보내기 변수가 있습니다.

모듈 디렉터리 DIR/인덱스

폴더를 직접 연결합니다. var user = require("./user"); , 해당 index.js 가 포함되어 있습니다.

예를 들어

Function User(name)( this.name = name; ) User.prototype.hello = function(who)( console.log(phrases.Hello + ", " + who.name); ); 수출.사용자 = 사용자;

./server.js 파일에서 User 생성자를 연결하고 사용합니다.

//server.js var user = require("./user"); var vasya = new user.User("Vasya");

"./" - 현재 폴더 기준

내보내기는 객체이고 거기에 놓인 것은 require(exports.jpg)의 결과로 반환됩니다. 이런 방식으로 모듈은 개인 변수/함수를 선언하고 필요한 것만 내보낼 수 있습니다.


전역변수 등의 경우 글로벌 객체가 있습니다

글로벌.사용자 = 사용자;

결론

  • 연결이 필요합니다
  • 변수: var(모듈의 경우 전용), 내보내기, 전역(거의 사용되지 않음)
  • 모듈 유형: js, node(.node 확장자 포함), json(.json 확장자 포함). Json 모듈은 파일에 간단한 정보를 저장해야 할 때 사용됩니다.
  • 모듈 디렉터리 DIR/인덱스

모듈 객체

  • 모듈 객체
  • 모듈 기능 module.exports = 기능
  • 캐싱 모듈(모듈을 다시 읽지 않음)
  • 모듈 배열: 검색 순서
  • 매개변수 전달: 모듈 팩토리

모듈 객체(모듈의 기본 객체)는 각 모듈(파일, console.log(module;);을 출력할 수 있음)에 존재하는 변수입니다. . 내용: id 속성 – 일반적으로 파일 경로,
parent – ​​상위 모듈에 대한 링크(module.parent – ​​이를 요구하는 상위 모듈에 대한 링크),
어린이(module.children - require를 통해 연결된 모듈),
부동산 등을 수출합니다.

모듈인가, 애플리케이션인가? 모듈.부모

모듈을 직접 시작할 수 있지만 그렇지 않은 경우 해당 기능이 다른 모듈에 연결되어 있으면 이 기능을 내보내도록 합니다. 이 두 가지 경우는 다음을 확인하여 구분할 수 있습니다.

If(module.parent) (exports.run = run; ) else ( run(); )


ps: stackoverflow.com에서 말하는 대로 부모는 해석을 위해 스크립트를 호출한 모듈입니다.

// $ 노드 foo.js console.log(module.parent); // null // require("./foo") console.log(module.parent); // ( ... )

module.exports의 올바른 사용

모듈의 맥락에서:

module.exports = 내보내기 = this (이러한 구성은 동일합니다)

객체가 아닌 직접 함수를 전달하려면 다음 구문을 사용하십시오.

Module.exports = 사용자;


모듈 캐싱

Nodejs가 모듈을 로드할 때 해당 모듈 개체를 완전히 생성하고(parent , 내보내기 및 기타 유사한 속성을 고려하여) 이를 자체적으로 기억합니다(module.id(파일의 전체 경로)는 내부 캐시의 식별자 역할을 합니다) ) 그리고 다음에 모듈(파일)에 다시 액세스(연결)할 때 nodejs는 캐시에서 동일한 객체를 가져옵니다. 예를 들어, 파일에서 모듈을 한 번 초기화하는 것으로 충분하며 나중에는 간단히 사용할 수 있습니다.

우리의 경우 var db = require("../db");
그리고 var db = require("./db"); 동일한 개체가 사용됩니다. 따라서 원칙은 다음과 같습니다. 모듈을 처음 사용할 때 초기화되고 앞으로는 연결해서 사용하기만 하면 됩니다(즉, 우리의 경우에는 db.connect()를 두 번 사용할 필요가 없습니다. 즉, 다른 파일에 있습니다).


모듈 배열: nodejs에서 모듈이 발견되는 순서

특정 경로를 지정하지 않고 DB를 항상 연결하도록 만드는 방법:

Var db = require("../db"); //또는 var db = require("./db");

그리고 이렇게:

Var db = require("db");

db가 연결된 파일에 관계없이.

이렇게 하려면 nodejs의 모듈 검색 순서(require가 호출될 때 발생하는 일)를 이해해야 합니다. nodejs에는 require("fs");와 같은 많은 내장 모듈이 있습니다. , 문제없이 연결됩니다. 예를 들어 require에 특정 경로를 지정하는 경우 require("../db"); , 검색은 지정된 경로를 기반으로 하며 파일을 찾거나 nodejs가 이 파일을 디렉터리로 가져오려고 시도합니다(그리고 카테고리 내에서 index.js를 찾습니다).

require("db")를 지정하는 경우; 모듈이 내장되어 있지 않으면 node_modules 디렉토리는 현재 위치를 기준으로 검색됩니다(찾으면 모듈을 가져오려고 시도합니다). node_modules 디렉터리가 없으면 위에서 node_modules 디렉터리가 검색됩니다.

모듈의 특정 경로를 지정하는 것 외에도 nodejs는 다음과 같은 모듈을 검색할 수 있습니다.

npm 소개 - Node.JS용 패키지 관리자

  1. 모듈에 대한 정보(이름, 버전 등)가 포함된 패키지 설명 파일(package.json)을 만듭니다. 수동으로 또는 명령을 통해
    npm 초기화
    (필요한 정보를 요청하겠습니다)
  2. 모듈을 게시하려면 다음을 수행해야 합니다.
    1. npm adduser 명령을 사용하여 사용자를 추가합니다(사용자 이름과 비밀번호를 입력해야 함). 이제 npm을 사용한 모든 작업은 이 사용자를 대신하여 수행됩니다. 사용자는 https://www.npmjs.com/~name_user에 로그인하여 모듈을 모니터링할 수 있습니다.
    2. 게시: npm 게시
  3. 그러면 누군가가 데이터베이스에 추가된 모듈을 사용할 수 있고 사용자 자신이 변경할 수 있습니다.
  4. npm help 명령을 사용하여 모든 npm 명령 가져오기
  5. 데이터베이스에서 모듈 검색: npm s 키워드 또는 npm 검색 키워드(예: npm s super module)
  6. 모듈 설치: npm install name_module 또는 npm i name_module
  7. 모듈을 설치할 때 nodejs는 먼저 현재 디렉터리에서 node_modules 폴더를 찾거나(그 다음 더 높은 등), (node_modules가 없는 경우) package.json을 찾습니다(또한 위로 올라갑니다. package.json은 일반적으로 루트를 나타냅니다. 프로젝트) 그리고 그에 따라 package.json을 찾으면 해당 디렉터리에 node_modules 폴더를 생성합니다. 두 옵션이 모두 실패하면 nodejs는 현재 디렉터리에 node_modules 폴더를 생성합니다. 특정 디렉터리에 모듈을 배치하려면 해당 디렉터리에 node_modules 폴더를 만들어야 합니다.
  8. npm up 업데이트 모듈(node_modules 폴더에 있는 업데이트 모듈을 확인합니다)
  9. npm 제거 module_name (모듈 제거)

npm의 출력:

npm 초기화
nmp 추가 사용자
npm 게시
npm 검색 키워드
npm 설치 모듈
npm 업데이트 모듈
npm 제거 모듈
npm 도움말 명령

NPM 패키지 구조

필요한 버전 설치(예: npm i) [이메일 보호됨]

모듈이 github 등의 git 버전 관리 시스템을 사용하여 개발된 경우 최신 버전의 모듈을 얻을 수 있습니다. Git 읽기 전용(url): https://github.com/strongloop/express.git 및 콘솔에서 다음을 수행하는 것으로 충분합니다.

npm i https://github.com/strongloop/express.git

package.json의 종속성

종속성은 이 모듈이 의존하는 모듈을 가리킵니다.

개발자 종속성

devDependency에 등록된 모듈은 모듈을 종속성으로 가져오는 경우 설치되지 않습니다. 이는 개발용으로만 설치되며, 예를 들어 node_modules 폴더의 모듈로 이동하여 npm i를 입력하는 경우(또는 npm config 플래그를 설정하여) 설치할 수 있습니다.

기본 필드는 패키지의 진입점을 지정합니다.

글로벌 모듈

-g 플래그를 설정하면 모든 모듈을 전역적으로 설치할 수 있습니다: npm -g module

전역은 시스템 디렉터리를 의미합니다.

Windows용 전역 모듈 디렉터리:

C:\users\사용자_이름\AppData\Roaming\npm

전역 모듈은 표준 시스템 디렉터리에 배치됩니다. package.json에 있는 바이너리는 시스템 경로(전역 모듈의 주요 사용)에 설치됩니다. 즉, 나중에 콘솔을 통해 호출할 수 있습니다.

I. Kantor 과정의 자료를 기반으로 함

5점 만점에 4점

이 기사에서는 Node.js의 기본 원칙과 장점, 단점에 대해 이야기하고 개발을 시작하는 방법을 보여 드리겠습니다. 하지만 Node.js 작업을 시작하기 전에 Node.js와 기존 서버 측 언어(PHP, Python, Ruby)의 차이점을 이해하는 것이 좋습니다.

비동기 프로그래밍

비동기 프로그래밍에 익숙해지기를 바랍니다. 누가 뭐라고 말하든 이것이 Ajax의 기본입니다. Node.js의 핵심 모듈의 모든 기능은 비동기식입니다. 따라서 일반적으로 다른 언어에서 스레드를 차단하는 모든 기능은 대신 Node.js의 백그라운드에서 실행됩니다. 이것이 Node.js를 이해하는 데 가장 중요한 것입니다. 예를 들어, 파일을 읽는 경우 읽기가 완료된 후 실행될 함수를 지정해야 합니다.

당신은 모든 것을 할 것입니다!

Node.js는 단지 프레임워크이므로 모든 작업을 수동으로 수행해야 합니다. Node.js에는 기본적으로 HTTP 서버도 없습니다! 이는 슬픈 일이지만 Node.js는 웹 애플리케이션의 뛰어난 성능으로 깊은 인상을 받았습니다. 하나의 스크립트만으로 클라이언트에 대한 모든 연결을 처리합니다. 이 솔루션은 애플리케이션에 사용되는 리소스의 양을 크게 줄입니다. 예를 들어 다음은 간단한 Node.js 애플리케이션에 대한 코드입니다.

가변 i, a, b, c, 최대;

최대 = 1000000000;

var d = Date.now();

(i = 0; 나는< max; i++) {
a = 1234 + 5678 + 나;
b = 1234 * 5678 + 나;
c = 1234 / 2 + 나;
}

console.log(Date.now() - d);

그리고 여기에 해당하는 PHP가 있습니다:

$a = 널;
$b = 널;
$c = 널;
$i = 널;
$최대 = 1000000000;
$start = 마이크로타임(true);
($i = 0; $i< $max; $i++) {
$a = 1234 + 5678 + $i;
$b = 1234 * 5678 + $i;
$c = 1234 / 2 + $i;
}
var_dump(마이크로타임(true) - $start);

다음 표에서는 두 예제의 실행 시간을 비교합니다.

두 예제 모두 명령줄에서 실행되었으므로 웹 서버 시작이 지연되지 않습니다. 각 테스트를 10번씩 실행하고 평균 결과를 얻었습니다. PHP는 적은 반복 횟수에서는 더 빨랐지만 반복 횟수가 증가함에 따라 이러한 장점은 빠르게 사라졌습니다. 모든 테스트를 완료했을 때 PHP는 Node.js보다 93% 느렸습니다.

Node.js는 빠르지만 올바르게 사용하려면 알아야 할 몇 가지 사항이 있습니다.

모듈

Node.js는 모듈식 아키텍처를 기반으로 구축되었습니다. 이는 복잡한 애플리케이션 생성을 단순화하기 위해 수행됩니다. 모듈은 C의 라이브러리나 Pascal의 유닛과 유사합니다. 각 모듈에는 해당 모듈의 "주제"와 관련된 기능 세트가 포함되어 있습니다. 예를 들어 http 모듈에는 HTTP 관련 기능이 포함되어 있습니다. Node.js에는 파일 시스템 작업, HTTP 및 TCP/UPD 서버 생성 등을 위한 여러 모듈도 포함되어 있습니다.

모듈은 require() 함수를 사용하여 연결됩니다:

Var http = require("http");

이 함수는 지정된 모듈을 반환합니다. 위의 예에서 http 모듈에 대한 링크는 http 변수에 저장됩니다.

이 함수는 모듈 이름을 입력으로 사용합니다. 그런 다음 Node.js는 애플리케이션 디렉터리에서 node_modules 폴더를 확인하고 그 안에서 http라는 폴더를 찾습니다. Node.js가 node_modules 디렉터리나 해당 디렉터리 내의 http 모듈을 찾지 못하면 전역 캐시 모듈을 찾습니다. 이름 대신 require() 함수에 모듈의 상대 또는 절대 경로를 전달할 수 있습니다.

Var myModule = require("./myModule.js");

모듈은 코드 조각을 캡슐화합니다. 모듈 내부의 코드는 대부분 비공개입니다. 즉, 모듈에 선언된 함수와 변수는 해당 모듈 내에서만 사용할 수 있습니다. 하지만 Node.js를 사용하면 공개 함수 및/또는 변수를 만들 수 있습니다. 내보내기 개체가 이에 대한 책임이 있습니다. 예:

VarPI = 수학.PI;
수출.지역 = 함수 (r) (
PI * r * r을 반환합니다;
};
수출.원주 = 함수(r)(
2 * PI * r을 반환;
};

이 예에서는 모듈 내에서만 사용할 수 있는 PI 변수를 생성합니다. 다음 2개의 함수는 내보내기 객체를 생성합니다. 이러한 함수는 내보내기 개체를 통해 정의되므로 모듈 외부에서 사용할 수 있습니다. 결과적으로 PI 변수는 외부 간섭으로부터 완벽하게 보호됩니다. 이런 식으로 면적 및 둘레 함수는 r 매개변수 값에 따라 정상적으로 작동합니다.

글로벌 범위

Node.js는 Google의 JavaScript V8 엔진을 기반으로 개발된 JavaScript 환경입니다. 따라서 최상의 클라이언트측 프로그래밍 방법을 사용해야 합니다. 예를 들어 전역 범위에서 선언을 피해야 합니다. 그러나 이것이 항상 가능한 것은 아닙니다. Node.js에서는 다음과 같이 var 키워드를 생략하여 전역 변수나 함수를 쉽게 만들 수 있습니다.

전역변수 = 1;
globalFunction = 함수 () ( ... );

다시 한 번 강조하지만, 전역 변수와 함수는 가능하면 피해야 합니다. 그러니 조심하세요. 변수를 선언하려면 var를 사용하세요!

설치

물론 Node.js에서 애플리케이션을 작성하고 실행하려면 먼저 이를 설치해야 합니다. nodejs.org 웹사이트에서 Windows 또는 OS X용 설치 프로그램을 다운로드할 수 있습니다. Linux의 경우 모든 패키지 관리자를 사용할 수 있습니다. Node.js를 설치하려면 명령줄을 열고 다음을 입력해야 합니다.

Sudo apt-get 업데이트
sudo apt-get 설치 노드

Sudo 적성 업데이트
sudo 적성 설치 노드

Node.js는 sid 저장소에서 사용할 수 있습니다. 소스 코드 목록에 추가할 수 있습니다.

Sudo echo deb http://ftp.us.debian.org/debian/ sid main > /etc/apt/sources.list.d/sid.list

이전 시스템에 sid 패키지를 설치하면 시스템이 손상될 수 있습니다. 따라서 설치 후에는 /etc/apt/sources.list.d/sid.list를 삭제하는 것이 좋습니다.

새 모듈 설치

Node.js에는 NPM(노드 패키지 관리자)이라는 패키지 관리자가 있습니다. NPM은 Node.js와 함께 자동으로 설치되며 새 모듈을 설치하는 데 사용할 수 있습니다. 새 모듈을 설치하려면 명령줄을 열고 원하는 폴더로 이동한 후 다음 명령을 실행해야 합니다.

Npm 설치 module_name

이 명령의 구문은 운영 체제와 독립적입니다. 이 명령은 module_name 대신 지정된 모듈을 설치합니다.

안녕하세요 세계

Node.js로 작성할 첫 번째 애플리케이션은 "Hello World!"입니다. 이를 위해 hello.js라는 파일을 만들고 다음 코드를 추가하겠습니다.

Console.log("안녕하세요!");

스크립트를 실행하려면 명령줄을 열고 hello.js 파일이 있는 폴더로 이동하여 다음 명령을 실행해야 합니다.

노드 hello.js

콘솔에 "Hello World!"가 표시됩니다.

HTTP 서버

이제 응용 프로그램을 더 복잡하게 만들겠습니다. 하지만 생각만큼 복잡하지는 않습니다.) 코드에는 주석이 포함되어 있습니다.

// http 모듈을 연결합니다.
var http = require("http");

// 서버를 생성합니다. 이 함수는 모든 요청에 ​​대해 매개변수로 전달됩니다.
// 요청 변수에는 모든 요청 매개변수가 포함됩니다.
// 응답 변수를 사용하면 클라이언트에 응답을 보낼 때 수행해야 할 작업을 지정할 수 있습니다.

// 클라이언트가 데이터를 보내고 응답을 기다리고 있을 때 발생하는 이벤트입니다.
// 응답으로 헤더를 작성합니다.
// 200은 HTTP 상태 코드입니다. (200은 "ok"를 의미합니다)
// 두 번째 매개변수는 헤더 필드를 포함하는 객체입니다.
// text/plain의 Content-Type을 사용하여 일반 텍스트를 보냅니다.
response.writeHead(200, (
"콘텐츠 유형": "텍스트/일반"
});
// 데이터 보내기
response.end("안녕하세요 HTTP!");
});
// 포트 8080을 수신합니다.
)).listen(8080);

이것은 매우 간단한 예입니다. 실제로 response.write() 메서드를 사용하면 훨씬 더 많은 데이터를 클라이언트에 보낼 수 있지만 response.end() 메서드보다 먼저 호출해야 합니다. 이 코드를 http.js 파일에 저장하고 콘솔에 입력했습니다.

노드 http.js

그런 다음 브라우저를 열고 http://localhost:8080으로 이동했습니다. 페이지에 "Hello HTTP!"가 표시됩니다.

URL 매개변수 처리 중

앞서 언급했듯이 요청 인수 구문 분석을 포함하여 Node.js에서 모든 작업을 직접 수행해야 합니다. 그러나 그렇게 어렵지는 않습니다. 다음 예에서는 이를 보여 드리겠습니다.

// http 모듈을 연결하고,
var http = require("http"),
// 요청 매개변수를 구문 분석할 때 도움이 되는 URL 모듈
url = require("url");

// 서버를 생성합니다.
http.createServer(함수(요청, 응답)(
// 이벤트 핸들러를 추가합니다.
request.on("end", 함수 () (
// 인수 요청을 구문 분석하여 _get 변수에 저장합니다.
// 이 함수는 URL을 구문 분석하고 객체를 반환합니다.
var _get = url.parse(request.url, true).query;
// 응답으로 헤더를 작성합니다.
response.writeHead(200, (
"콘텐츠 유형": "텍스트/일반"
});
// 데이터를 보내고 응답을 완료합니다.
response.end("여기에 귀하의 데이터가 있습니다: " + _get["data"]);
});
// 8080 포트에서 수신 대기합니다.
)).listen(8080);

이 코드는 Node.js의 핵심 모듈인 url 모듈의parse() 메서드를 사용하여 URL을 객체로 구문 분석합니다. 반환된 개체에는 URL 매개변수를 검색하는 쿼리 속성이 있습니다. 이 코드를 get.js 파일에 저장하고 다음 명령을 실행했습니다.

노드 get.js

그런 다음 브라우저에서 http://localhost:8080/?data=put_some_text_here 페이지를 열었습니다.

파일 읽기 및 쓰기

Node.js에는 파일 작업을 위한 fs 모듈이 있습니다. 이 모듈에는 파일을 읽고 쓰기 위한 fs.readFile() 및 fs.writeFile() 메서드가 있습니다. 예제를 본 후에 이에 대해 더 자세히 설명하겠습니다.

// http 모듈을 연결하고,
var http = require("http"),
// 및 fs 모듈
fs = require("fs");

// http 서버를 생성합니다.
http.createServer(함수(요청, 응답)(
// 이벤트 핸들러를 추가합니다.
request.on("end", 함수 () (
// 파일 읽기
// 헤더를 작성합니다.
response.writeHead(200, (
"콘텐츠 유형": "텍스트/일반"
});
//파일에서 얻은 숫자를 늘립니다.
데이터 = parsInt(data) + 1;
// 파일에 새 숫자를 씁니다.

);
});
// 포트 8080을 수신합니다.
)).listen(8080);

이 코드를 files.js 파일에 저장했습니다. 이 스크립트를 실행하기 전에 files.js가 있는 디렉터리에 test.txt라는 파일을 만들어야 합니다.

이 코드는 fs.readFile() 및 fs.writeFile() 메서드의 작업을 보여줍니다. 서버가 요청을 받을 때마다 스크립트는 파일에서 숫자를 읽고 이를 증가시킨 다음 동일한 파일에 새 숫자를 씁니다. fs.readFile() 메서드는 읽을 파일 이름, 예상되는 인코딩 및 호출할 함수.

파일에 쓰는 것이 훨씬 쉽습니다. 실제 애플리케이션에서는 오류를 확인해야 하지만 어떤 결과도 기대해서는 안 됩니다. fs.writeFile() 메서드는 파일 이름을 사용하고 데이터를 인수로 씁니다. 이 메소드는 인코딩 및 콜백 함수를 지정하기 위해 세 번째 및 네 번째 선택적 인수를 사용할 수도 있습니다.

다음 명령을 사용하여 스크립트를 실행했습니다.

노드 파일.js

그런 다음 브라우저에서 http://localhost:8080을 열고 여러 번 다시 시작했습니다. 코드에 오류가 있었던 것 같습니다. 왜냐하면... 숫자가 2개 증가했습니다. 실제로는 2개의 요청이 전송되었으므로 이는 오류가 아닙니다. 첫 번째 요청은 브라우저가 favicon.ico를 요청할 때 자동으로 이루어졌고 두 번째 요청은 http://localhost:8080이었습니다.

이는 기술적으로 버그는 아니지만 이 스크립트 동작은 명확하지 않습니다. 그래서 URL을 확인하는 수정 사항을 추가했습니다. 수정된 코드는 다음과 같습니다.

// http 모듈을 연결하고,
var http = require("http"),
// 및 fs 모듈
fs = require("fs");

// http 서버를 생성합니다.
http.createServer(함수(요청, 응답)(
// 이벤트 핸들러를 추가합니다.
request.on("end", 함수 () (
// 요청 확인 /
if (request.url == "/") (
// 파일을 읽습니다.
fs.readFile("test.txt", "utf-8", 함수(오류, 데이터) (
// 헤더를 작성합니다.
response.writeHead(200, (
"콘텐츠 유형": "텍스트/일반"
});
// 파일에서 얻은 숫자를 늘립니다.
데이터 = parsInt(data) + 1;
// 증가된 숫자를 파일에 씁니다.
fs.writeFile("test.txt", 데이터);
// 응답으로 좋은 메시지를 작성합니다.
response.end("이 페이지는 " + data + " 번 새로 고쳐졌습니다!");
});
) 또 다른 (
// 파일을 찾을 수 없습니다.
response.writeHead(404);
// 데이터를 전송하지 않고 요청을 완료합니다.
응답.끝();
}
});
// 포트 8080을 수신합니다.
)).listen(8080);

이제 스크립트가 예상대로 작동합니다.

MySQL에 대한 액세스

기존 서버 기술에는 데이터베이스 연결 및 쿼리 수단이 내장되어 있습니다. Node.js의 경우 특수 라이브러리를 설치해야 합니다. 저는 가장 안정적이고 사용하기 쉬운 node-mysql을 선택했습니다. 전체 모듈이 호출됩니다. [이메일 보호됨](@ 뒤에 버전이 옵니다) 이 모듈을 설치하기 위해 콘솔을 열고 스크립트가 저장된 디렉터리로 이동하여 다음 명령을 실행했습니다.

NPM 설치 [이메일 보호됨]

이 명령은 모듈을 다운로드 및 설치하고 현재 디렉터리에 node_modules 폴더를 만듭니다. 다음으로 이 모듈을 사용하는 예를 작성했습니다.

// http 모듈을 연결하고,
var http = require("http"),
// 그리고 mysql 모듈.
mysql = require("mysql");

// 연결을 생성합니다.
// 기본 설정은 mysql 설정에 따라 변경되어야 합니다.
var 연결 = mysql.createConnection((
사용자: "루트",
비밀번호: "",
데이터베이스: "db_name"
});

// http 서버를 생성합니다.
http.createServer(함수(요청, 응답)(
// 이벤트 핸들러를 추가합니다.
request.on("end", 함수 () (
// 데이터베이스에 쿼리합니다.
Connection.query("SELECT * FROM your_table;", 함수(오류, 행, 필드) (
response.writeHead(200, (
"콘텐츠 유형": "x-application/json"
});
//json 형식으로 데이터를 보냅니다.
// 변수 문자열에는 쿼리 결과가 포함됩니다.
response.end(JSON.stringify(rows));
});
});
// 포트 8080을 수신합니다.
)).listen(8080);

데이터베이스에 대한 쿼리는 간단합니다. 쿼리 자체와 쿼리 메서드에 콜백 함수를 작성해야 합니다. 실제 애플리케이션에서는 먼저 오류가 있었는지 확인해야 하며(오류가 있으면 error 매개변수는 정의되지 않습니다) 요청이 완료되었는지 여부에 따라 응답이 달라집니다. 또한 Content-Type을 x-application/json으로 설정했는데 이는 MIME 유형이 실제로 json임을 나타냅니다. 행 매개변수에는 요청 결과가 포함되어 있으며, JSON.stringify() 메서드를 사용하여 JSON 구조로 쉽게 변환했습니다.

이 코드를 mysql.js 파일에 저장하고 다음 명령을 실행했습니다.

노드 mysql.js

그런 다음 브라우저에서 http://localhost:8080으로 이동했는데 브라우저에서 JSON 형식의 파일을 다운로드하라는 제안을 받았습니다.

결론

Node.js에서는 많은 작업을 수동으로 수행해야 하지만 모든 작업이 애플리케이션의 속도와 안정성 측면에서 보상을 받습니다. 낮은 수준에서 애플리케이션을 개발하고 싶지 않다면 언제든지 일부 프레임워크를 사용하여 작업을 더 쉽게 만들 수 있습니다. 예를 들어 익스프레스.

Node.js는 유망한 기술이며 고부하 애플리케이션을 위한 탁월한 선택입니다. 이는 Microsoft, eBay, Yahoo와 같은 기업에서 입증되었습니다. 귀하의 웹사이트나 애플리케이션에 대한 호스팅 선택이 확실하지 않은 경우 언제든지 저렴한 VPS 솔루션이나 Microsoft, Azure 및 Amazon EC2와 같은 다양한 클라우드 서비스를 사용할 수 있습니다.

한 학생이 이렇게 물었습니다. “옛날 프로그래머들은 간단한 컴퓨터만 사용하고 언어 없이 프로그래밍했지만 아름다운 프로그램을 만들었습니다. 우리는 왜 복잡한 컴퓨터와 프로그래밍 언어를 사용하는 걸까요?” Fu-Tzu는 이렇게 대답했습니다. “옛날 건축자들은 막대기와 진흙만을 사용했지만 아름다운 오두막을 만들었습니다.”

위안마 스승님, “프로그래밍 책”

지금까지 JavaScript를 배우고 단일 환경인 브라우저에서 사용해 보았습니다. 이 장과 다음 장에서는 브라우저 외부에서 JavaScript 기술을 사용할 수 있게 해주는 프로그램인 Node.js를 간략하게 소개하겠습니다. 이를 통해 명령줄 유틸리티부터 동적 HTTP 서버까지 모든 것을 작성할 수 있습니다.

이 장에서는 Node.js를 구성하는 중요한 아이디어를 가르치는 데 중점을 두고 프레임워크에서 유용한 프로그램을 작성할 수 있도록 충분한 정보를 제공하도록 설계되었습니다. 그들은 Node.js에 대한 포괄적인 참조가 되려고 노력하지 않습니다.

이전 장의 코드를 브라우저에서 직접 작성하고 실행할 수 있지만 이 장의 코드는 Node용으로 작성된 것이므로 브라우저에서는 작동하지 않습니다.

이 장의 코드를 바로 실행하려면 nodejs.org에서 운영 체제에 맞는 Node를 설치하는 것부터 시작하세요. 또한 이 사이트에서는 Node 및 해당 내장 모듈에 대한 문서를 찾을 수 있습니다.

소개

네트워크를 통해 통신하는 시스템을 작성할 때 가장 어려운 문제 중 하나는 입력과 출력을 처리하는 것입니다. 네트워크, 디스크 및 기타 장치에서 데이터를 읽고 씁니다. 데이터 이동에는 시간이 걸리며 이러한 활동을 적절하게 계획하면 사용자 또는 네트워크 요청에 대한 시스템 응답 시간에 큰 영향을 미칠 수 있습니다.

전통적인 입력 및 출력 처리에서는 readFile과 같은 함수가 파일 읽기를 시작하고 파일을 완전히 읽었을 때만 반환합니다. 이를 동기식 I/O(입력/출력)이라고 합니다.

Node는 비동기 I/O를 더 쉽고 쉽게 사용할 수 있도록 설계되었습니다. 우리는 이미 17장에서 논의된 XMLHttpRequest 브라우저 객체와 같은 비동기 인터페이스를 보았습니다. 이러한 인터페이스를 사용하면 인터페이스가 작업을 수행하는 동안 스크립트가 계속 실행될 수 있으며 작업이 완료되면 콜백 함수를 호출할 수 있습니다. 이것이 Node.js에서 모든 I/O가 작동하는 방식입니다.

JavaScript는 Node.js와 같은 시스템에 쉽게 맞습니다. 이는 I/O 시스템이 내장되어 있지 않은 몇 안 되는 언어 중 하나입니다. 따라서 JavaScript는 I/O에 대한 Node의 다소 특이한 접근 방식에 쉽게 적합하며 결국 두 개의 서로 다른 입력 및 출력 시스템을 생성하지 않습니다. 2009년 Node를 개발할 때 사람들은 이미 브라우저에서 콜백 기반 I/O를 사용하고 있었기 때문에 언어를 둘러싼 커뮤니티는 비동기 프로그래밍 스타일에 익숙했습니다.

비동기성

프로그램이 인터넷에서 두 개의 리소스를 수신한 다음 데이터로 작업을 수행해야 하는 작은 예를 통해 I/O에 대한 동기식 접근 방식과 비동기식 접근 방식의 차이점을 설명하려고 합니다.

동기식 환경에서 문제를 해결하는 확실한 방법은 순차적으로 쿼리하는 것입니다. 이 방법에는 단점이 있습니다. 두 번째 요청은 첫 번째 요청이 완료된 후에만 시작됩니다. 총 시간은 두 요청을 처리하는 데 걸리는 시간의 합보다 적지 않습니다. 이는 네트워크를 통해 데이터가 전송되는 동안 대부분의 시간 동안 컴퓨터를 유휴 상태로 유지하는 컴퓨터를 비효율적으로 사용하는 것입니다.

동기식 시스템의 문제에 대한 해결책은 추가 프로그램 실행 제어 스레드를 시작하는 것입니다(이에 대해서는 이미 14장에서 논의했습니다). 두 번째 스레드는 두 번째 요청을 실행할 수 있으며, 두 스레드는 모두 결과가 반환될 때까지 기다린 후 다시 동기화되어 작업을 단일 결과로 수렴합니다.

다이어그램에서 굵은 선은 프로그램의 정상 작동 시간을 나타내고 가는 선은 I/O 대기 시간을 나타냅니다. 동기식 모델에서는 I/O에 소요된 시간이 각 스레드의 시간 일정에 포함됩니다. 비동기식에서는 I/O를 통해 작업을 시작하면 타임라인이 분기됩니다. I/O를 시작한 스레드는 실행을 계속하고 I/O는 병렬로 실행되어 완료 시 함수 콜백을 만듭니다.

동기 및 비동기 I/O의 프로그램 흐름

이 차이점을 표현하는 또 다른 방법은 동기식 모델에서는 I/O가 끝날 때까지 기다리는 것이 암시적이지만 비동기식 모델에서는 명시적이며 직접 제어할 수 있다는 것입니다. 그러나 비동기식은 양방향으로 작동합니다. 비선형 프로그램을 표현하기는 더 쉬워지지만 직선 프로그램은 표현하기가 더 어려워집니다.

17장에서 나는 콜백이 많은 소음을 발생시키고 프로그램을 덜 체계적으로 만든다는 사실을 이미 다루었습니다. 이 접근 방식이 일반적으로 좋은 생각인지 여부는 논쟁의 여지가 있습니다. 어쨌든 익숙해지는 데는 시간이 걸립니다.

하지만 JavaScript 기반 시스템의 경우 콜백과 함께 비동기를 사용하는 것이 합리적이라고 말하고 싶습니다. JavaScript의 장점 중 하나는 단순성입니다. 프로그램에 여러 스레드를 추가하려고 하면 많은 복잡성이 발생합니다. 콜백이 코드를 단순하게 만들지는 않지만 그 뒤에 숨은 아이디어는 매우 간단하면서도 고성능 웹 서버를 작성할 수 있을 만큼 강력합니다.

노드 명령

Node.js가 시스템에 설치되면 JavaScript 파일을 실행하는 node라는 프로그램이 있습니다. 다음 코드가 포함된 hello.js 파일이 있다고 가정해 보겠습니다.

Var 메시지 = "안녕하세요 세계"; console.log(메시지);

명령줄에서 프로그램을 실행할 수 있습니다.

$node hello.js 안녕하세요 세상

Node의 console.log 메소드는 브라우저에서와 동일한 방식으로 작동합니다. 텍스트를 표시합니다. 그러나 Node에서는 텍스트가 브라우저의 JavaScript 콘솔이 아닌 표준 출력으로 인쇄됩니다.

파일 없이 노드를 실행하면 JavaScript 코드를 작성하고 결과를 얻을 수 있는 쿼리 문자열이 제공됩니다.

$ 노드 > 1 + 1 2 > [-1, -2, -3].map(Math.abs) > ​​​​process.exit(0) $

콘솔과 같은 프로세스 변수는 Node.js에서 전역적으로 사용할 수 있습니다. 이는 프로그램을 검사하고 조작하는 여러 가지 방법을 제공합니다. 종료 메소드는 프로세스를 종료하고 프로그램 종료 상태 코드를 전달할 수 있습니다. 이 코드는 프로그램이 성공적으로 종료되었는지(코드 0) 실패했는지(다른 숫자) 노드를 시작한 프로그램(이 경우 셸)에 알려줍니다.

프로그램에 전달된 명령줄 인수에 액세스하려면 process.argv 문자열 배열을 읽을 수 있습니다. 여기에는 node 명령의 이름과 스크립트의 이름도 포함되어 있으므로 인수 목록은 인덱스 2에서 시작합니다. showargv.js 파일에 console.log(process.argv) 문만 포함된 경우 다음과 같이 실행할 수 있습니다. :

$ node showargv.js 1 --그리고 2 ["node", "/home/marijn/showargv.js", "one", "--and", "two"]

모든 표준 JavaScript 전역 변수(Array, Math, JSON)는 Node 환경에서도 사용할 수 있습니다. 하지만 문서나 알림 등 브라우저 관련 기능은 없습니다.

브라우저에서 window라고 불리는 전역 범위 객체는 Node.js에서는 더 의미 있게 global이라고 불립니다.

모듈

콘솔 및 프로세스와 같이 언급된 몇 가지 변수를 제외하고 Node는 전역 범위에서 거의 기능을 유지하지 않습니다. 내장된 나머지 기능에 액세스하려면 모듈 시스템에 액세스해야 합니다.

require 함수를 기반으로 하는 CommonJS 시스템은 10장에서 설명했습니다. 이 시스템은 Node에 내장되어 있으며 내장 및 다운로드된 라이브러리부터 프로그램의 일부인 파일까지 모든 것을 로드하는 데 사용됩니다.

require Node를 호출할 때, 주어진 문자열을 파일 이름으로 변환해야 합니다. "/", "./" 또는 "../"로 시작하는 경로는 현재 경로를 기준으로 하는 경로로 변환됩니다. "./"는 현재 디렉터리를 의미하고 "../"는 위 디렉터리를 의미하며 "/"는 파일 시스템의 루트 디렉터리를 의미합니다. /home/marijn/elife/run.js 파일에서 "./world/world"를 요청하면 Node는 /home/marijn/elife/world/world.js 파일을 로드하려고 시도합니다. .js 확장자는 생략할 수 있습니다.

상대 경로나 절대 경로가 아닌 것으로 보이는 문자열을 전달하면 내장 모듈이거나 node_modules 디렉터리에 설치된 모듈인 것으로 간주됩니다. 예를 들어, require("fs")는 파일 시스템 작업을 위한 내장 모듈을 제공하고, require("elife")는 node_modules/elife/에서 라이브러리 로드를 시도합니다. 라이브러리를 설치하는 일반적인 방법은 NPM을 사용하는 것입니다. 이에 대해서는 나중에 다시 설명하겠습니다.

시연을 위해 간단한 두 파일 프로젝트를 만들어 보겠습니다. 첫 번째는 main.js라고 하며 문자열을 왜곡하도록 설계된 명령줄에서 호출되는 스크립트를 정의합니다.

Var garble = require("./garble"); // 인덱스 2에는 명령줄의 첫 번째 프로그램 인수가 포함되어 있습니다. var 인수 = process.argv; console.log(garble(인수));

garble.js 파일은 이전에 정의한 명령줄 프로그램과 garble 함수에 직접 액세스해야 하는 다른 스크립트 모두에서 사용할 수 있는 문자열 맹글링 라이브러리를 정의합니다.

Module.exports = function(string) ( return string.split("").map(function(ch) ( return String.fromCharCode(ch.charCodeAt(0) + 5); )).join(""); ) ;

속성을 추가하는 대신 module.exports를 바꾸면 모듈에서 특정 값을 내보낼 수 있습니다. 이 경우 모듈의 요청 결과는 왜곡 기능 자체가 됩니다.

이 함수는 빈 문자열로 분할을 사용하여 문자열을 문자로 분할한 다음 모든 문자를 5단위 더 높은 코드로 다른 문자로 바꿉니다. 그런 다음 결과를 다시 문자열로 연결합니다.

이제 도구를 호출할 수 있습니다.

$ 노드 main.js JavaScript Of(fXhwnuy

NPM을 통한 설치

10장에서 간략하게 언급한 NPM은 JavaScript 모듈의 온라인 저장소이며, 그 중 다수는 Node.js용으로 특별히 작성되었습니다. 컴퓨터에 Node를 설치하면 이 저장소에 편리한 인터페이스를 제공하는 npm 프로그램이 제공됩니다.

예를 들어 NPM 모듈 중 하나인 figlet은 텍스트를 텍스트 문자로 구성된 그림인 "ASCII 아트"로 변환합니다. 설치 방법은 다음과 같습니다.

$ npm 설치 figlet npm GET https://registry.npmjs.org/figlet npm 200 https://registry.npmjs.org/figlet npm GET https://registry.npmjs.org/figlet/-/figlet-1.0. 9.tgz npm 200 https://registry.npmjs.org/figlet/-/figlet-1.0.9.tgz [이메일 보호됨] node_modules/figlet $ node > var figlet = require("figlet"); > figlet.text("안녕하세요!", function(error, data) ( if (error) console.error(error); else console.log(data); )); _ _ _ _ _ _ _ | | | | ___| | | ___ __ _____ _ __| | __| | | | |_| |/ _ \ | |/ _ \ \ \ /\ / / _ \| "__| |/ _` | | | _ | __/ | | (_) | \ V V / (_) | | | | (_| |_| |_| |_|\___|_|_|\ ___/ \_/\_/ \___/|_|

npm install을 실행한 후 NPM은 node_modules 디렉터리를 생성합니다. 그 안에는 라이브러리가 포함된 figlet 디렉토리가 있습니다. 노드를 시작하고 require(“figlet”)를 호출하면 라이브러리가 로드되고 텍스트 메서드를 호출하여 크고 멋진 글자를 인쇄할 수 있습니다.

흥미로운 점은 단순히 대문자가 포함된 문자열을 반환하는 대신 figlet.text가 결과를 전달하는 콜백 함수를 허용한다는 것입니다. 또한 오류가 발생한 경우 오류 객체를 포함하고 성공할 경우 null을 포함하는 또 다른 인수인 error를 전달합니다.

이 작동 원리는 Node.js에서 채택되었습니다. 문자를 생성하려면 figlet은 문자가 포함된 디스크에서 파일을 읽어야 합니다. 파일 읽기는 Node에서 비동기 작업이므로 figlet.text는 결과를 즉시 반환할 수 없습니다. 비동기성은 전염성이 있습니다. 비동기식을 호출하는 모든 함수는 그 자체로 비동기화됩니다.

NPM은 단순한 npm 설치 그 이상입니다. 프로그램이나 라이브러리, 특히 기반이 되는 라이브러리에 대한 JSON 정보가 포함된 package.json 파일을 읽습니다. 해당 파일이 포함된 디렉터리에서 npm install을 실행하면 모든 종속성이 자동으로 설치되고 해당 종속성이 차례로 설치됩니다. npm 도구는 다른 사람들이 라이브러리를 찾고, 다운로드하고, 사용할 수 있도록 NPM 온라인 저장소에 라이브러리를 호스팅하는 데에도 사용됩니다.

NPM 사용에 대한 자세한 내용은 더 이상 다루지 않겠습니다. 라이브러리 검색에 대한 문서는 npmjs.org를 참조하세요.

파일 시스템 모듈

가장 널리 사용되는 내장 노드 모듈 중 하나는 "파일 시스템"을 의미하는 "fs" 모듈입니다. 이 모듈은 파일 및 디렉터리 작업을 위한 기능을 제공합니다.

예를 들어, 파일을 읽고 파일 내용으로 콜백을 만드는 readFile 함수가 있습니다.

Var fs = require("fs"); fs.readFile("file.txt", "utf8", function(error, text) ( if (error) throw error; console.log("포함된 파일:", text); ));

readFile의 두 번째 인수는 파일 내용을 문자열로 변환할 문자 인코딩을 지정합니다. 텍스트는 여러 가지 방법으로 이진 데이터로 변환할 수 있지만 가장 최신 방법은 UTF-8입니다. 파일에 다른 인코딩의 텍스트가 포함되어 있다고 믿을 이유가 없다면 "utf8" 매개변수를 안전하게 전달할 수 있습니다. 인코딩을 지정하지 않으면 Node는 바이너리로 인코딩된 데이터를 문자열이 아닌 Buffer 객체로 제공합니다. 이것은 파일의 바이트를 포함하는 배열과 유사한 객체입니다.

Var fs = require("fs"); fs.readFile("file.txt", function(error, buffer) ( if (error) throw error; console.log("파일에 ", buffer.length, " 바이트가 포함되어 있습니다.", "첫 번째 바이트:", buffer ); ));

비슷한 함수인 writeFile이 디스크에 파일을 쓰는 데 사용됩니다.

Var fs = require("fs"); fs.writeFile("graffiti.txt", "노드가 여기에 있었습니다.", function(err) ( if (err) console.log("아무 것도 작동하지 않았으며 그 이유는 다음과 같습니다:", err); else console.log("쓰기 성공 . 누구나 무료입니다."); ));

여기서 인코딩을 설정할 필요가 없습니다. writeFile은 Buffer 객체가 아닌 쓸 문자열이 주어지면 UTF-8의 기본 인코딩을 사용하여 텍스트로 출력되어야 한다고 가정하기 때문입니다.

"fs" 모듈에는 많은 유용한 기능이 포함되어 있습니다. readdir 함수는 디렉터리에 있는 파일 목록을 문자열 배열로 반환하고, stat는 파일에 대한 정보를 반환하고, rename은 파일 이름을 바꾸고, 연결 해제는 삭제 등을 수행합니다. nodejs.org의 문서를 참조하세요.

많은 fs 함수에는 동기 및 비동기 옵션이 모두 있습니다. 예를 들어, readFileSync라는 readFile 함수의 동기 버전이 있습니다.

Var fs = require("fs"); console.log(fs.readFileSync("file.txt", "utf8"));

동기 함수는 사용하기 쉽고 비동기 메서드의 추가 속도가 중요하지 않은 간단한 스크립트에 더 유용합니다. 그러나 동기 작업이 실행되는 동안 프로그램은 완전히 중지됩니다. 사용자 입력이나 네트워크를 통한 다른 프로그램에 응답해야 하는 경우 동기 I/O를 기다리면 성가신 지연이 발생합니다.

HTTP 모듈

또 다른 주요 모듈은 "http"입니다. HTTP 서버 및 HTTP 요청을 생성하는 기능을 제공합니다.

간단한 HTTP 서버를 시작하는 데 필요한 모든 것은 다음과 같습니다.

Var http = require("http"); var server = http.createServer(function(request, response) ( response.writeHead(200, ("Content-Type": "text/html")); response.write("

안녕하세요!

요청하셨습니다 " + 요청.url + "

"); response.end(); )); server.listen(8000);

컴퓨터에서 스크립트를 실행하면 브라우저가 localhost :8000/hello를 가리키도록 하여 서버에 대한 요청을 생성할 수 있습니다. 작은 HTML 페이지로 응답합니다.

createServer에 인수로 전달된 함수는 서버에 연결을 시도할 때마다 호출됩니다. 요청 및 응답 변수는 입력 및 출력 데이터를 나타내는 개체입니다. 첫 번째에는 요청에 대한 정보가 포함되어 있습니다. 예를 들어 url 속성에는 요청 URL이 포함되어 있습니다.

무언가를 다시 보내려면 응답 개체의 메서드가 사용됩니다. 첫 번째인 writeHead는 응답 헤더를 작성합니다(17장 참조). 상태 코드(이 경우 "OK"는 200)와 헤더 값을 포함하는 개체를 제공합니다. 여기서 우리는 클라이언트에게 HTML 문서를 기다려야 한다고 말합니다.

그런 다음 response.write를 통해 전송된 응답 본문(문서 자체)이 옵니다. 예를 들어 스트리밍 데이터가 도착할 때 응답을 청크로 보내려는 경우 이 메서드를 여러 번 호출할 수 있습니다. 마지막으로 response.end는 응답의 끝을 알립니다.

server.listen을 호출하면 서버가 포트 8000에서 요청을 수신하게 됩니다. 따라서 브라우저에서 localhost(기본 포트는 80)뿐만 아니라 localhost:8000으로 이동해야 합니다.

추가 이벤트(이 경우 연결)를 기다리고 있기 때문에 자동으로 종료되지 않는 Node 스크립트를 중지하려면 Ctrl-C를 눌러야 합니다.

실제 웹 서버는 예제에 설명된 것보다 훨씬 더 많은 작업을 수행합니다. 클라이언트가 수행하려는 작업을 이해하기 위해 요청 메서드(메서드 속성)를 살펴보고, 해당 작업이 수행되어야 하는 리소스를 이해하기 위해 요청 URL을 살펴봅니다. 다음으로 서버의 고급 버전을 볼 수 있습니다.

HTTP 클라이언트를 만들기 위해 "http" 요청 모듈 기능을 사용할 수 있습니다.

Var http = require("http"); var request = http.request(( 호스트 이름: "eloquentjavascript.net", 경로: "/20_node.html", 메서드: "GET", 헤더: (수락: "text/html") ), function(response) ( 콘솔 .log("서비스가 코드로 응답했습니다. ", response.statusCode )); 요청.끝();

첫 번째 요청 인수는 요청을 구성하여 우리가 통신할 서버, 요청이 사용할 경로, 사용할 방법 등을 Node에 알려줍니다. 두 번째는 기능이다. 요청이 끝나면 호출해야 합니다. 응답에 대한 모든 정보(예: 상태 코드)가 포함된 응답 개체가 전달됩니다.

서버의 응답 객체와 마찬가지로 요청에 의해 반환된 객체를 사용하면 write 메소드를 사용하여 데이터를 전달하고 end 메소드를 사용하여 요청을 종료할 수 있습니다. GET 요청은 본문에 데이터를 포함하면 안 되므로 이 예에서는 쓰기를 사용하지 않습니다.

보안 URL(HTTPS)에 대한 요청을 위해 Node는 http.request와 유사한 자체 요청 기능이 있는 https 모듈을 제공합니다.

스트림

HTTP 예제에서 두 가지 예제 스트림, 즉 서버가 쓸 수 있는 응답 객체와 http.request에서 반환되는 요청 객체를 보았습니다.

쓰기 가능한 스트림은 노드 인터페이스에서 널리 사용되는 개념입니다. 모든 스레드에는 문자열이나 Buffer 개체를 전달할 수 있는 쓰기 메서드가 있습니다. end 메소드는 스트림을 닫고 인수가 있으면 닫기 전에 데이터 조각을 인쇄합니다. 두 메소드 모두 추가 인수를 통해 콜백 함수를 제공할 수 있으며, 이는 녹음이 완료되거나 스트림이 닫힐 때 호출됩니다.

fs.createWriteStream 함수를 사용하여 파일을 가리키는 스트림을 생성할 수 있습니다. 그런 다음 write 메소드를 사용하여 fs.writeFile에서와 같이 파일 전체가 아닌 청크로 파일에 쓸 수 있습니다.

읽기 가능한 스트림은 좀 더 복잡해집니다. HTTP 서버의 콜백 함수에 전달된 요청 변수와 HTTP 클라이언트에 전달된 응답 변수는 모두 읽을 수 있는 스트림입니다. (서버는 요청을 읽고 응답을 쓰고, 클라이언트는 요청을 쓰고 응답을 읽습니다.) 스트림 읽기는 메서드가 아닌 이벤트 핸들러를 통해 수행됩니다.

Node에서 이벤트를 생성하는 객체에는 브라우저의 addEventListener 메소드와 유사한 on 메소드가 있습니다. 이벤트 이름과 함수를 지정하고, 이벤트가 발생하면 즉시 호출되도록 해당 함수를 등록합니다.

읽기 가능한 스트림에는 "data" 및 "end" 이벤트가 있습니다. 첫 번째는 데이터가 도착할 때 발생하고 두 번째는 완료 시 발생합니다. 이 모델은 문서 전체를 수신하지 않더라도 즉시 처리할 수 있는 스트리밍 데이터에 적합합니다. 파일은 fs.createReadStream을 통해 스트림으로 읽을 수 있습니다.

다음 코드는 요청 본문을 읽고 이를 모두 대문자 텍스트 스트림으로 다시 보내는 서버를 만듭니다.

Var http = require("http"); http.createServer(function(request, response) ( response.writeHead(200, ("Content-Type": "text/plain")); request.on("data", function(chunk) ( response.write(chunk) .toString().toUpperCase()); request.on("end", function() ( response.end(); )).listen(8000);

Data Handler에 전달된 청크 변수는 기본 인코딩(UTF-8)에서 디코딩하는 toString 메소드를 호출하여 문자열로 변환할 수 있는 2진 버퍼입니다.

다음 코드는 서버와 동시에 실행될 때 서버에 요청을 보내고 수신된 응답을 인쇄합니다.

Var http = require("http"); var request = http.request(( 호스트 이름: "localhost", 포트: 8000, 메서드: "POST"), function(response) ( response.on("data", function(chunk) ( process.stdout.write(chunk) .toString()); request.end("안녕하세요 서버");

이 예제에서는 console.log가 아닌 process.stdout(쓰기 가능한 스트림인 프로세스의 표준 출력)에 씁니다. console.log는 각 코드 뒤에 추가 줄 바꿈을 추가하기 때문에 사용할 수 없습니다. 여기서는 필요하지 않습니다.

간단한 파일 서버

HTTP 서버와 파일 시스템 작업에 대한 새로운 지식을 결합하고 이들 사이에 브리지, 즉 파일에 대한 원격 액세스를 제공하는 HTTP 서버를 구축해 보겠습니다. 이러한 서버에는 많은 사용 사례가 있습니다. 이를 통해 웹 애플리케이션은 데이터를 저장하고 공유할 수 있으며, 여러 사람들에게 파일 세트에 대한 액세스 권한을 부여할 수 있습니다.

파일을 HTTP 리소스로 처리할 때 GET, PUT 및 DELETE 메서드를 사용하여 파일을 읽고 쓰고 삭제할 수 있습니다. 요청의 경로를 파일 경로로 해석합니다.

전체 파일 시스템을 노출할 필요는 없으므로 이러한 경로를 루트 디렉터리에 상대적인 것으로 해석할 것이며 이것이 스크립트의 시작 디렉터리가 됩니다. /home/marijn/public/(또는 Windows의 경우 C:\Users\marijn\public\)에서 서버를 시작하는 경우 /file.txt에 대한 요청은 /home/marijn/public/file.txt( 또는 C :\Users\marijn\public\file.txt).

우리는 다양한 HTTP 메소드를 처리하는 함수를 저장하기 위해 메소드 객체를 사용하여 프로그램을 점진적으로 구축할 것입니다.

Var http = require("http"), fs = require("fs"); var 메소드 = Object.create(null); http.createServer(function(request, response) ( function response(code, body, type) ( if (!type) type = "text/plain"; response.writeHead(code, ("Content-Type": type)) ; if (body && body.pipe) body.pipe(response); else response.end(body); if (메소드의 request.method) 메소드(urlToPath(request.url), response, else response(); "메소드" + request.method + "는 허용되지 않습니다. )).listen(8000);

이 코드는 405 오류를 반환하는 서버를 시작합니다. 이 코드는 요청된 메서드가 서버에서 지원되지 않음을 나타내는 데 사용됩니다.

응답 함수는 다양한 메서드를 처리하고 요청을 완료하기 위한 콜백 역할을 하는 함수에 전달됩니다. HTTP 상태 코드, 본문 및 콘텐츠 유형을 허용합니다. 전달된 본문이 읽기 가능한 스트림인 경우 읽기 가능한 스트림을 쓰기 가능한 스트림으로 전달하는 데 사용되는 파이프 메서드가 있습니다. 그렇지 않은 경우 null(본문이 비어 있음) 또는 문자열이라고 가정하고 최종 응답 메서드에 직접 전달됩니다.

요청의 URL에서 경로를 가져오기 위해 urlToPath 함수는 Node에 내장된 "url" 모듈을 사용하여 URL을 구문 분석합니다. /file.txt와 같은 경로 이름을 사용하여 %20 이스케이프 코드를 제거하기 위해 디코딩하고 현재 디렉터리에 대한 상대 경로를 가져오기 위해 앞에 점을 삽입합니다.

urlToPath 함수가 안전하지 않다고 생각하시나요? 네가 옳아. 연습문제에서 이 문제를 다시 다루겠습니다.

디렉터리를 읽을 때 파일 목록을 반환하고, 파일을 읽을 때 파일의 내용을 반환하도록 GET 메서드를 설계하겠습니다.

진짜 질문은 파일을 읽을 때 어떤 유형의 Content-Type 헤더를 반환해야 하는가입니다. 파일에는 무엇이든 있을 수 있으므로 서버는 모든 사람에게 동일한 유형을 반환할 수 없습니다. 하지만 NPM이 이를 도와줄 수 있습니다. MIME 모듈(text/plain과 같은 파일 콘텐츠 유형 표시자는 MIME 유형이라고도 함)은 수많은 파일 확장자의 올바른 유형을 알고 있습니다.

서버 스크립트가 있는 디렉터리에서 다음 npm 명령을 실행하면 require("mime")를 사용하여 유형 라이브러리를 쿼리할 수 있습니다.

$ npm 설치 mime npm http GET https://registry.npmjs.org/mime npm http 304 https://registry.npmjs.org/mime [이메일 보호됨] node_modules/mime

요청한 파일이 존재하지 않는 경우 이 경우의 올바른 오류 코드는 404입니다. fs.stat를 사용하여 파일에 대한 정보를 반환하여 해당 파일이 존재하는지, 디렉토리인지 확인합니다.

Methods.GET = function(path, response) ( fs.stat(path, function(error, stats) ( if (error && error.code == "ENOENT") response(404, "파일을 찾을 수 없음"); else if (오류) 응답(500, error.toString()); else if (stats.isDirectory()) fs.readdir(path, function(error, files) ( if (오류) 응답(500, error.toString()) ; 그렇지 않으면 응답(200, files.join("\n")); 그렇지 않으면 응답(200, fs.createReadStream(path), require("mime").lookup(path));

디스크 쿼리에는 시간이 걸리기 때문에 fs.stat는 비동기적으로 실행됩니다. 파일이 존재하지 않으면 fs.stat는 코드 속성 "ENOENT"가 포함된 오류 개체를 콜백 함수에 전달합니다. Node가 오류마다 다른 오류 유형을 정의했다면 좋겠지만 그렇지 않습니다. 대신 혼란스러운 Unix 스타일 코드를 뱉어냅니다.

요청에 문제가 있음을 나타내는 4로 시작하는 코드와 달리 서버에 문제가 있음을 나타내는 코드 500으로 모든 예기치 않은 오류가 발생합니다. 어떤 상황에서는 이것이 완전히 정확하지 않을 수도 있지만 작은 샘플 프로그램의 경우에는 충분합니다.

fs.stat에서 반환된 stats 개체는 파일에 대한 모든 정보를 알려줍니다. 예를 들어, size는 파일 크기이고, mtime은 수정 날짜입니다. 여기에서 이것이 디렉토리인지 일반 파일인지 알아내야 합니다. isDirectory 메소드가 이를 알려줍니다.

디렉토리의 파일 목록을 읽으려면 fs.readdir을 사용하고 다른 콜백을 통해 이를 사용자에게 반환합니다. 일반 파일의 경우 fs.createReadStream을 통해 읽을 수 있는 스트림을 생성하고 해당 파일에 대해 MIME 모듈이 생성한 콘텐츠 유형과 함께 이를 응답에 전달합니다.

DELETE 처리 코드가 더 간단해집니다.

Methods.DELETE = function(path, response) ( fs.stat(path, function(error, stats) ( if (error && error.code == "ENOENT") response(204); else if (error) response(500 , error.toString()); else if (stats.isDirectory()) fs.rmdir(path, responseErrorOrNothing(respond)); else fs.unlink(path, responseErrorOrNothing(respond));

존재하지 않는 파일을 삭제하려고 하면 오류 대신 204 상태가 반환되는 이유가 궁금할 것입니다. 존재하지 않는 파일을 삭제하려고 하면 파일이 더 이상 존재하지 않으므로 요청이 이미 실행되었다고 말할 수 있습니다. HTTP 표준은 사람들이 멱등적 요청, 즉 동일한 작업을 여러 번 반복해도 다른 결과가 생성되지 않는 요청을 하도록 권장합니다.

함수 responseErrorOrNothing(respond) ( return function(error) ( if (error) response(500, error.toString()); else response(204); ); )

HTTP 응답에 데이터가 포함되어 있지 않으면 204("콘텐츠 없음") 상태 코드를 사용할 수 있습니다. 다양한 상황에서 오류를 보고하거나 204 응답을 반환하는 콜백 함수를 제공해야 하므로 이러한 콜백을 생성하는 특별한 함수인 responseErrorOrNothing을 작성했습니다.

PUT 요청 핸들러는 다음과 같습니다.

Methods.PUT = function(path, response, request) ( var outStream = fs.createWriteStream(path); outStream.on("error", function(error) ( response(500, error.toString()); )); outStream.on("finish", function() ( response(204); )); request.pipe(outStream);

여기서는 파일이 있는지 확인할 필요가 없습니다. 파일이 있으면 간단히 덮어쓰면 됩니다. 다시 한 번 파이프를 사용하여 읽기 스트림에서 쓰기 스트림으로(우리의 경우 요청에서 파일로) 데이터를 전송합니다. 스레드를 생성할 수 없는 경우 "오류" 이벤트가 생성되며 이를 응답으로 보고합니다. 데이터가 성공적으로 전송되면 파이프가 두 스트림을 모두 닫고 "완료" 이벤트가 발생하게 됩니다. 그런 다음 코드 204를 사용하여 성공을 보고할 수 있습니다.

전체 서버 스크립트는 여기에 있습니다: eloquentjavascript.net/code/file_server.js. Node.js를 통해 다운로드하여 실행할 수 있습니다. 물론 연습이나 실험을 해결하기 위해 변경, 보완할 수도 있습니다.

Unix 시스템에서 공개적으로 사용 가능한 컬 명령줄 유틸리티를 사용하여 HTTP 요청을 생성할 수 있습니다. 다음 스니펫은 서버를 테스트합니다. -X는 요청 방법을 지정하는 데 사용되고, -d는 요청 본문을 포함하는 데 사용됩니다.

$ 컬 http://localhost:8000/file.txt 파일을 찾을 수 없습니다 $ 컬 -X PUT -d hello http://localhost:8000/file.txt $ 컬 http://localhost:8000/file.txt hello $ 컬 -X DELETE http://localhost:8000/file.txt $ 컬 http://localhost:8000/file.txt 파일을 찾을 수 없습니다

file.txt에 대한 첫 번째 요청은 파일이 아직 존재하지 않기 때문에 실패합니다. PUT 요청은 파일을 생성하고 다음 요청은 파일을 성공적으로 검색합니다. DELETE를 통해 삭제한 후 파일이 다시 누락되었습니다.

오류 처리 중

파일 서버 코드에는 오류 처리 방법을 모를 때 예외를 리디렉션하는 6개 위치가 있습니다. 예외는 콜백 함수에 자동으로 전달되지 않고 인수로 전달되므로 매번 개별적으로 처리해야 합니다. 이는 예외 처리의 이점, 즉 오류를 중앙에서 처리하는 기능을 무효화합니다.

실제로 시스템에서 예외가 발생하면 어떻게 되나요? 우리는 try 블록을 사용하지 않으므로 호출 스택의 맨 위로 전달됩니다. Node에서는 이로 인해 프로그램이 종료되고 예외 정보(스택 추적과 함께)가 표준 출력으로 인쇄됩니다.

따라서 호출 함수에 인수로 전달되는 비동기 문제와는 달리 코드에 문제가 있으면 서버가 중단됩니다. 정확하게 응답을 보내기 위해 요청을 처리하는 동안 발생하는 모든 예외를 처리해야 하는 경우 각 콜백에 try/catch 블록을 추가해야 합니다.

이것은 나쁘다. 많은 Node 프로그램은 예외 처리를 가능한 한 적게 사용하도록 작성되었습니다. 이는 예외가 발생하면 프로그램이 이를 처리할 수 없어 충돌이 발생한다는 것을 의미합니다.

또 다른 접근 방식은 17장에서 설명한 Promise를 사용하는 것입니다. Promise는 콜백 함수에서 발생하는 예외를 포착하여 오류로 전달합니다. Node에서는 Promise 라이브러리를 로드하고 이를 사용하여 비동기 호출을 처리할 수 있습니다. Promise를 통합하는 노드 라이브러리는 거의 없지만 일반적으로 래핑하기가 매우 간단합니다. NPM의 우수한 “promise” 모듈에는 denodeify라는 함수가 포함되어 있습니다. 이 함수는 fs.readFile과 같은 비동기 함수를 가져와서 이를 Promise를 반환하는 함수로 변환합니다.

Var Promise = require("약속"); var fs = require("fs"); var readFile = Promise.denodeify(fs.readFile); readFile("file.txt", "utf8").then(function(content) ( console.log("포함된 파일: " + content); ), function(error) ( console.log("파일을 읽지 못했습니다. : " + 오류); ));

비교를 위해 나는 eloquentjavascript.net/code/file_server_promises.js에서 찾을 수 있는 promise를 사용하여 파일 서버의 다른 버전을 작성했습니다. 이제 함수가 콜백을 할당하는 대신 결과를 반환할 수 있고 예외가 암시적으로 전달되므로 더 깔끔해졌습니다.

스타일의 차이를 보여주기 위해 거기에서 몇 줄을 인용하겠습니다.

코드에 사용된 fsp 개체에는 Promise.denodeify를 사용하여 래핑된 약속이 있는 fs 함수의 변형이 포함되어 있습니다. 코드 및 본문 속성과 함께 메서드 핸들러에서 반환된 개체는 약속 체인의 최종 결과가 되며 클라이언트에 보낼 응답을 결정하는 데 사용됩니다.

Methods.GET = function(path) ( return InspectionPath(path).then(function(stats) ( if (!stats) // 존재하지 않음 return (코드: 404, 본문: "파일을 찾을 수 없음"); else if ( stats.isDirectory()) return fsp.readdir(path).then(function(files) ( return (code: 200, body: files.join("\n")); )) else return (코드: 200, 유형: require("mime").lookup(path), body: fs.createReadStream(path)); function informPath(path) ( return fsp.stat(path).then(null, function(error) ( if (error.code == "ENOENT") return null; else throw error; )); )

InspectionPath 함수는 파일을 찾을 수 없는 경우를 처리하는 fs.stat 주위의 간단한 래퍼입니다. 이 경우 오류를 null을 반환하는 성공으로 대체합니다. 다른 모든 오류는 전송될 수 있습니다. 이러한 핸들러에서 반환된 Promise가 중단되면 서버는 코드 500으로 응답합니다.

결론

Node는 브라우저 외부에서 JavaScript를 실행할 수 있는 훌륭하고 간단한 시스템입니다. 원래는 네트워크를 통해 작동하고 네트워크에서 노드 역할을 하도록 설계되었습니다. 하지만 이를 통해 많은 일을 할 수 있으며, JavaScript로 프로그래밍하는 것을 좋아한다면 Node로 일상적인 작업을 자동화하는 것이 훌륭하게 작동합니다.

NPM은 여러분이 생각할 수 있는 모든 것(심지어 그렇지 않은 것까지)에 대한 라이브러리를 제공하며 간단한 명령으로 다운로드하고 설치할 수 있습니다. Node에는 파일 시스템 작업을 위한 "fs"와 HTTP 서버 실행 및 HTTP 요청을 위한 "http"를 포함한 내장 모듈 세트도 함께 제공됩니다.

fs.readFileSync와 같은 함수의 명시적인 동기 변형을 사용하지 않는 한 Node의 모든 입력 및 출력은 비동기식으로 수행됩니다. 콜백 함수를 제공하고 노드는 I/O 작업이 완료될 때 적절한 시간에 이를 호출합니다.

수업 과정

그리고 다시 내용에 동의합니다.
17장에서 첫 번째 연습은 다양한 Accept 헤더를 전달하여 다양한 유형의 콘텐츠를 요청하는 eloquentjavascript.net/author에 대한 요청을 만드는 것이었습니다.

Node의 http.request 함수를 사용하여 다시 수행하세요. 최소한 text/plain, text/html 및 application/json 유형을 요청하세요. 요청 헤더는 http.request의 첫 번째 인수인 headers 속성의 객체로 전달될 수 있다는 점을 기억하세요.

각 응답의 내용을 인쇄합니다.

누출 수리

파일에 대한 액세스를 단순화하기 위해 내 컴퓨터의 /home/marijn/public 디렉토리에 실행 중인 서버를 남겨 두었습니다. 어느 날 나는 누군가가 내가 브라우저에 저장한 모든 비밀번호에 접근하고 있다는 사실을 발견했습니다. 무슨 일이 일어났나요?

이것이 명확하지 않다면 다음과 같이 정의된 urlToPath 함수를 기억하십시오.

함수 urlToPath(url) ( var path = require("url").parse(url).pathname; return "." + decodeURIComponent(path); )

이제 "fs" 함수에 전달된 경로는 상대적일 수 있다는 점을 기억하세요. 여기에는 최상위 디렉터리에 대한 경로 "../"가 포함될 수 있습니다. 클라이언트가 다음과 같은 URL로 요청을 보내면 어떻게 되나요?

내 호스트 이름 :8000/../.config/config/google-chrome/Default/Web%20Data
내호스트 이름 :8000/../.ssh/id_dsa
내 호스트 이름 :8000/../../../etc/passwd

이 문제를 해결하려면 urlToPath 함수를 변경하세요. Windows Node에서는 정방향 슬래시와 백슬래시를 모두 사용하여 경로를 지정할 수 있습니다.

또한, 일단 조잡한 시스템을 인터넷에 노출하면 시스템의 버그가 귀하와 귀하의 컴퓨터에 불리하게 사용될 수 있다는 사실을 묵상하십시오.

디렉토리 생성
DELETE 메소드는 fs.rmdir을 통해 디렉토리를 삭제할 때도 작동하지만 서버는 아직 디렉토리를 생성하는 기능을 제공하지 않습니다.

fs.mkdir을 통해 디렉터리를 생성해야 하는 MKCOL 메서드에 대한 지원을 추가합니다. MKCOL은 핵심 HTTP 방법은 아니지만 WebDAV 표준에는 바로 그 목적을 위해 존재합니다. 여기에는 리소스를 읽는 것이 아니라 쓰는 데 사용할 수 있도록 HTTP에 대한 확장이 포함되어 있습니다.

웹상의 공개 장소
파일 서버는 모든 파일을 제공하고 올바른 Content-Type 헤더를 반환하므로 웹 사이트를 제공하는 데 사용될 수 있습니다. 누구나 파일을 삭제하고 교체할 수 있으므로 이는 흥미로운 사이트가 될 것입니다. 유효한 HTTP 요청을 생성할 수 있는 사람은 누구나 수정, 손상 및 삭제할 수 있습니다. 그러나 그것은 여전히 ​​웹사이트일 것이다.

간단한 JavaScript 파일로 간단한 HTML 페이지를 작성합니다. 서버가 제공하는 디렉토리에 배치하고 브라우저에서 엽니다.

그런 다음 고급 연습으로 책에서 배운 모든 내용을 결합하여 사이트 자체 내에서 웹 사이트를 수정하기 위한 보다 사용자 친화적인 인터페이스를 구축합니다.

HTML 양식(18장)을 사용하여 사이트를 구성하는 파일을 편집하면 17장에 설명된 대로 사용자가 HTTP 요청을 통해 서버에서 해당 파일을 업데이트할 수 있습니다.

편집할 수 있는 하나의 파일로 시작하세요. 그런 다음 편집할 파일을 선택할 수 있도록 만듭니다. 디렉터리에서 요청할 때 파일 서버가 파일 목록을 반환한다는 사실을 활용하세요.

파일 서버 코드에서 직접 파일을 변경하지 마십시오. 실수를 하면 해당 파일이 손상될 가능성이 높습니다. 외부에서 접근이 불가능한 디렉터리에서 작업하고, 테스트 후 복사해 두세요.

컴퓨터가 방화벽, 라우터 또는 기타 장치 없이 인터넷에 직접 연결되어 있으면 친구를 사이트에 초대할 수 있습니다. 확인하려면 whatismyip.com으로 이동하여 주소 표시줄에 IP 주소를 복사하고 8000을 추가하여 원하는 포트를 선택하세요. 귀하가 귀하의 사이트에 있다면 모든 사람이 볼 수 있습니다.

공유하다