nodeJS 입문 예 1 - 모듈 (Modules)

18961 단어
모듈 (모듈)
        주기 (사이클)
        핵심 모듈 (코어 모듈)
       파일 모듈 (파일 모듈)
       노드 모듈 (node modules) 폴 더 에서 추가
        모듈
        캐 시 (캐 시)
           모듈 캐 시 설명
        module.exports
        module.require
        기타...
       전역 폴 더 에서 불 러 오기
       액세스 메 인 모듈
    부록: 패키지 관리 기술
모듈 (모듈)
Node 에는 간단 한 모듈 로드 시스템 이 있 습 니 다. Node 에 서 는 파일 과 모듈 inone - to - one 이 있 습 니 다.  통신. 다음 예, foo. js 는 같은 디 렉 터 리 에 모듈 circle. js 를 불 러 옵 니 다.
  foo.js 내용 은 다음 과 같다.
var circle = require('./circle.js');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));
circle.js 내용 은 다음 과 같다.
var PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

  circle.js area()circumference(). 출력 대상 에 상세 한 출력 대상 exports object 를 추가 합 니 다.
모듈 의 부분 변 수 는 개인 입 니 다. 이 예 에서 PI 는 circle. js 개인 입 니 다.
사이클 (주기)
서로 불 러 올 때, 당기 반환 시 모듈 이 실행 되 지 않 을 수도 있 습 니 다
이런 상황 을 고려 하 다.a.js :
console.log('a starting');
exports.done = false;
var b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js :
console.log('b starting');
exports.done = false;
var a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js :
console.log('main starting');
var a = require('./a.js');
var b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);  main.js  a.js ,a.js  b.js,  b.js    a.js。                 b.js a.js     。 b.js    ,           a.js   

이 때 main. js 에서 두 모듈 을 불 러 옵 니 다. 출력 은 다음 과 같 습 니 다.
$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true                         

Core Modules (核心模块)

Node有几个编译成二进制的模块。这些模块在NODE文档中有详尽的描述。

核心模块的定义在node的源码文件夹lib/文件夹中。


如果require()鉴定通过,核心模块将优先加载。例如,require("http")将总是返回建立的http模块,即使有一个文件的名字


File Modules (文件模块)

如果执行的文件名没有找到,node将尝试加载请求后缀为.js、.json和.node    文件名相同的文件。.js文件解析成JavaScript的文本文件,

.json文件解析成JSON文本文件,.node文件解析成用dlopen加载的编译的附加模块

模块前缀为"/"是一个文件的绝对路径。如:require('/home/marco/foo.js')将加载在/home/marco/foo.js下的文件。

模块前缀为“./”是一个调用require()加载的文件的相对路径。也就是说,用require('./circle')加载时找到此文件,circle.js必须要和foo.js在同一目录下面。

没有'/'或者'./'前缀表示文件时,模块是核心模块或者是从node_modules文件夹里加载。


从`node_modules`文件夹中加载

如果通过require()标识模块不是本地模块,并且没有以'/'、'../'或者'./'开头,node从当前模块的父目录开始,添加/node_modules,并尝试从本地加载模块。

如果没有在这里找到,将会从父文件夹查找,直到达到最顶层文件夹。

例如,如果 '/home/ry/projects/foo.js'调用require('bar.js'),node将以以下本地路径查找,顺序如下:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

这允许程序设置依赖的本地化,所以不会引起冲突。


文件夹作为模块(Folders as Modules )

这非常方便地组织程序和libraries    到一个独立的目录下,并且对library提供一个简单的入口点。在某个文件夹有三种方式作为参数传递给require()。

第一种在文件夹的根路径下(在main 模块中申明描述的)创建一个package.json文件。一个package.json文件的例子如下:


