Подтвердить что ты не робот

RequireJS целая папка

Возможно ли "потребовать" целую папку с помощью requireJS.

Например, у меня есть папка поведения с тонны js файлов поведения. Я действительно хотел бы иметь возможность просто использовать require (['behaviors/*'], function() {...}); загрузить все в эту папку, а не обновлять этот список. После сжатия и оптимизации у меня были бы все эти файлы вместе, но для разработки проще работать с ними по отдельности.

4b9b3361

Ответ 1

javascript в браузере не имеет доступа к файловой системе и поэтому не может сканировать каталог для файлов. Если вы создаете свое приложение на языке сценариев, например php или ruby, вы можете написать script, который сканирует каталог и добавляет имена файлов в вызов require().

Ответ 2

Пока 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 использовать зависимости с сопоставлением шаблонов glunt glob.

require(['behaviors/**/*'], function (behaviors) { }

Эта идеология предполагает, что у вас есть значимая файловая структура.

Ответ 3

Я знаю, что это устарело, но я хочу поделиться своим решением:

Для этого решения вам нужен JQuery

1) Создайте bash script, который будет отображать все 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

  • Проблема с моим script! В конце добавляет лишний ", это все испортит! Убедитесь, что удалить лишнее пространство в конце 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 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 script, заполняющий directoryContents.txt. Затем моя клиентская сторона просто считывает каталогContents.txt для списка файлов и требует каждого в этом списке.

Надеюсь, это поможет!

Ответ 4

На самом деле нет способа сделать это концептуально "на лету" (что я знаю).

Там немного работы:

Используйте 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, так что есть каталог, смежный с (sibling of) /js/controllers/init.js, называемый "index". Это сделает ваши модули масштабируемыми для данного интерфейса - вы можете просто заменить модули и сохранить свой интерфейс одинаково.

Надеюсь, это поможет! Счастливое кодирование!

Ответ 5

Я написал библиотеку для решения этой проблемы.

Вы можете использовать мой 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]
        }
    });

и еще больший пример:

define(
    [
        "app/js/jsx/BaseView",
        "app/js/jsx/GenericView",
        "app/js/jsx/controllerViews/FluxCartApp",
        "app/js/jsx/reactComponents/FluxCart",
        "app/js/jsx/reactComponents/FluxProduct",
        "app/js/jsx/reactComponents/Item",
        "app/js/jsx/reactComponents/Job",
        "app/js/jsx/reactComponents/JobsList",
        "app/js/jsx/reactComponents/MenuExample",
        "app/js/jsx/reactComponents/Picture",
        "app/js/jsx/reactComponents/PictureList",
        "app/js/jsx/reactComponents/RealTimeSearchView",
        "app/js/jsx/reactComponents/Service",
        "app/js/jsx/reactComponents/ServiceChooser",
        "app/js/jsx/reactComponents/TimerExample",
        "app/js/jsx/reactComponents/listView",
        "app/js/jsx/reactComponents/todoList",
        "app/js/jsx/relViews/FluxCart/FluxCartMain",
        "app/js/jsx/relViews/getAll/getAll",
        "app/js/jsx/relViews/jobs/jobsView",
        "app/js/jsx/standardViews/IndexView",
        "app/js/jsx/standardViews/dashboardView",
        "app/js/jsx/standardViews/footerView",
        "app/js/jsx/standardViews/headerView",
        "app/js/jsx/standardViews/homeView",
        "app/js/jsx/standardViews/loginView",
        "app/js/jsx/standardViews/overviewView",
        "app/js/jsx/standardViews/pictureView",
        "app/js/jsx/standardViews/portalView",
        "app/js/jsx/standardViews/registeredUsersView",
        "app/js/jsx/standardViews/userProfileView"
    ],
    function(){

        return {

            "BaseView": arguments[0],
            "GenericView": arguments[1],
            "controllerViews/FluxCartApp": arguments[2],
            "reactComponents/FluxCart": arguments[3],
            "reactComponents/FluxProduct": arguments[4],
            "reactComponents/Item": arguments[5],
            "reactComponents/Job": arguments[6],
            "reactComponents/JobsList": arguments[7],
            "reactComponents/MenuExample": arguments[8],
            "reactComponents/Picture": arguments[9],
            "reactComponents/PictureList": arguments[10],
            "reactComponents/RealTimeSearchView": arguments[11],
            "reactComponents/Service": arguments[12],
            "reactComponents/ServiceChooser": arguments[13],
            "reactComponents/TimerExample": arguments[14],
            "reactComponents/listView": arguments[15],
            "reactComponents/todoList": arguments[16],
            "relViews/FluxCart/FluxCartMain": arguments[17],
            "relViews/getAll/getAll": arguments[18],
            "relViews/jobs/jobsView": arguments[19],
            "standardViews/IndexView": arguments[20],
            "standardViews/dashboardView": arguments[21],
            "standardViews/footerView": arguments[22],
            "standardViews/headerView": arguments[23],
            "standardViews/homeView": arguments[24],
            "standardViews/loginView": arguments[25],
            "standardViews/overviewView": arguments[26],
            "standardViews/pictureView": arguments[27],
            "standardViews/portalView": arguments[28],
            "standardViews/registeredUsersView": arguments[29],
            "standardViews/userProfileView": arguments[30]
        }
  });

Затем вы можете потребовать модули в своем интерфейсе следующим образом:

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://www.npmjs.com/package/requirejs-metagen

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