Требовать всю папку

javascript requirejs

22826 просмотра

5 ответа

6782 Репутация автора

Можно ли «требовать» целую папку с помощью requireJS.

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

Автор: nicholas Источник Размещён: 05.05.2011 05:17

Ответы (5)


24 плюса

9798 Репутация автора

Решение

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

Автор: greggreg Размещён: 05.05.2011 05:35

5 плюса

29764 Репутация автора

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

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

1) Создайте скрипт bash , который перечислит все 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

  • Проблема с моим скриптом! Добавляет лишний "" в конце, что все портит! Убедитесь, что вы удалили лишнее пространство в конце 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");
    }
}
});

То, что я в итоге делал, это каждый раз, когда мой Node-сервер загружался, он запускал скрипт bash, заполняя directoryContents.txt. Тогда Моя клиентская сторона просто читает directoryContents.txt для списка файлов, и требует каждого в этом списке.

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

Автор: Katie Размещён: 19.11.2013 02:01

8 плюса

4663 Репутация автора

Хотя 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']);

Затем запустите задание. Ваш файл будет создан. Измените ваш, main.jsчтобы загрузитьnamespaces.js

require(['namespaces'], function () { ... });

Таким образом, теперь позволяет модулям srcиспользовать зависимости с сопоставлением с шаблоном grunt.

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

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

Автор: Nate-Wilkins Размещён: 29.11.2013 05:21

1 плюс

7607 Репутация автора

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

Хотя есть несколько обходных путей:

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

Надеюсь это поможет! Удачного кодирования!

Автор: Cody Размещён: 23.12.2013 11:32

1 плюс

1 Репутация автора

Я написал библиотеку, чтобы решить эту проблему. В конце концов кто-то пришел и улучшил мою библиотеку, вот она:

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]
        }
    });

Затем вы можете потребовать модули в вашем интерфейсе, например, так:

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

Автор: Alexander Mills Размещён: 15.09.2015 12:18
Вопросы из категории :
32x32