{ "name" : "some-library",
  "main" : "./lib/some-library.js" }      ./some-libraryrequire('./some-library')./some-library/lib/some-library.js。   package.json   Node    。         package.json  ,node           index.js  index.node  。  :      package.json  ,    require('./some-library')      
  • ./some-library/index.js
  • ./some-library/index.node

  • 캐 시 (캐 시)
    처음 불 러 올 때 모듈 은 캐 시 됩 니 다. 같은 파일 에서 호출 require('foo') 할 때마다 같은 대상 을 정확하게 가 져 옵 니 다.
    여러 번 require ("foo") 를 호출 하면 여러 번 호출 되 지 않 을 수 있 습 니 다. 이것 은 매우 중요 한 특징 입 니 다. 따라서 일부 완성 대상 은 되 돌아 갈 수 있 기 때문에 즉시 상호 조정 할 때 로드 에 의 해 전달 할 수 있 습 니 다.
    모듈 코드 를 여러 번 호출 하려 면 외부 (export) 함수 가 필요 하고 이 함 수 를 호출 해 야 합 니 다.
    모듈 캐 시 설명 (Module Caching Caveats)
    모듈 의 캐 시 는 결 정 된 파일 이름 을 기반 으로 합 니 다. 모듈 은 호출 모듈 로 컬 분석 을 기반 으로 서로 다른 파일 이름 (node modules 폴 더 에서 불 러 오기) 을 사용 할 수 있 기 때 문 입 니 다. 서로 다른 파일 을 분석 하면 require ("foo") 가 항상 정확 하고 같은 이미 지 를 되 돌려 줄 것 이 라 고 보장 하지 않 습 니 다.
    모듈 외부 인터페이스 (module. exports)
    exports 대상 은 시스템 모듈 을 통 해 만 들 어 졌 습 니 다. 때때로 이것 은 요구 에 부합 되 지 않 습 니 다. 많은 경우 클래스 의 실체 가 필요 합 니 다. 이 분 배 를 위해 module. exports 의 export 대상 을 설명 합 니 다. 예 를 들 어 a. js 라 는 모듈 (module) 을 만 듭 니 다.
    var EventEmitter = require('events').EventEmitter;
    
    module.exports = new EventEmitter();
    
    //              'ready'  。
    setTimeout(function() {
      module.exports.emit('ready');
    }, 1000);         ,     : 
    var a = require('./a');
    a.on('ready', function() {
      console.log('module a is ready');
    });     module.exports      。            。       : 

    x.js:

    setTimeout(function() {
      module.exports = { a: "hello" };
    }, 0);

    y.js:

    var x = require('./x');
    console.log(x.a);

    module.require 

    module.require , module require()。

    , module 。require() exports,module , (export)。


    require() , , require.resolve() 。

    , (high-level) (pseudocode) (algorithmin )。



    require(X) from module at path Y
       Y       X
    1、  X     
       a.      。
       b.  
    
    2、  X './'    '/'    '../'  。
       a.      (LOAD_AS_FILE(Y + X)) 
       b.      (LOAD_AS_DIRECTORY(Y + X))
    3、      (LOAD_NODE_MODULE(X, dirname(Y)))
    4、       "not found"。
    
    
           LOAD_AS_FILE(X) 1、  X     , JavaScript    X。   2、  X.js     , JavaScript    X。
    3、  X.node     ,        X.node。  
    
    
            LOAD_AS_DIRECTORY(X) 1、  X/package.json     , a.  X/package.json,      ('main' field) b.   M = X + json  (json main field) c.     M 2、  X/index.js     ,   JavaScript    X/inde.js。  。 3、  X/index.node     ,           ,  。 
    
           LOAD_NODE_MODULES(X, START) 1、  DIRS = NODE_MODULES_PATHS(START)。 2、           a.    (DIR/X) LOAD_AS_FILE(DIR/X) b.    (DIR/X) LOAD_DIRECTORY(DIR/X)  NODE_MODULES_PATHS(START) 1、  PARTS = path split(START) 2、  ROOT = PARTS ‘node_modules’         。
    3、  I = PARTS - 1
    4、  DIRS = []
    5、while I > ROOT
    a.   PARTS[I] = "node_modules" CONTINUE
    c.DIR = (PARTS[0...I]+ 'node_modules'     )
    b.DIRS = DIRS + DIR
    c.  I = I - 1 1. let PARTS = path split(START)
    6、  DIRS
    
    

    전역 폴 더 에서 Loading from the global folders 불 러 오기
    NODE PATH 환경 변 수 를 콜론 - delimited (colon - delimited) 의 절대 경로 집합 으로 설정 하면 아무 곳 에서 도 찾 지 못 하면 node 는 모듈 에서 이 디 렉 터 리 를 찾 습 니 다.
    (메모: Windows 에서 NODE PATH 분할 은 콜론 대신 분점 으로)
    또한, node 는 위 치 를 검색 합 니 다:
    1. $HOME/.node_modules
    2. $HOME/.node_libraries
    3. $PREFIX/lib/node
    $HOME 는 사용자 홈 디 렉 터 리 이 고 $PREFIX 는 노드 설정 의 설치 접두사 (installPrefix) 입 니 다.
    역사적 인 의미 가 있 습 니 다. 의존 파일 이나 가방 을 node_modules 폴 더 에 두 는 것 을 권장 합 니 다. 빠르게 불 러 오고 신뢰 할 수 있 습 니 다.
    액세스 메 인 모듈  Accessing the main module
    파일 이 node 에서 직접 실 행 될 때 require. main 은 module 에 만 도착 합 니 다. 테스트 할 때 파일 이 직접 실 행 됐 는 지 여 부 를 결정 할 수 있 습 니 다.
    require.main === module
    파일 foo. js 에 대해 node foo. js 를 실행 하면 true 입 니 다. 그러나 require ('/ foo') 를 통 해 실 행 될 때 false 입 니 다. module 은 파일 이름 속성 (일반적인 경우 filename 과 같 음) 을 제공 하기 때문에 현재 응용 입구 점 은 require. main. filename 검 사 를 통 해 얻 을 수 있 습 니 다.
    부록: 패키지 관리 기술 (Package Manager Tips)
    노드 의 의미 require () 함 수 는 일반적으로 건전 한 디 렉 터 리 구 조 를 지원 할 수 있 도록 설계 되 었 습 니 다. 패키지 관리 프로그램 (Package manager), 예 를 들 어 dpkg, rpm, npm 는 node 모듈 에서 로 컬 패 키 지 를 수정 하지 않 아 도 됩 니 다.
    다음은 디 렉 터 리 구조 에 대한 조언 입 니 다.
    / usr / node / < some - package > / < some - version > 디 렉 터 리 아래 에 가방 의 상세 한 버 전 설명 을 설치 합 니 다.
    가방 은 다른 것 을 가 져 올 수 있 습 니 다. foo 가방 을 불 러 오기 위해 서 는 가방 bar 의 버 전 설명 을 불 러 와 야 합 니 다. 가방 bar 는 의존 도가 있 습 니 다. 어떤 경우 에는 의존 가방 이 충돌 하거나 서로 순환 할 수 있 습 니 다. node 는 모든 모듈 이 불 러 오 는 실제 경 로 를 찾 고 node modules 폴 더 에서 위의 설명 에 따라 의존 가방 을 찾 아 아래 구조 로 디자인 하기 때 문 입 니 다.쉽게 해결 할 수 있 는 문제:
  • /usr/lib/node/foo/1.2.3/ - foo 가방 의 상세 내용, 버 전 1.2.3.
  • /usr/lib/node/bar/4.3.2/ - foo 가 의존 하 는 bar 에 대한 상세 한 설명
  • /usr/lib/node/foo/1.2.3/node_modules/bar - 상징 연결 /usr/lib/node/bar/4.3.2/.
  • /usr/lib/node/bar/4.3.2/node_modules/* - bar 의존의 상징 으로 연 결 된 가방
  • 따라서 순환 이 서로 바 뀌 거나 가방 에 의존 하 는 충돌 이 발생 하 더 라 도 각 모듈 은 가방 에 의존 하 는 버 전 을 제공 할 수 있 습 니 다.
    foo 패키지 의 코드 는 requiret ("bar") 를 사용 하여 버 전 을 / usr / lib / node / foo / 1.2.3 / node modules / bar 에 연결 합 니 다. 그리고 bar 패키지 의 코드 에서 reuire ('quux) 를 호출 하여 버 전 을 / usr / lib / node / bar / 4.3.2 / node module / quux 에 연결 합 니 다.
    또한, 모듈 에서 프로 세 스 를 가장 잘 검사 하기 위해 서 는 가방 을 / usr / lib / node 에 직접 놓 는 것 이 아니 라 / usr / lib / node moduls / < name > / < version > 에 놓 을 수 있 습 니 다. node 는 더 이상 / usr / node modules 또는 / node modules 를 찾 지 않 습 니 다. 부족 한 의존 가방 을 찾 습 니 다.
    모듈 대 nod  REPL 을 사용 할 수 있 습 니 다. / usr / lib / node modules 폴 더 를 $NODE PATH 의 환경 변수 에 설정 하면 유용 할 수 있 습 니 다. 모듈 검사 에 사용 되 는 node mudules 폴 더 는 상대 경로 이기 때 문 입 니 다.
    또한 실제 경 로 를 기반 으로 한 파일 호출 require () 이기 때문에 가방 은 어디 에 나 있 을 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기