пятница, 5 июня 2015 г.

JavaScript Build Require JS Tree Visualization

Файл rjs.js

// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
//    (Подробнее смотрите на странице https://github.com/jrburke/requirejs/wiki/Internal-API:-onResourceLoad)
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
//     window.rjs.buildTree();
//     console.log(window.rjs.tree);
//    В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования дерева зависимостей модулей в формате UML вызовите метод window.rjs.toUml().
//    Результат работы метода вы можете использовать здесь: http://yuml.me/diagram/scruffy/class/draw
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toUml()
// - Возвращает строку в формате UML, которая может быть использована для построения UML-диаграммы.
// - UML Website: http://yuml.me/diagram/scruffy/class/draw

// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {

    // context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей
    // В данном случае он никак не используется.
   
    // module - объект содержащий информацию о только что загруженном модуле.
    // Свойства объекта module:
    // module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
    // module.parentMap - объект модуля, используемый для решения задачи относительных ID для данного модуля. Может быть null, но если существует, то имеет ту же структуру, что и объект module.
    // Дополнительно можно использовать следующие свойства объекта module:
    // module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
   
    // dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
   
    // Сформировать глобальный объект window.rjs при загрузке первого модуля
    if (!window.rjs) {
        window.rjs = {
              tree: {} // дерево зависимостей модулей
            , buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
            , toUml: toUml // функция формирования дерева зависисмостей модулей в формате UML (определена ниже)
        };
    }

    // Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
    if (!window.rjs.tree[module.name]) {
        window.rjs.tree[module.name] = {moduleDependeciesNames: [], moduleMap: {}};
        // moduleDependeciesNames - массив имен модулей, от которых зависит данный модуль
        // moduleMap - карта зависимостей данного модуля
    }
   
    // Для формирования полного дерева зависимостей модулей друг от друга
    var i, len;
    if (dependeciesArray) { // Если у модуля есть зависимости, то
        for (
            i = 0, len = dependeciesArray.length;
            i < len;
            i++
        ) { // добавить в массив имен зависимостей имена модулей, от которых зависит данный модуль
            window.rjs.tree[module.name].moduleDependeciesNames.push(dependeciesArray[i].name);
        }
    }
   
    // На данном этапе в дерево добавлены имена всех загруженных модулей.
    // В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
    // Однако карта зависимостей у всех модулей пока пуста.
   
// Для формирования простого дерева зависимостей данного модуля
//    if (module.parentMap && module.parentMap.name) {
//        if (!window.rjs.tree[module.parentMap.name]) {
//            window.rjs.tree[module.parentMap.name] = {moduleDependeciesNames: [], moduleMap: {}};
//        }
//        if (module.parentMap.name !== module.name) {
//            window.rjs.tree[module.parentMap.name].moduleDependeciesNames.push(module.name);
//        }
//    }

};

// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
    var tree = window.rjs.tree
        , moduleName
        , currentModule
        , i
        , len
        , currentDependencyName;
    for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
        if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
            currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
            for (
                i = 0, len = currentModule.moduleDependeciesNames.length;
                i < len;
                i++
            ) {
                currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
                currentModule.moduleMap[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
            }
        }
    }
}

// Фунцкия формирования дерева зависисмостей модулей в формате UML
function toUml () {
    var uml = []
        , tree = window.rjs.tree
        , moduleName
        , currentModule
        , i
        , len;
    for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
        if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
            currentModule = tree[moduleName]; // вида {moduleDependeciesNames: [], moduleMap: {}}
            for (
                i = 0, len = currentModule.moduleDependeciesNames.length;
                i < len;
                i++
            ) {
                uml.push('[' + moduleName + ']->[' + currentModule.moduleDependeciesNames[i] + ']'); // Добавить строку вида [moduleName]->[moduleDependecyName] для каждой зависимости данного модуля
            }
        }
    }
    return uml.join('\n');
}

Файл index.js

require.config({
      paths: {
          onResourceLoad: 'lib/require/rjs'
        , FirstModule: 'app/first/controller'
        , SecondModule: 'app/second/controller'
        , ThirdModule: 'app/third/controller'
      }
});

require(
    [
          'onResourceLoad'
        , 'FirstModule'
        , 'SecondModule'
        , 'ThirdModule'
    ]
    , function(
          onResourceLoad
        , FirstModule
        , SecondModule
        , ThirdModule
    ) {
   
        FirstModule.init();
        SecondModule.init();
        ThirdModule.init();
       
    }
);

Комментариев нет:

Отправить комментарий