45

これは少し長いですが、私の混乱を説明するためにコード例が必要です。その後、次の回答に興味があります。

  1. require('module')またはの代わりにどのように使用しますrequire('../../src/module')require('./module')?
  2. 作業を複製せずに再利用./index.jsするにはどうすればよいですか? (そして、エントリーモジュールであるため、実行をspec/specs.js防ぎます)。src/app.js

私はすでにいくつかのブラウザー ベースのプロジェクトを開始しており、browserifyと grunt が大好きです。しかし、各プロジェクトは私の開発/学習曲線の同じ時点で終了します。ミックスにテストを追加し、2 つのbrowserifyバンドル (app.jsおよびspec/specs.js) を管理する必要があると、システム全体が崩壊します。説明します:

grunt-browserifyを使用して、初期ディレクトリを設定します。

.
├── Gruntfile.js
├── index.js  (generated via grunt-browserify)      [1]
├── lib
│   ├── jquery
│   │   └── jquery.js                               [2]
│   └── jquery-ui
│       └── jquery-ui.js                            [3]
├── spec
│   ├── specs.js  (generated via grunt-browserify)  [4]
│   └── src
│       ├── spec_helper.js  (entry)
│       └── module_spec.js  (entry)
└── src
    ├── app.js  (entry)
    └── module.js
  1. 1 つのエントリ ファイル ( ) を使用し、コード ウォークを実行して必要なすべてのモジュールsrc/app.jsをバンドルします。
  2. エイリアスに browserify-shim を使用しjqueryます。
  3. シムなしでエイリアスされているだけjquery-uiです( you の後に必要ですvar $ = require('jquery'))。
  4. すべてのヘルパー ファイルとスペック ファイルspec/srcをエントリ モジュールとして使用します。

構成をステップ実行します。

browserify: {
  dist: {
    files: {
      'index.js': ['src/app.js']
    }
  }
}

// in app.js
var MyModule = require('./module'); // <-- relative path required?!

幸せ

jquery を追加します。

browserify: {
  options: {
    shim: {
      jquery: {
        path: 'lib/jquery/jquery.js',
        exports: '$'
      }
    },
    noParse: ['lib/**/*.js'],
    alias: [
      'lib/jquery-ui/jquery-ui.js:jquery-ui'
    ]
  },
  dist: {
    files: {
      'index.js': ['src/app.js']
    }
  }
}

// in app.js
var $ = require('jquery');
require('jquery-ui');
var MyModule = require('./module');

幸せ

仕様を追加します。

options: {
  shim: {
    jquery: {
      path: 'lib/jquery/jquery.js',
      exports: '$'
    }
  },
  noParse: ['lib/**/*.js'],
  alias: [
    'lib/jquery-ui/jquery-ui.js:jquery-ui'
  ]
},
dist: {
  files: {
    'app.js': 'src/app.js'
  }
},
spec: {
  files: {
    'spec/specs.js': ['spec/src/**/*helper.js', 'spec/src/**/*spec.js']
  }
}

// in app.js
var $ = require('jquery');
require('jquery-ui');
var MyModule = require('./module');

// in spec/src/module_spec.js
describe("MyModule", function() {
  var MyModule = require('../../src/module'); // <-- This looks like butt!!!
});

悲しい

要約すると、どうすれば...

  1. または?require('module')の代わりに使用します。require('../../src/module')require('./module')
  2. 作業を複製せずに./index.js再利用できますか? (そして、エントリーモジュールであるため、実行をspec/specs.js防ぎます)。src/app.js
4

4 に答える 4

30

簡単な答え:

最も簡単な方法はpaths、browserify のオプションを使用することです。私はそれを数ヶ月使用して大成功を収めました。この機能を使用するスターター キットも作成しました: https://github.com/stample/gulp-browserify-react-phonegap-starter

var b = browserify('./app', {paths: ['./node_modules','./src/js']});

paths - 通常の node_modules 再帰ウォークで何も見つからない場合に使用する require.paths 配列

これにファイルがある場合、どこにでもsrc/js/modulePath/myModule.js書き込むことはできませんが、他のソースファイルから書き込むことができます。require("myModule")require("modulePath/myModule")

非推奨オプション?

そうではないようです!

Browserify モジュールの解決アルゴリズムは、 NodeJS の解決アルゴリズムを反映しています。したがって、Browserifyのpathsオプションは、NodeJS の環境NODE_PATH変数の動作のミラーです。Browserify の作成者 (サブスタック) は、この SO トピックで、このNODE_PATHオプションは NodeJS で廃止されたため、Browserify でも廃止され、次のバージョンで削除される可能性があると主張しています。

私はこの主張に同意しません。

NODE_PATHのドキュメントを参照してください。オプションが非推奨であることは言及されていません。ただし、サブスタックの主張の方向性を示す興味深い言及がまだあります。

