помощью 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

https://www.npmjs.com/package/requirejs-metagen

https://github.com/ORESoftware/requirejs-metagen