помощью RequireJS всю папку
можно ли "требовать" всю папку с помощью RequireJS.
например, у меня есть папка поведения с тонной файлов поведения js. Я бы очень хотел иметь возможность просто использовать require (['behaviors/*'], function() {...}); загружать все в эту папку, а не обновлять этот список. После сжатия и оптимизации у меня будут все эти файлы, но для разработки легче работать с ними по отдельности.
5 ответов
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
для использования зависимостей с сопоставлением шаблона glob grunt.
require(['behaviors/**/*'], function (behaviors) { }
эта идеология предполагает, что у вас есть значимые структуры файла.
Я знаю, что это старый, но я хотел бы поделиться мое решение:
для этого решения вам нужен JQuery
1) Создать bash script что будет список всех файлов js in "MyDirectory/", and сохраните его в " 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
- проблема с моим скриптом! Ставит дополнительный "" в конце, это все портит! Убедитесь, что удалить лишний пробел в конце directoryContents.txt
2) затем в вашем клиентском коде JS:
- сделайте запрос "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");
у меня была проблема с этим кодом, не закончившимся до моего другого кода, поэтому вот мой расширенный ответ:
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 следующим образом:
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
вы можете использовать my 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'];
есть два преимущества, требующие каталогов в целом:
(1) в производстве, с r.оптимизатор js, вы можете указать на одну зависимость (модуль A) , и она может легко отслеживать все зависимости A, представляющие весь каталог
(2) в разработке, вы можете требовать все каталоги и затем с помощью синхронного синтаксиса зависимостей, потому что вы знаете, что они уже были загружены
наслаждайтесь "RequireJS-Metagen"
https://github.com/smartprocure/directory-metagen