依存関係を node_modules フォルダーにローカルに配置することを強くお勧めします。それらはより速く、より確実にロードされます。

そして、この質問は 2012 年にメーリング リストに投稿されました。

Oliver Leics: is NODE_PATH deprecated? 
Ben Noordhuis (ex core NodeJS contributor): No. Why do you ask? 

NodeJS解決アルゴリズムで何かが削除されていない場合、Browserifyからすぐに削除されるとは思いません:)

結論

pathsオプションを使用するかnode_modules、公式ドキュメントやBrowserify の著者が推奨するようにコードを挿入することができます。

node_modules個人的には、このフォルダー全体をソース管理から除外するだけなので、独自のコードを入れるという考えは好きではありません。私はこのpathsオプションを数か月間使用していますが、まったく問題はありませんでした。ビルド速度はかなり良好です。

内部にシンボリックリンクを配置するというサブスタックのソリューションはnode_modules便利かもしれませんが、残念ながらここには Windows で作業している開発者がいます...

ただし、オプションを使用したくない場合があるとpaths思います: 他のアプリで必要となる NPM リポジトリで公開されたライブラリを開発している場合。ライブラリ内の相対パス地獄を回避したいという理由だけで、これらのライブラリ クライアントが特別なビルド構成をセットアップする必要はありません。

別の可能なオプションは、remapifyを使用することです

于 2014-05-12T11:58:12.237 に答える
7

エイリアスとopts.paths/に関するここでのすべての回答$NODE_PATHは素晴らしいものではありません。そのアプローチは node と browserify のモジュール システムの非推奨部分であるため、いつでも機能しなくなる可能性があるからです。

node_modules アルゴリズムがどのように機能するかを学ぶ必要があります。これにより、ネストされたnode_modulesディレクトリで適切に機能する方法でコードを効果的に編成できるようになります。

browserify ハンドブックには、 ../../../../../../ ..相対パスの問題を回避するセクションがあります。次のように要約できます。

  • 内部モジュラー コードをnode_modules/またはnode_modules/appに配置して、require('yourmodule')またはrequire('app/yourmodule')好みに応じて配置します。
  • Windows 以外のプラットフォーム向けに開発している場合は、シンボリック リンクを使用できます。

opts.path/を使用しないでください$NODE_PATH。それはあなたのプロジェクトを作ります:

  • 非自明な構成または環境設定に暗黙的に依存する
  • ノードとブラウザの両方で動作させるのが難しい
  • node と browserify では配列パスが非推奨になっているため、モジュール システムの変更に対して脆弱です。
于 2014-08-13T21:47:08.270 に答える
4

これらの答えは、プロジェクトの残りの部分がどのように設定されているかによって異なりますが、出発点としては適切かもしれません。また、これを実際に機能させるには、現在の v2 ベータ版の grunt-browserify を使用する必要があります ( npm install grunt-browserify@2)。

1.

モジュールの動的エイリアスを作成するには、 aliasMappingを使用します。わかりやすくするために、すべてのモジュールを に移動しましょうsrc/modules/。次に、aliasMapping 構成は次のようになります。

options: {
  aliasMappings: {
    cwd: 'src',
    src: ['modules/**/*.js']
  }
}

にモジュールがあると仮定するとsrc/modules/magic/stuff.js、require を実行している .js ファイルがどこにあるかに関係なく、次のように require できます。

var magicStuff = require('modules/magic/stuff.js');

2.

これについてはわかりません。あなたのプロジェクト構造は を示してspec/index.jsいますが、言及していますspec/specs.js。それらは同じファイルであるはずですか?

とにかく、あなたが話している複製作品は何ですか?./index.jsは とは異なるエントリ ファイルを持っているためですspec/index.js。に含める方法を探している場合は./index.jsspecs/最初からビルドするのではなく、テストを実行する前にコピーすることができます。

于 2014-03-01T12:42:27.090 に答える
1

Sebastien Lorber が指摘しているように、パイプを介して browserify を呼び出す際にパスを設定するのが絶対的な最善の方法だと思います。

しかし、browserify の最新バージョン (現時点では、つまりbrowserify@11.0.0) では、path 変数には、Browserify がそのプロセスに使用する唯一のパスが格納されます。したがって、パス変数を設定すると、たとえば、ノードのグローバルフォルダーが除外されます。その結果、次のような Gulp タスクが必要になります。

gulp.task('reactBuild', function() {
  return gulp.src(newThemeJSX)
    .pipe(browserify({
        debug: true,
        extensions: ['.jsx', '.js', '.json'],
        transform: [reactify],
        paths: ['../base_folder/node_modules', '/usr/lib/node_modules']
    }))
    .pipe(gulp.dest(newThemeBuilt))
    .on('error', function(error) {
        console.log(error);
    });
});
于 2015-07-22T17:49:09.580 に答える