Файл rjs.js
// Порядок использования:
//
// 1. Загрузите данный файл первым в качестве зависимости внутри вашего главного JavaScript-файла.
// 2. Как только HTML-страница будет загружена выполните в консоли браузера команды:
// window.rjs.buildTree();
// console.log(window.rjs.tree);
// В результате в объекте window.rjs.tree будет сформировано дерево зависимостей ваших модулей.
// 3. Для формирования списка зависимостей модулей вызовите метод window.rjs.toList().
//
// Методы доступные после загрузки HTML-страницы:
// rjs.buildTree()
// - Формирует карту зависимостей ваших модулей внутри объекта rjs.tree.
// - Выведите значение rjs.tree в консоли браузера, чтобы увидеть карту зависимостей модулей.
// rjs.toList()
// - Возвращает строку со списком зависимостей всех модулей.
// onResourceLoad - это внутренний крюк, который может быть использован для вывода сообщения о том, что модуль был
// создан или он экспортировал свое значение. Таким образом становится возможна отрисовка порядка загрузки модулей и их зависимостей.
requirejs.onResourceLoad = function (context, module, dependeciesArray) {
// context - внутренний объект, испольуемый RequireJS для хранения экспортированных значений и состояния загрузки модулей.
// В данном случае он никак не используется.
// module - объект содержащий информацию о только что загруженном модуле.
// Свойства объекта module:
// module.name - нормализованное имя модуля. Для плагина это просто имя плагина.
// module.url - URL исползуемый для загрузки файла модуля. Может быть относительным путем.
// dependeciesArray - массив зависимостей определенных для данного модуля. Каждый элемент массива это объект module.
// Сформировать глобальный объект window.rjs при загрузке первого модуля
if (!window.rjs) {
window.rjs = {
tree: {} // дерево зависимостей модулей
, buildTree: buildTree // функция формирования карты зависисмостей модулей (определена ниже)
, toList: toList // функция формирования списка зависисмостей модулей (определена ниже)
, toPaths: toPaths
, buildPathsTree: buildPathsTree
, getMainFileTree: getMainFileTree
, drawTree: drawTree
};
}
// Если модуля нет в дереве зависимостей, то добавить объект с данными нового модуля в дерево
if (!window.rjs.tree[module.name]) {
window.rjs.tree[module.name] = {moduleName: module.name, moduleDependeciesNames: [], moduleDependeciesTree: {}, modulePath: module.url ? module.url.split('?')[0] : ''};
// 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);
}
}
// На данном этапе в дерево добавлены имена всех загруженных модулей.
// В массив имен зависимостей всех модулей добавлены имена модулей, от которых они зависят.
// Однако карта зависимостей у всех модулей пока пуста.
};
// Функция формирования карты дерева зависисмостей модулей
// На данном этапе карта зависимостей у всех модулей пока пуста.
// Поэтому данная функция заполняет занчения moduleMap для каждого модуля.
function buildTree () {
var tree = window.rjs.tree
, moduleName
, currentModule
, i
, len
, currentDependencyName;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
for (
i = 0, len = currentModule.moduleDependeciesNames.length;
i < len;
i++
) {
currentDependencyName = currentModule.moduleDependeciesNames[i]; // Взять имя текущей зависимости данного модуля
currentModule.moduleDependeciesTree[currentDependencyName] = tree[currentDependencyName]; // В карту данного модуля добавить объект текущего модуля из дерева
}
}
}
}
// Фунцкия формирования списка зависисмостей модулей
// Данная функция возвращает строку, состоящую из списка зависисмостей модулей
function toList () {
var list = []
, tree = window.rjs.tree
, moduleName
, currentModule
, i
, len;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
len = currentModule.moduleDependeciesNames.length;
if (len) {
for (i = 0; i < len; i++) {
list.push(moduleName + ' < ' + currentModule.moduleDependeciesNames[i]); // Добавить строку вида "moduleName > moduleDependecyName" для каждой зависимости данного модуля
}
} else {
list.push(currentModule.moduleName); // Добавить строку вида "moduleName" для данного модуля
}
}
}
list.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return list.join('\n');
}
// Фунцкия формирования списка путей к файлам модулей
// Данная функция возвращает строку, состоящую из списка путей к файлам модулей
function toPaths () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return paths.join('\n');
}
// Функция формирования дерева путей загрузки модулей
function buildPathsTree () {
var paths = []
, tree = window.rjs.tree
, moduleName
, currentModule;
for (moduleName in tree) { // Для каждого имени модуля, содержащегося в дереве
if (tree.hasOwnProperty(moduleName)) { // Если имя модуля содержится в дереве, то взять объект с данными данного модуля
currentModule = tree[moduleName]; // вида {moduleName: module.name, moduleDependeciesNames: [], moduleMap: {}, modulePath: ''}
paths.push(
moduleName.search('.html') === -1
? currentModule.modulePath.replace('./', '')
: 'js/' + moduleName
); // Добавить строку вида "modulePath" для данного модуля
}
}
paths.sort(function(a, b){if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}});
return convertArrayOfDelimitedStringsIntoHierarchicalObject(paths, '/');
}
// Функция конвертации массива с разграниченными строками в иерархическое дерево
function convertArrayOfDelimitedStringsIntoHierarchicalObject (input, delimiter) {
// input = ['Fred-Jim-Bob', 'Fred-Jim', 'Fred-Thomas-Rob', 'Fred'];
// delimiter = '-';
var output = []
, i, j, k
, inputLength
, chain, chainLength
, currentNode, currentNodeLength
, wantedNode
, lastNode
, newNode;
for (i = 0, inputLength = input.length; i < inputLength; i++) {
chain = input[i].split(delimiter);
currentNode = output;
for (j = 0, chainLength = chain.length; j < chainLength; j++) {
wantedNode = chain[j];
lastNode = currentNode;
for (k = 0, currentNodeLength = currentNode.length; k < currentNodeLength; k++) {
if (currentNode[k].name === wantedNode) {
currentNode = currentNode[k].dependecies;
break;
}
}
// If we couldn't find an item in this list of dependecies
// that has the right name, create one:
if (lastNode === currentNode) {
currentNode[k] = {name: wantedNode, dependecies: []};
newNode = currentNode[k];
currentNode = newNode.dependecies;
}
}
}
return output.length > 0 ? output[0] : {};
}
// Функция выбора главного файла
function getMainFileTree () {
function buildTreeObject (module) {
var treeObject = {
name: module.moduleName
, path: module.modulePath
, dependecies: []
};
for (var key in module.moduleDependeciesTree) {
treeObject.dependecies.push(buildTreeObject(module.moduleDependeciesTree[key]));
}
treeObject.dependecies.sort(function(a, b){
a = a.name;
b = b.name;
if (a > b) {return 1} else if (a < b) {return -1;} else {return 0;}
});
return treeObject;
}
return buildTreeObject(window.rjs.tree['main']);
}
// Функция отрисовки дерева зависимостей модулей
function drawTree (obj, prefix, options) {
if (typeof obj === 'string') {obj = {name: obj};}
if (prefix === undefined) {prefix = '';}
if (options === undefined) {options = {};}
function chr (s) {
var chars = {
'│' : '|',
'└' : '`',
'├' : '+',
'─' : '-',
'┬' : '-'
};
if (options.unicode === false) {
return chars[s];
} else {
return s;
}
};
var dependecies = obj.dependecies || []
, lines = (obj.name || '').split('\n')
, splitter = '\n' + prefix + (dependecies.length ? chr('│') : ' ') + ' ';
return prefix
+ lines.join(splitter) + '\n'
+ dependecies.map(function (module, index) {
var last = (index === dependecies.length - 1)
, more = (module.dependecies && module.dependecies.length)
, prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
return prefix
+ (last ? chr('└') : chr('├')) + chr('─')
+ (more ? chr('┬') : chr('─')) + ' '
+ drawTree(module, prefix_, options).slice(prefix.length + 2);
}).join('');
}
Файл index.js
require.config({
paths: {
onResourceLoad: 'lib/require/rjs'
, main: './main'
}
, urlArgs: '_=' + Math.random()
});
require(
[
'onResourceLoad'
, 'main'
]
, function(
onResourceLoad
, main
) {
main();
if (console && console.log) {
window.rjs.buildTree();
//for (var key in window.rjs.tree) {console.log(key);}
//console.log(window.rjs.toList());
console.log(window.rjs.drawTree(window.rjs.getMainFileTree()));
// console.log(window.rjs.toPaths());
console.log(window.rjs.drawTree(window.rjs.buildPathsTree()));
}
}
);
Файл main.js
require.config({
paths: {
FirstModule: 'app/first/controller'
, SecondModule: 'app/second/controller'
, ThirdModule: 'app/third/controller'
}
});
define(
[
'FirstModule'
, 'SecondModule'
, 'ThirdModule'
]
, function(
FirstModule
, SecondModule
, ThirdModule
) {
return function () {
FirstModule.init();
SecondModule.init();
ThirdModule.init();
};
}
);
Комментариев нет:
Отправить комментарий