是否可以使用 requireJS 来“要求”整个文件夹。
例如,我有一个包含大量行为 js 文件的行为文件夹。我真的很想能够简单地使用 require(['behaviors/*'], function() {...}); 加载该文件夹中的所有内容,而不必使该列表保持最新。压缩和优化后,我会将所有这些文件放在一起,但对于开发来说,单独使用它们会更容易。
是否可以使用 requireJS 来“要求”整个文件夹。
例如,我有一个包含大量行为 js 文件的行为文件夹。我真的很想能够简单地使用 require(['behaviors/*'], function() {...}); 加载该文件夹中的所有内容,而不必使该列表保持最新。压缩和优化后,我会将所有这些文件放在一起,但对于开发来说,单独使用它们会更容易。
浏览器中的 javascript 没有文件系统访问权限,因此无法扫描目录中的文件。如果您正在使用 php 或 ruby 等脚本语言构建应用程序,您可以编写一个脚本来扫描目录并将文件名添加到 require() 调用中。
我不知道我是否可以再推荐这种方法。我认为更明确的方法是手动“要求”/“导出”您需要的功能。我认为的例外情况是,如果您有要导出的文件的“命名空间”,请参见下文“Babel 和 ES6 模块导入声明(export-namespace-from)或参见下文“Babel 和 ES6 模块导入声明。
这些解决方案还假设您有一个有意义的文件结构——其中文件名成为“需要”*
定义的一部分。
但是,如果您仍然需要这样做,那么有一些现有的工具和方法可能会提供您正在寻找的行为。
可能的解决方案
Babel 和 ES6 模块导入声明(plugin-export-namespace-from)
.babelrc
文件以包含babel-plugin-proposal-export-namespace-from。常见/index.js
export * from './common/a'; // export const a = false;
export * from './common/b'; // export const b = true;
main.js
import { a, b } from './common';
console.log(a); // false
console.log(b); // true
Babel 和 ES6 模块导入声明(插件通配符)
.babelrc
文件以包含babel-plugin-wildcard。main.js
import { a, b } from './common/*'; // imports './common/a.js' and './common/b.js'
console.log(a); // false
console.log(b); // true
RequireJS(现已过时)
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']);
namespaces.js
require(['namespaces'], function () { ... });
src
的模块使用依赖项 glob 模式匹配。require(['behaviors/**/*'], function (behaviors) { }
我知道这是旧的,但我想分享我的解决方案:
对于此解决方案,您需要 JQuery
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
我的目录/FirstJavascriptFile 我的目录/SecondJavascriptFile 我的目录/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");
}
}
});
我最终做的是每次我的节点服务器启动时,它将运行 bash 脚本,填充 directoryContents.txt。然后我的客户端只是读取 directoryContents.txt 的文件列表,并需要该列表中的每个。
希望这可以帮助!
实际上并没有一种方法可以在概念上即时执行此操作(据我所知)。
不过有一些解决方法:
使用grunt
然后concat
只需要那个庞然大物......我知道,有点糟糕。
我认为是一个更好的解决方案......使用这样的要求层次结构:
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
称为“索引”。这将使您的模块可扩展到给定的接口——您可以简单地交换模块并保持您的接口相同。
希望这可以帮助!快乐编码!
我写了一个库来解决这个问题。最终其他人出现并改进了我的图书馆,这里是:
https://github.com/smartprocure/directory-metagen
您可以将我的库与 Gulp 或其他任何东西一起使用 - 它为您的项目生成元数据,而 RequireJS 可以使用该元数据从文件系统中获取所需的文件。
使用这个库将生成一个 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]
}
});
然后,您可以像这样在前端 require 模块:
var footerView = require("app/js/jsx/standardViews/footerView");
但是,正如您所看到的,这太冗长了,所以神奇的方式是这样的:
将上面的依赖项命名为 allViews!
现在你可以这样做:
var allViews = require('allViews');
var footerView = allViews['standardViews/footerView'];
要求整个目录有两个优点:
(1) 在生产环境中,使用 r.js 优化器,您可以指向一个依赖项(模块 A),然后它可以轻松跟踪 A 的所有代表整个目录的依赖项
(2) 在开发中,您可以预先要求整个目录,然后使用同步语法来要求依赖项,因为您知道它们已经被加载
享受“RequireJS-Metagen”
https://github.com/smartprocure/directory-metagen