87

ノードにいくつかのアプリがあり、それらはすべて、私が作成したいくつかのモジュールを共有しています。これらのモジュールはnpmでは利用できません。アプリ間で自由に共有できるようにしたいのですが、ディレクトリをコピーしたり、Gitに依存したりしたくありません。そして、私はこれを行うためにシンボリックリンクを使用することについてもそれほど大きくはありません。

次のようなディレクトリを配置したいと思います。

app1
 server.js
 node_modules
  (public modules from npm needed for app1)
 lib
  (my own modules specific to app1)

app2
 server.js
 node_modules
  (public modules from npm needed for app2)
 lib
  (my own modules specific to app2)

shared_lib
 (my own modules that are used in both app1 and app2)

私が見ている問題は、shared_lib内のモジュールが、実行中のアプリのnode_modulesディレクトリにあるモジュールの場所について混乱しているように見えることです。少なくともそれが問題だと思います。

だから....ファイルの重複を避けるためにこれを行うための良い方法は何ですか?(node_modules内の重複については気にしないことに注意してください。これらは私のコードではないため、Gitなどにチェックインしません)

4

6 に答える 6

52

npmのドキュメントでは、npm-linkを使用して独自のNode.jsパッケージをローカルで作成し、それらを他のNode.jsアプリケーションで使用できるようにすることを推奨しています。これは単純な4ステップのプロセスです。

一般的な手順は、最初に次の構造のパッケージを作成することです。

  hello
  | index.js
  | package.json

これらのファイルの一般的な実装は次のとおりです。

index.js

  exports.world = function() {
     return('Hello World');
  }

package.json

  {
    "name": "hello",
    "version": "0.0.1",
    "private": true,
    "main": "index.js",
    "dependencies": {
    },
    "engines": {
    "node": "v0.6.x"
    }
  }

「private:true」は、npmがパッケージの公開を拒否することを保証します。これは、プライベートパッケージの偶発的な公開を防ぐ方法です。

次に、Node.jsパッケージフォルダーのルートに移動し、実行npm linkしてパッケージをグローバルにリンクし、他のアプリケーションで使用できるようにします。

このパッケージを別のアプリケーション(「hello-world」など)で使用するには、次のディレクトリ構造を使用します。

 hello-world
 | app.js

hello-worldフォルダーに移動して、以下を実行します。

 npm link hello

これで、他のnpmパッケージと同じように使用できます。

app.js

  var http = require('http');
  var hello = require('hello');

  var server = http.createServer(function(req, res) {
     res.writeHead(200);
     res.end(hello.world());
  });
  server.listen(8080);
于 2012-07-01T03:20:21.000 に答える
25

さまざまなレベルにnode_modulesフォルダーを配置することで、これを機能させることができます。ノードは、モジュールが見つかるまで自動的に上方向にトラバースします。

node_modules内にモジュールを含めるためにnpmに公開する必要はないことに注意してください-使用するだけです:

"private": true

各プライベートpackage.jsonファイル内-プロジェクトの場合、次のようになります。

app1
 server.js
 node_modules
  (public modules from npm needed for app1)
  (private modules locally needed for app1)

app2
 server.js
 node_modules
  (public modules from npm needed for app2)
  (private modules locally needed for app2)

node_modules
  (public modules from npm needed for app1 & app2)
  (private modules locally for app1 & app2)

重要なのは、node.jsにはすでにこれに対処するためのメカニズムがあり、それは素晴らしいことです。それを「NPMではないプライベート」トリックと組み合わせるだけで、準備は完了です。

要するに:

require('somemodule')

アプリAまたはBから、モジュールが見つかるまで上にカスケードされます-モジュールが下にあるか上にあるかに関係なく。実際、これにより、 require(...)ステートメントを変更せずに場所をホットスワップできます。

node.jsモジュールのドキュメント

于 2012-07-01T13:04:08.317 に答える
5

requirecallで正しいパスを使用するだけです

たとえば、server.jsでは次のようになります。

var moduleName = require('../ shared_lib / moduleName / module.js');

パスのプレフィックスが「/」、「../」、または「./」になるとすぐに、パスは呼び出し元のファイルからの相対パスになることを知っておくことが重要です。

ノードモジュールの読み込みの詳細については、http: //nodejs.org/docs/latest/api/modules.htmlをご覧ください。

于 2012-07-01T01:47:34.353 に答える
4

はい、app1からshared_libを参照できますが、app1をパッケージ化してAWSのウェブサーバーなどの他の環境にデプロイする場合は、問題が発生します。

この場合、「npm install shared_lib / module」を使用して、shared_libのモジュールをapp1とapp2にインストールすることをお勧めします。また、app1とapp2のshared_libモジュールのすべての依存関係をインストールし、競合/重複を処理します。

これを参照してください: 自分のレジストリなしでプライベートNPMモジュールをインストールするにはどうすればよいですか?

于 2017-01-13T10:45:36.047 に答える
2

node.jsのドキュメントを確認すると、Node.jsがpackage.jsonファイル形式も少なくとも大まかに理解していることがわかります。

基本的に、という名前のfooディレクトリがあり、そのディレクトリpackage.jsonにキーと値のペアが含まれるファイルがある"main": "myCode.js"場合、次のようにしようとすると、内部にファイルrequire("foo")があるこのディレクトリが見つかると、モジュールに使用されます。package.jsonfoo/myCode.jsfoo

したがって、ディレクトリ構造では、各共有ライブラリにそのような単純なpackage.jsonファイルを含む独自のディレクトリがある場合、アプリは次の方法で共有ライブラリを取得できます。

var lib1 = require('../shared_lib/lib1');
var lib2 = require('../shared_lib/lib2');

そして、それはこれらのアプリの両方で機能するはずです。

于 2012-07-01T01:39:37.107 に答える
0

別の解決策は、他の場所からこのリポジトリにファイルを複製することです。

clone.js

const path = require('path')
const fs = require('fs')

const shared = [
  {
    type: 'file',
    source: '../app1',
    files: [
      'src/file1',
      'src/file2',
      '...'
    ],
  },
]

function cloneFiles(source, files) {
  const Reset = '\x1b[0m'
  const FgGreen = '\x1b[32m'
  console.log(`---------- Cloning ${files.length} files from ${source} ----------`)

  for (const file of files) {
    const sourceFile = path.join(__dirname, '..', source, file)
    const targetFile = path.join(__dirname, '..', file)

    process.stdout.write(` ${file} ... `)
    fs.copyFileSync(sourceFile, targetFile)
    console.log(`${FgGreen}Done!${Reset}`)
  }

  console.log(`---------- All done successfully ----------\n`)
}

;(() => {
  for (const item of shared) {
    switch (item.type) {
      case 'file':
        cloneFiles(item.source, item.files)
        break
    }
  }
})()

次に、package.jsonでこのスクリプトを追加し、ファイルのクローンを作成/同期するときに呼び出すことができます。

"clone": "node clone.js"
于 2022-02-18T05:41:41.850 に答える