RequireJSを使用してフォルダ全体を「require」することは可能ですか?.
たとえば、大量のビヘイビアjsファイルを含むビヘイビアフォルダがあります。 require(['behaviors/*']、function(){...});を簡単に使用できるようにしたいと思います。そのリストを最新の状態に保つ必要はなく、そのフォルダ内のすべてをロードします。圧縮して最適化すると、これらすべてのファイルがひとまとめになりますが、開発では、個別に操作する方が簡単です。
ブラウザのjavascriptにはファイルシステムへのアクセス権がないため、ディレクトリでファイルをスキャンすることはできません。 phpやRuby)などのスクリプト言語でアプリを構築している場合は、ディレクトリをスキャンしてファイル名をrequire()呼び出しに追加するスクリプトを作成できます。
ブラウザのJavaScriptはファイルシステムを見ることができません(そして見るべきではありません)が、私はこれを行うGruntタスクを作成しました。私は現在、あちこちでそれを修正するためにまだ取り組んでいますが、ぜひご覧ください。
https://npmjs.org/package/require-wild
_npm install require-wild
_
あなたの場合、あなたがしなければならないのはタスクの設定をセットアップすることだけです
_grunt.initConfig({
requireWild: {
app: {
// Input files to look for wildcards (require|define)
src: ["./**/*.js"],
// Output file contains generated namespace modules
dest: "./namespaces.js",
// Load your require config file used to find baseUrl - optional
options: { requireConfigFile: "./main.js" }
}
}
});
grunt.loadNpmTasks("require-wild");
grunt.registerTask('default', ['requireWild']);
_
次に、gruntタスクを実行します。ファイルが生成されます。 _main.js
_を変更して_namespaces.js
_をロードします
require(['namespaces'], function () { ... });
したがって、src
の下のモジュールが、gruntのglobパターンマッチングで依存関係を使用できるようになりました。
require(['behaviors/**/*'], function (behaviors) { }
このイデオロギーは、意味のあるファイル構造があることを前提としています。
私はこれが古いことを知っていますが、私の解決策を共有したいと思います:
このソリューションにはJQueryが必要です
1)bashスクリプトを作成しますすべてのjsファイルを一覧表示します "MyDirectory /"に、"directoryContents.txt"に保存します:
#!/bin/bash
#Find all the files in that directory...
for file in $( find MyDirectory/ -type f -name "*.js" )
do
fileClean=${file%.js} #Must remove .js from the end!
echo -n "$fileClean " >> MyDirectory/directoryContents.txt
done
MyDirectory/FirstJavascriptFile MyDirectory/SecondJavascriptFile MyDirectory/ThirdJavascriptFile
2)次に、クライアント側のJSコードで:
。
$.get( "MyDirectory/directoryContents.txt", {}, function( data ) {
var allJsFilesInFolder = data.split(" ");
for(var a=0; a<allJsFilesInFolder.length; a++)
{
require([allJsFilesInFolder[a]], function(jsConfig)
{
//Done loading this one file
});
}
}, "text");
このコードが他のコードの前に終了しないという問題があったので、これが私の拡張された答えです:
define([''], function() {
return {
createTestMenu: function()
{
this.loadAllJSFiles(function(){
//Here ALL those files you need are loaded!
});
},
loadAllJSFiles: function(callback)
{
$.get( "MyDirectory/directoryContents.txt", {}, function( data ) {
var allJsFilesInFolder = data.split(" ");
var currentFileNum = 0;
for(var a=0; a<allJsFilesInFolder.length; a++)
{
require([allJsFilesInFolder[a]], function(jsConfig)
{
currentFileNum++;
//If it's the last file that needs to be loaded, run the callback.
if (currentFileNum==allJsFilesInFolder.length)
{
console.log("Done loading all configuration files.");
if (typeof callback != "undefined"){callback();}
}
});
}
}, "text");
}
}
});
私がやったことは、Nodeサーバーが起動するたびに、bashスクリプトを実行して、directoryContents.txtにデータを入力することでした。次に、クライアント側は、ファイルのリストとしてdirectoryContents.txtを読み取るだけで、そのリストのそれぞれ。
お役に立てれば!
私はこの問題を解決するためにライブラリを作成しました。最終的に誰かがやって来て私のライブラリを改善しました。ここにあります:
https://github.com/smartprocure/directory-metagen
私のlibはGulpなどで使用できます。プロジェクトのメタデータが生成され、RequireJSはそのメタデータを使用して、ファイルシステムから目的のファイルを要求できます。
このlibを使用すると、次のようなRequireJSモジュールが生成されます。
define(
[
"text!app/templates/dashboardTemplate.ejs",
"text!app/templates/fluxCartTemplate.ejs",
"text!app/templates/footerTemplate.ejs",
"text!app/templates/getAllTemplate.ejs",
"text!app/templates/headerTemplate.ejs",
"text!app/templates/homeTemplate.ejs",
"text!app/templates/indexTemplate.ejs",
"text!app/templates/jobsTemplate.ejs",
"text!app/templates/loginTemplate.ejs",
"text!app/templates/overviewTemplate.ejs",
"text!app/templates/pictureTemplate.ejs",
"text!app/templates/portalTemplate.ejs",
"text!app/templates/registeredUsersTemplate.ejs",
"text!app/templates/userProfileTemplate.ejs"
],
function(){
return {
"templates/dashboardTemplate.ejs": arguments[0],
"templates/fluxCartTemplate.ejs": arguments[1],
"templates/footerTemplate.ejs": arguments[2],
"templates/getAllTemplate.ejs": arguments[3],
"templates/headerTemplate.ejs": arguments[4],
"templates/homeTemplate.ejs": arguments[5],
"templates/indexTemplate.ejs": arguments[6],
"templates/jobsTemplate.ejs": arguments[7],
"templates/loginTemplate.ejs": arguments[8],
"templates/overviewTemplate.ejs": arguments[9],
"templates/pictureTemplate.ejs": arguments[10],
"templates/portalTemplate.ejs": arguments[11],
"templates/registeredUsersTemplate.ejs": arguments[12],
"templates/userProfileTemplate.ejs": arguments[13]
}
});
次に、次のようにフロントエンドでモジュールを要求できます。
var footerView = require("app/js/jsx/standardViews/footerView");
ただし、ご覧のとおり、これは冗長すぎるため、魔法の方法は次のようになります。
上記の依存関係にallViewsという名前を付けてください。
今、あなたはできる:
var allViews = require('allViews');
var footerView = allViews['standardViews/footerView'];
ディレクトリ全体を要求することには2つの利点があります。
(1)本番環境では、r.jsオプティマイザーを使用して、1つの依存関係(モジュールA)を指定でき、ディレクトリ全体を表すAのすべての依存関係を簡単に追跡できます。
(2)開発では、ディレクトリ全体を事前に要求してから、同期構文を使用して依存関係を要求できます。これは、ディレクトリがすでにロードされていることがわかっているためです。
「RequireJS-Metagen」をお楽しみください
https://github.com/smartprocure/directory-metagen
これを概念的にオンザフライで行う方法は実際にはありません(私が知っていることです)
ただし、いくつかの回避策があります。
grunt
とconcat
を使用して、その巨大なものを要求するだけです...私は知っています、ちょっと厄介です。
私が思うのはより良い解決策です...次のようなrequire階層を使用してください:
require('/js/controllers/init', function(ctrls){
ctrls(app, globals);
});
// /js/controllers/init.js
define('js/controllers/index', 'js/controllers/posts', function(index, posts){
return function protagonist(app, globals){
var indexModule = index(app, globals);
var indexModule = posts(app, globals);
return app || someModule;
};
});
// /js/controllers/index.js
define('js/controllers/index', 'js/controllers/posts', function(index, posts){
return function protagonist(app, globals){
function method1(){}
function method2(){}
return {
m1: method1,
m2: method2
};
};
});
"protagonist
" function
に注意してください。これにより、モジュールを使用する前に初期化できるため、 'sandbox
'(この場合はapp
とglobals
)を渡すことができます。
現実的には、/js/controllers/index.js
...はありません。/js/controllers/index/main.js
(の兄弟)に隣接するディレクトリが呼び出されるように、おそらく/js/controllers/index/init.js
または/js/controllers/init.js
のようなものにする必要があります。 「インデックス」。これにより、モジュールが特定のインターフェイスにスケーラブルになります。モジュールを交換して、インターフェイスを同じに保つことができます。
お役に立てれば!ハッピーコーディング!