CoffeeScriptを使用してNodeを記述する.jsモジュール


Node.jsはJavaScriptに基づいてアプリケーションを作成し、JavaScriptは私の主な開発言語です.CoffeeScriptは、JavaScriptにコンパイルされたプログラミング言語です.なぜCoffeeScriptで再利用可能なコード--モジュールを書くのでしょうか.CoffeeScriptは非常に高度な言語で、JavaScript、Ruby、Pythonの中で私の大好きな部分を結合しています.このチュートリアルでは、CoffeeScriptをNodeに使用する方法を説明します.jsは多重化可能なオープンソースモジュールを作成します.最近、プレイリスト解析モジュールを作成するときにこの新しいスキルをgetしました.ポイントは、迅速な開発を構造の良いノードにする方法です.jsモジュール.
手順は次のとおりです.
  • はgit倉庫にアイデアを入れます.
  • ディレクトリ構造を追加します.
  • ライブラリ関数をテストから分離します.
  • 構築スクリプトを追加します.
  • nodeモジュールを作成します.
  • LICENSEとREADMEを追加します.
  • リリース.

  • まず、アイデアが必要です.それほど革命的なアイデアではありませんそれはただ一つのことをして、それをよくするだけです.これはUNIXが議論されている哲学の最初の準則であり、Node.jsコミュニティは共感を呼んだ.私が開発したとき、私は単一のファイルから始めて、いくつかの探求を行いました.そして私は多重化可能なものを作るまでコードを漸進的に改良しました.このようにして、私たちはそれを多重化することができて、他の人もそれを多重化することができて、他の人もコードから啓発することができて、世界はそのためもっとすばらしいことができます.
    このチュートリアルでは、nanomsgのバインドを作成する方法について説明します.nanomsgはZeroMQの創造者MartinSústrikが最新に開発した伸張性プロトコルライブラリである.私は以前ZeroMQで遊んだことがありますが、とても素晴らしいと思います.ZeroMQの著者がCベースの新しいライブラリを作ったのを見て、私はとても興奮しました.私は彼のブログ「なぜC++ではなくCでZeroMQを書くべきなのか」が大好きです.
    素早く手に入れるために、まずnodeのバージョンが十分に新しいことを確認します.私はnvmと最新の安定minor版node(バージョンフォーマットはmajor.minor.patch、安定版のminor数字は偶数なのでv0.11.0は非安定版)を使うのが好きです.
    node -v
    -> v0.10.17
    

    次に、動的にリンクするライブラリをダウンロードする必要があります.
    curl -O http://download.nanomsg.org/nanomsg-0.1-alpha.zip && \
    unzip nanomsg-0.1-alpha.zip && \
    cd nanomsg-0.1-alpha && \
    mkdir build && \
    cd build && \
    ../configure && \
    make && \
    make install
    

    ダイナミックリンクライブラリと対話するためにnodeのFFIモジュールを使用します.バインディングを記述する場合、これはオリジナル拡張を使用するよりも容易であり、V 8のAPIの最近の修正はオリジナル拡張にいくつかの面倒をもたらした.
    npm install ffi
    

    CoffeeScriptを使用してコードを記述します.
    npm install -g coffee-script
    

    C++バインドサンプルに基づいてmain.coffeeを作成します.
    ffi = require 'ffi'
    assert = require 'assert'
    
    AF_SP = 1
    NN_PAIR = 16
    
    nanomsg = ffi.Library 'libnanomsg',
      nn_socket: [ 'int', [ 'int', 'int' ]]
      nn_bind: [ 'int', [ 'int', 'string' ]]
      nn_connect: [ 'int', ['int', 'string' ]]
      nn_send: [ 'int', ['int', 'pointer', 'int', 'int']]
      nn_recv: [ 'int', ['int', 'pointer', 'int', 'int']]
      nn_errno: [ 'int', []]
    
    # test
    s1 = nanomsg.nn_socket AF_SP, NN_PAIR
    assert s1 >= 0, 's1: ' + nanomsg.nn_errno()
    
    ret = nanomsg.nn_bind s1, 'inproc://a'
    assert ret > 0, 'bind'
    
    s2 = nanomsg.nn_socket AF_SP, NN_PAIR
    assert s2 >= 0, 's2: ' + nanomsg.nn_errno()
    
    ret = nanomsg.nn_connect s2, 'inproc://a'
    assert ret > 0, 'connect'
    
    msg = new Buffer 'hello'
    ret = nanomsg.nn_send s2, msg, msg.length, 0
    assert ret > 0, 'send'
    
    recv = new Buffer msg.length
    ret = nanomsg.nn_recv s1, recv, recv.length, 0
    assert ret > 0, 'recv'
    
    console.log recv.toString()
    assert msg.toString() is recv.toString(), 'received message did not match sent'
    
    coffee main.coffee
    -> hello
    

    この迅速に作成された例は、私たちがすでにいくつかのことをすることができることを示しています.現在、ディレクトリ構造は次のとおりです.
    tree -L 2
    .
    ├── main.coffee
    └── node_modules
        └── ffi
    
    2 directories, 1 file
    

    アイデアをgit倉庫に変更
    次にgitを使用して倉庫を作成し、私たちの仕事を保存し始めました.より早く提出し、より多く提出します..gitignoreファイルを追加して、提出する必要のないファイルがgit倉庫に追加されないようにしましょう.node_modulesフォルダはコミットする必要はありません.nodeモジュールがインストールされると、その依存性が再帰的にインストールされるため、ソースコード管理システムにコミットする必要はありません.私はvimを使用しているので、vimの交換ファイルを排除する必要があります.
    node_modules/
    *.swp
    

    ではgit倉庫を作成しましょう.
    git init && \
    git add . && \
    git commit -am "initial commit"
    

    githubに初期化されていない倉庫を作成し、プッシュします.
    git remote add origin [email protected]:nickdesaulniers/node-nanomsg.git && \
    git push -u origin master
    

    ディレクトリ構造は次のとおりです.
    tree -L 2 -a
    .
    ├── .gitignore
    ├── main.coffee
    └── node_modules
        └── ffi
    
    2 directories, 2 files
    

    ディレクトリ構造の追加
    私のコードがgitの下にある以上、ディレクトリ構造の追加を始めましょう.src/lib/test/ディレクトリを作成する必要があります.src/は私たちのCoffeeScriptを配置し、lib/はコンパイルされたJavaScriptファイルを配置し、私たちのテストコードはtest/になります.
    mkdir src lib test
    

    テストからライブラリ関数を分離main.coffeesrc/に移動し、そのコピーをtest/に移動します.テストロジックからライブラリ関数を分離します.
    cp main.coffee test/test.coffee && \
    git add test/test.coffee && \
    git mv main.coffee src/nanomsg.coffee
    
    git statusは次のことを示しています.
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    # renamed:    main.coffee -> src/nanomsg.coffee
    # new file:   test/test.coffee
    #
    
    src/main.coffeeを変更しましょう.
    ffi = require 'ffi'
    
    exports = module.exports = ffi.Library 'libnanomsg',
      nn_socket: [ 'int', [ 'int', 'int' ]]
      nn_bind: [ 'int', [ 'int', 'string' ]]
      nn_connect: [ 'int', ['int', 'string' ]]
      nn_send: [ 'int', ['int', 'pointer', 'int', 'int']]
      nn_recv: [ 'int', ['int', 'pointer', 'int', 'int']]
      nn_errno: [ 'int', []]
    
    exports.AF_SP = 1
    exports.NN_PAIR = 16
    

    テストを修正します.
    assert = require 'assert'
    nanomsg = require '../lib/nanomsg.js'
    
    { AF_SP, NN_PAIR } = nanomsg
    
    s1 = nanomsg.nn_socket AF_SP, NN_PAIR
    assert s1 >= 0, 's1: ' + nanomsg.nn_errno()
    
    ret = nanomsg.nn_bind s1, 'inproc://a'
    assert ret > 0, 'bind'
    
    s2 = nanomsg.nn_socket AF_SP, NN_PAIR
    assert s2 >= 0, 's2: ' + nanomsg.nn_errno()
    
    ret = nanomsg.nn_connect s2, 'inproc://a'
    assert ret > 0, 'connect'
    
    msg = new Buffer 'hello'
    ret = nanomsg.nn_send s2, msg, msg.length, 0
    assert ret > 0, 'send'
    
    recv = new Buffer msg.length
    ret = nanomsg.nn_recv s1, recv, recv.length, 0
    assert ret > 0, 'recv'
    
    assert msg.toString() is recv.toString(), 'received message did not match sent'
    
    testにはまだ存在しないlib/のJavaScriptファイルが含まれていることに気づきましたか?coffee test/test.coffeeを実行しようとすると、クラッシュします.まずコンパイルしましょう.coffee -o lib -c src/nanomsg.coffee
    コンパイルが完了したら、coffee test/test.coffeeを使用してテストを実行します.
    今提出しましょう.lib/をバージョン管理に追加しないでください.なぜか説明します.
    tree -L 2 -C -a -I '.git'
    .
    ├── .gitignore
    ├── lib
    │   └── nanomsg.js
    ├── node_modules
    │   └── ffi
    ├── src
    │   └── nanomsg.coffee
    └── test
        └── test.coffee
    
    5 directories, 4 files
    

    現在のところ、プロパティを追加してテストを実行する場合は、次の手順に従います.
    coffee -o lib -c src/nanomsg.coffee && coffee test/test.coffee
    

    このコマンドは簡単で理解しにくいわけではありませんが、テストを実行するには、プロジェクトに貢献するコードを知っている人は、このコマンドを知る必要があります.Grunt、JavaScriptタスク自動化ツールを使用して、構築とテストプロセスを自動化します.
    コンストラクションスクリプトの追加
    npm install -g grunt-cli && \
    npm install grunt-contrib-coffee
    

    CoffeeScriptを使用して簡単なGruntfileを作成します.
    module.exports = (grunt) ->
      grunt.initConfig
        coffee:
          compile:
            files:
              'lib/nanomsg.js': ['src/*.coffee']
      grunt.loadNpmTasks 'grunt-contrib-coffee'
      grunt.registerTask 'default', ['coffee']
    
    gruntを実行すると、ライブラリが作成されます.コミットしましょう.
    しかし、gruntは私たちのテストを実行しません.私たちのテストの出力もよくありません.この点を変えましょう
    npm install -g mocha && \
    npm install chai grunt-mocha-test
    

    編集test/test.coffee:
    assert = require 'assert'
    should = require('chai').should()
    nanomsg = require '../lib/nanomsg.js'
    
    describe 'nanomsg', ->
      it 'should at least work', ->
        { AF_SP, NN_PAIR } = nanomsg
    
        s1 = nanomsg.nn_socket AF_SP, NN_PAIR
        s1.should.be.at.least 0
    
        ret = nanomsg.nn_bind s1, 'inproc://a'
        ret.should.be.above 0
    
        s2 = nanomsg.nn_socket AF_SP, NN_PAIR
        s2.should.be.at.least 0
    
        ret = nanomsg.nn_connect s2, 'inproc://a'
        ret.should.be.above 0
    
        msg = new Buffer 'hello'
        ret = nanomsg.nn_send s2, msg, msg.length, 0
        ret.should.be.above 0
    
        recv = new Buffer msg.length
        ret = nanomsg.nn_recv s1, recv, recv.length, 0
        ret.should.be.above 0
    
        msg.toString().should.equal recv.toString()
    

    その後、gruntfileを編集し、テスト手順に参加します.
    module.exports = (grunt) ->
      grunt.initConfig
        coffee:
          compile:
            files:
              'lib/nanomsg.js': ['src/*.coffee']
        mochaTest:
          options:
            reporter: 'nyan'
          src: ['test/test.coffee']
    
      grunt.loadNpmTasks 'grunt-contrib-coffee'
      grunt.loadNpmTasks 'grunt-mocha-test'
    
      grunt.registerTask 'default', ['coffee', 'mochaTest']
    

    今、gruntを実行すると、私たちのプログラムを構築し、テストを実行し、楽しくて死んだ虹の猫を見ることができます.虹の猫mochaテストの報告は、人間の心が達成できる最高の成果ではない.
    grunt
    Running "coffee:compile" (coffee) task
    File lib/nanomsg.js created.
    
    Running "mochaTest:src" (mochaTest) task
     1   -__,------,
     0   -__|  /\_/\
     0   -_~|_( ^ .^)
         -_ ""  ""
    
      1 passing (5 ms)
    
    
    Done, without errors.
    

    また提出の時が来た.
    tree -L 2 -C -a -I '.git'
    .
    ├── .gitignore
    ├── Gruntfile.coffee
    ├── lib
    │   └── nanomsg.js
    ├── node_modules
    │   ├── ffi
    │   ├── grunt
    │   └── grunt-contrib-coffee
    ├── src
    │   └── nanomsg.coffee
    └── test
        └── test.coffee
    
    7 directories, 5 files
    

    nodeモジュールの作成
    現在、私たちの設計はモジュール化されており、構築とテストの論理が内蔵されています.このモジュールを再配布しやすくしましょう.まず、無視したファイルについて議論します.ダウンロードに含まれないファイルを指定する.npmignoreファイルを作成します.ノードパッケージマネージャ、npm、デフォルトではファイルのセットは無視されます.
    Gruntfile.coffee
    src/
    test/
    

    デフォルトではsrc/ディレクトリは無視され、私たちの.gitignoreではlib/は無視されます.
    node_modules/
    lib/
    *.swp
    

    どうしてそうなの?正直に言うと、厳密な意味では、この2つのディレクトリを無視する必要はありません.しかし、これは役に立つと思います.誰かがコードを取得したとき、彼はコンパイルの結果を必要としません.結局、彼らは修正することができますが、これは再コンパイルする必要があります.lib/nanomsg.jsを追加すると、ダウンロードしたファイルが追加されます(もちろん、そのサイズは相対的に重要ではありません).同様に、モジュールをダウンロードする人がいる場合、ソースコード、構築スクリプト、テストではなく、コンパイルしたファイルだけを望んでいます.コンパイルされたJavaScriptにブラウザでアクセスしたい場合は、.gitignorelib/を含まない可能性があります.githubのraw URLで参照できます.もちろん、これらは一般的な経験にすぎず、必ずしも正しいわけではありません.モジュール全体にコードを入れないという欠点を補うために、manifestに倉庫へのリンクを追加します.しかし、その前に、先に提出しましょう.
    これはmanifestファイルを作成するときで、私たちのアプリケーションの基本的な情報が含まれています.npm search を使用して、使用するパッケージ名が利用可能かどうかを確認するのは良い注意です.すべての依存関係がインストールされているので、npm initを実行しましょう.
    This utility will walk you through creating a package.json file.
    It only covers the most common items, and tries to guess sane defaults.
    
    See `npm help json` for definitive documentation on these fields
    and exactly what they do.
    
    Use `npm install  --save` afterwards to install a package and
    save it as a dependency in the package.json file.
    
    Press ^C at any time to quit.
    name: (nanomsg)
    version: (0.0.0)
    description: nanomsg bindings
    entry point: (index.js) lib/nanomsg.js
    test command: grunt
    git repository: (git://github.com/nickdesaulniers/node-nanomsg.git)
    keywords: nanomsg
    author: Nick Desaulniers
    license: (BSD-2-Clause) Beerware
    About to write to /Users/Nicholas/code/c/nanomsg/package.json:
    
    {
      "name": "nanomsg",
      "version": "0.0.0",
      "description": "nanomsg bindings",
      "main": "lib/nanomsg.js",
      "directories": {
        "test": "test"
      },
      "dependencies": {
        "chai": "~1.7.2",
        "ffi": "~1.2.5",
        "grunt": "~0.4.1",
        "grunt-mocha-test": "~0.6.3",
        "grunt-contrib-coffee": "~0.7.0"
      },
      "devDependencies": {},
      "scripts": {
        "test": "grunt"
      },
      "repository": {
        "type": "git",
        "url": "git://github.com/nickdesaulniers/node-nanomsg.git"
      },
      "keywords": [
        "nanomsg"
      ],
      "author": "Nick Desaulniers",
      "license": "Beerware",
      "bugs": {
        "url": "https://github.com/nickdesaulniers/node-nanomsg/issues"
      }
    }
    
    
    Is this ok? (yes)
    

    これにより、npmにpackage.json manifestが作成されます.
    現在、gruntを使用するほか、npm testを使用してテストを実行することもできます.モジュールをパブリッシュする前に、コミットしてください.
    tree -L 2 -C -a -I '.git'
    .
    ├── .gitignore
    ├── .npmignore
    ├── Gruntfile.coffee
    ├── lib
    │   └── nanomsg.js
    ├── node_modules
    │   ├── .bin
    │   ├── chai
    │   ├── ffi
    │   ├── grunt
    │   ├── grunt-contrib-coffee
    │   └── grunt-mocha-test
    ├── package.json
    ├── src
    │   └── nanomsg.coffee
    └── test
        └── test.coffee
    
    10 directories, 7 files
    

    LICENSEとREADMEの追加
    今、私たちはもう完成したところです.しかし、開発者はどのようにこれらのコードを多重化すべきかを知っていますか?どんなにソースコードを直接表示するのが好きでも、npmは私たちのモジュールにreadmeファイルがないと文句を言います.そしてreadmeがあればgithub倉庫の方がきれいです.
    # Node-NanoMSG
    Node.js binding for [nanomsg](http://nanomsg.org/index.html).
    
    ## Usage
    
    `npm install nanomsg`
    
    ```javascript
    var nanomsg = require('nanomsg');
    var assert = require('assert');
    var AF_SP = nanomsg.AF_SP;
    var NN_PAIR = nanomsg.NN_PAIR;
    var msg = new Buffer('hello');
    var recv = new Buffer(msg.length);
    var s1, s2, ret;
    
    s1 = nanomsg.nn_socket(AF_SP, NN_PAIR);
    assert(s1 >= 0, 's1: ' + nanomsg.errno());
    
    ret = nanomsg.nn_bind(s1, 'inproc://a');
    assert(ret > 0, 'bind');
    
    s2 = nanomsg.nn_socket(AF_SP, NN_PAIR);
    assert(s2 >= 0, 's2: ' + nanomsg.errno());
    
    ret = nanomsg.nn_connect(s2, 'inproc://a');
    assert(ret > 0, 'connect');
    
    ret = nanomsg.nn_send(s2, msg, msg.length, 0);
    assert(ret > 0, 'send');
    
    ret = nanomsg.recv(s1, recv, recv.length, 0);
    assert(ret > 0, 'recv');
    
    assert(msg.toString() === recv.toString(), "didn't receive sent message");
    console.log(recv.toString());
    

    リリース前に、ライセンスファイルを作成する必要があります.コードを公開するため、ライセンスが明確でない公開コードは著作権保護の下にあり、多重化できません.
    /*
     * ----------------------------------------------------------------------------
     * "THE BEER-WARE LICENSE" (Revision 42):
     *  wrote this file. As long as you retain this notice you
     * can do whatever you want with this stuff. If we meet some day, and you think
     * this stuff is worth it, you can buy me a beer in return. Nick Desaulniers
     * ----------------------------------------------------------------------------
     */
     ```
    
             ,     MIT BSD     ,                。     ,    GPL     。[TLDRLegal](http://www.tldrlegal.com/)               。
    
    ```sh
    tree -L 2 -C -a -I '.git'
    .
    ├── .gitignore
    ├── .npmignore
    ├── Gruntfile.coffee
    ├── LICENSE
    ├── README.md
    ├── lib
    │   └── nanomsg.js
    ├── node_modules
    │   ├── .bin
    │   ├── chai
    │   ├── ffi
    │   ├── grunt
    │   ├── grunt-contrib-coffee
    │   └── grunt-mocha-test
    ├── package.json
    ├── src
    │   └── nanomsg.coffee
    └── test
        └── test.coffee
    
    10 directories, 9 files
    

    パブリッシュnpm publish
    npm http PUT https://registry.npmjs.org/nanomsg
    npm http 201 https://registry.npmjs.org/nanomsg
    npm http GET https://registry.npmjs.org/nanomsg
    npm http 200 https://registry.npmjs.org/nanomsg
    npm http PUT https://registry.npmjs.org/nanomsg/-/nanomsg-0.0.0.tgz/-rev/1-20f1ec5ca2eed51e840feff22479bb5d
    npm http 201 https://registry.npmjs.org/nanomsg/-/nanomsg-0.0.0.tgz/-rev/1-20f1ec5ca2eed51e840feff22479bb5d
    npm http PUT https://registry.npmjs.org/nanomsg/0.0.0/-tag/latest
    npm http 201 https://registry.npmjs.org/nanomsg/0.0.0/-tag/latest
    + [email protected]
    

    最後に、別の場所で新しいディレクトリを作成し、readmeの手順に従って走って、パッケージが確実に多重化されることを確認するのが好きです.これはreadmeでerrnoとrecvの前のnn_接頭辞をうっかり漏らしてしまったので役に立ちます!
    readmeの例を更新したら、バージョン番号を変更して再発行しましょう.npm versionを使用して現在のバージョンを表示し、npm version patchを使用して変更します.その前にreadmeの変更を提出する必要があります.最後に、npm publishを再度運転することを忘れないでください.
    最終的なディレクトリ構造は次のように見えます.
    tree -L 2 -C -a -I '.git'
    .
    ├── .gitignore
    ├── .npmignore
    ├── Gruntfile.coffee
    ├── LICENSE
    ├── README.md
    ├── lib
    │   └── nanomsg.js
    ├── node_modules
    │   ├── .bin
    │   ├── chai
    │   ├── ffi
    │   ├── grunt
    │   ├── grunt-contrib-coffee
    │   └── grunt-mocha-test
    ├── package.json
    ├── src
    │   └── nanomsg.coffee
    └── test
        └── test.coffee
    
    10 directories, 9 files
    

    最後に、私はMartinSústrikに連絡して、nanomsgに新しいバインドがあることを知らせます.
    このバインディングは十分ではなく,テストカバー率はより高く,APIはCによく似ており,いくつかのOO構文糖を使用することができるが,我々はすでに良好な出発点を持っており,さらに改善することができる.もしあなたが意図的に手伝ってくれるなら、派生してください.https://github.com/nickdesaulniers/node-nanomsg.git
    Nodeモジュールの構築手順、テスト、ディレクトリ構造についてどう思いますか?このチュートリアルは明らかに権威のあるガイドラインではありません.あなた方のコメントを楽しみにしています.
    原文Making Great Node.js Modules With CoffeeScript翻訳SegmentFault