Javascript requireJS 整个文件夹
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5892978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
requireJS an entire folder
提问by nicholas
Is it possible to "require" an entire folder using requireJS.
是否可以使用 requireJS“要求”整个文件夹。
For example, I have a behaviors folder with a ton of behavior js files. I'd really like to be able to simply use require(['behaviors/*'], function() {...}); to load everything in that folder rather than having to keep that list up to date. Once compressed and optimized I'd have all those files lump together, but for development it's easier to work with them individually.
例如,我有一个包含大量行为 js 文件的行为文件夹。我真的很想能够简单地使用 require(['behaviors/*'], function() {...}); 加载该文件夹中的所有内容,而不必使该列表保持最新。一旦压缩和优化,我会将所有这些文件放在一起,但对于开发来说,单独使用它们会更容易。
回答by greggreg
javascript in browser has no filesystem access and so it can't scan a directory for files. If you are building your app in a scripting language like php or ruby you could write a script that scans the directory and adds the file names to the require() call.
浏览器中的 javascript 没有文件系统访问权限,因此它无法扫描目录中的文件。如果您使用 php 或 ruby 等脚本语言构建应用程序,您可以编写一个脚本来扫描目录并将文件名添加到 require() 调用中。
回答by Nate-Wilkins
While JavaScript in the browser can't (and shouldn't) see the file system I created a Grunt task that will do just this. I'm currently still working on it touching it up here and there but you're welcome to take a look.
虽然浏览器中的 JavaScript 不能(也不应该)看到文件系统,但我创建了一个 Grunt 任务来完成这个任务。我目前仍在努力修改它,但欢迎您来看看。
https://npmjs.org/package/require-wild
https://npmjs.org/package/require-wild
npm install require-wild
npm install require-wild
In your case all you'd have to do is setup the task's settings
在您的情况下,您所要做的就是设置任务的设置
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']);
Then run the grunt task. Your file will be generated. Modify your main.js
to load namespaces.js
然后运行 grunt 任务。将生成您的文件。修改你main.js
的加载namespaces.js
require(['namespaces'], function () { ... });
require(['namespaces'], function () { ... });
Thus now allowing modules under src
to use dependencies with grunt's glob pattern matching.
因此现在允许下面的模块src
使用具有 grunt 的 glob 模式匹配的依赖项。
require(['behaviors/**/*'], function (behaviors) { }
require(['behaviors/**/*'], function (behaviors) { }
This ideology assumes that you have a meaningful file structure.
这种意识形态假设您有一个有意义的文件结构。
回答by Katie
I know this is old, but I'd like to share my solution:
我知道这是旧的,但我想分享我的解决方案:
For this solution you need JQuery
对于此解决方案,您需要 JQuery
1) Create a bash scriptthat will list all the js filesin "MyDirectory/", and save it to "directoryContents.txt":
1)创建一个bash脚本,列出“MyDirectory/”中的所有js文件,并将其保存到“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
- File will look like this:
- 文件将如下所示:
MyDirectory/FirstJavascriptFile MyDirectory/SecondJavascriptFile MyDirectory/ThirdJavascriptFile
MyDirectory/FirstJavascriptFile MyDirectory/SecondJavascriptFile MyDirectory/ThirdJavascriptFile
- Problem with my script! Puts an extra " " at the end, that messes things up! Make sure to remove the excess spaceat the end of directoryContents.txt
- 我的脚本有问题!最后多加一个“”,把事情搞砸了!确保删除directoryContents.txt末尾的多余空间
2) Then in your Client side JS code:
2)然后在您的客户端JS代码中:
- do a "GET" request to retrieve the text file
- For each entry (split by the space), 'require' that file:
- 执行“GET”请求以检索文本文件
- 对于每个条目(按空格分割),“要求”该文件:
.
.
$.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");
I was having a problem with this code not finishing before my other code, so Here's my extended answer:
我遇到了这个代码没有在我的其他代码之前完成的问题,所以这是我的扩展答案:
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");
}
}
});
What I ended up doing was everytime my Node server boots, it will run the bash script, populating directoryContents.txt. Then My client side just reads directoryContents.txt for the list of files, and requires each in that list.
我最终做的是每次我的 Node 服务器启动时,它都会运行 bash 脚本,填充 directoryContents.txt。然后我的客户端只读取 directoryContents.txt 的文件列表,并需要该列表中的每个。
Hope this helps!
希望这可以帮助!
回答by Cody
There isn't really a way to do this conceptually on the fly (that I know of).
没有真正的方法可以在概念上即时执行此操作(我知道)。
There's a few work arounds though:
不过有一些解决方法:
Use grunt
and concat
and then just require that behemoth...I know, kinda sucky.
使用grunt
和concat
,然后只需要庞然大物......我知道,有点苏茨基。
What I think is a better solution... use a require hierarchy like so:
我认为是一个更好的解决方案......使用像这样的要求层次结构:
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
};
};
});
Note that "protagonist
" function
. That allows you to initialize modules before their use, so now you can pass in a 'sandbox
' -- in this case app
and globals
.
注意“ protagonist
” function
。这允许您在使用模块之前对其进行初始化,因此现在您可以传入一个 ' sandbox
' - 在本例中为app
和globals
。
Realistically, you wouldn't have /js/controllers/index.js
... It should probably be something like /js/controllers/index/main.js
or /js/controllers/index/init.js
so that there is a directory adjacent to (sibling of) /js/controllers/init.js
called "index". This will make your modules scalable to a given interface -- you can simply swap modules out and keep your interface the same.
实际上,你不会/js/controllers/index.js
......它可能应该是这样的/js/controllers/index/main.js
,/js/controllers/index/init.js
以便有一个与(的兄弟姐妹)相邻的目录,/js/controllers/init.js
称为“索引”。这将使您的模块可扩展到给定的接口——您可以简单地交换模块并保持您的接口相同。
Hope this helps! Happy coding!
希望这可以帮助!快乐编码!
回答by Alexander Mills
I wrote a library to solve this problem. Eventually someone else came along and improved my library, here it is:
我写了一个库来解决这个问题。最终其他人出现并改进了我的库,这里是:
https://github.com/smartprocure/directory-metagen
https://github.com/smartprocure/directory-metagen
You can use my lib with Gulp or whatever - it generates metadata for your project and RequireJS can use that metadata to require the desired files from the filesystem.
您可以将我的库与 Gulp 或其他任何东西一起使用 - 它为您的项目生成元数据,RequireJS 可以使用该元数据从文件系统中获取所需的文件。
Using this lib will produce a RequireJS module that looks something like this:
使用这个库将生成一个 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]
}
});
You can then require modules in your front-end like so:
然后,您可以像这样在前端要求模块:
var footerView = require("app/js/jsx/standardViews/footerView");
however, as you can see this is too verbose, so the magic way is like so:
然而,正如你所看到的,这太冗长了,所以神奇的方法是这样的:
name the dependency above as allViews!
将上面的依赖项命名为 allViews!
now you can do:
现在你可以这样做:
var allViews = require('allViews');
var footerView = allViews['standardViews/footerView'];
There are two advantages to requiring directories whole:
要求整个目录有两个优点:
(1) in production, with the r.js optimizer, you can point to one dependency (module A) and it can then easily trace all of A's dependencies that represent a entire directory
(1) 在生产中,使用 r.js 优化器,您可以指向一个依赖项(模块 A),然后它可以轻松跟踪代表整个目录的 A 的所有依赖项
(2) in development, you can require whole directories up front and then use synchronous syntax to require dependencies because you know they have already been loaded
(2) 在开发中,你可以预先 require 整个目录,然后使用同步语法来 require 依赖,因为你知道它们已经被加载了
enjoy "RequireJS-Metagen"
享受“RequireJS-Metagen”
https://github.com/smartprocure/directory-metagen
https://github.com/smartprocure/directory-metagen
https://www.npmjs.com/package/requirejs-metagen
https://www.npmjs.com/package/requirejs-metagen