Pull to refresh

Helios Kernel (удобный include в Javascript)

JavaScript *
Hello World,

Всё начилось с простой идеи: мне захотелось, чтоб я мог в шапке скрипта написать что-то вроде

include( "path/to/someLibrary.js" );

а ниже использовать объекты, объявленные в скрипте someLibrary.js. Так появилась библиотека Helios Kernel.



Эта библиотека определяет функцию include(), отслеживает зависимости между файлами, и следит, чтоб требуемые исходники инициализировались до того, как будет вызван код их использующий.

В итоге, каждый скрипт выглядит примерно следующим образом:

// инклудим требуемые скрипты
include( "path/to/someLibrary.js" );
include( "path/to/someOtherLibrary.js" );

function init() {
    // эта функция - инициализатор нашего скрипта, здесь можно
    // использовать объекты, объявленные в скриптах, которые мы заинклудили
    someLibrary.doSomething();
    var mySomething = new someLibrary.Something();
    someOtherLibrary.doSomethingElse();
}

Все скрипты, путь к которым передаётся в качестве параметра для include(), должны иметь такую же структуру, то есть, их код должен находится внутри функции init(), и они могут иметь свои зависимости, объявленные через include(). Helios Kernel подключает требуемые скрипты, и инициализирует их в нужном порядке.


Update: Здесь наверное будет уместно пояснить, чем эта библиотека отличается от десятка других библиотек для загрузки скриптов. Helios Kernel предоставляет такой же подход к определению зависимостей между модулями, какой используется во многих других языках программирования и обычно доступен там «из коробки» — это возможность определять зависимости модуля в шапке самого модуля. То есть теперь, если нужно загрузить какой-то модуль, не нужно беспокоиться о том, чтоб предварительно загрузить другие модули, которые ему требуются для работы. Указывать зависимости модуля — задача для автора модуля, а не для его пользователей. Пользователь просто сообщает, что ему нужен какой-то модуль, и библиотека Helios Kernel сама загружает необходимые зависимости и инициализирует их в соответствующем порядке.


Я постарался сделать эту библиотеку максимально простой (в плане функциональности). Она также содержит несколько полезных штук, которые естественным образом её дополняют.

Библиотека объявляет ещё две полезные функции: kernel.require() и kernel.release(), которые могут использоваться для того, чтобы динамически в рантайме загружать и выгружать необходимые скрипты (вместе со всеми зависимостями). Выглядит это примерно так:

// пользователь нажимает какую-нибудь кнопку
// и в контроллере приложения вызывается обработчик
AppController.prototype.doSomethingHandler = function() {
    // обработчик загружает дополнительный код
    this.magicLibraryTicket = kernel.require(
        "path/to/magicLibrary.js",
        function() {
            // и когда этот код загрузился и проинициализировался,
            // использует новые объекты и функции
            magicLibrary.doSomething();
        }
    );
}

// затем пользователь нажимает другую кнопку, означающую,
// что ему больше не нужна дополнительная функциональность
AppController.prototype.stopSomethingHandler = function() {
    // другой обработчик делает необходимые завершающие действия
    magicLibrary.stopDoingSomething();
    // и сообщает, что код можно выгрузить
    kernel.release( this.magicLibraryTicket );
}

Эти две функции (kernel.require() и kernel.release()) информируют библиотеку о том, что понадобился какой-то скрипт (или что какой-то скрипт больше не требуется). Библиотека сама решает, что когда нужно загружать и выгружать — если, например, какой-то скрипт используется ещё и в другом месте, он не будет выгружен по запросу kernel.release().

Кроме того, Helios Kernel умеет управляться со всякими странными ситуациями. Например: у функции kernel.require() есть ещё третий необязательный параметр (помимо пути скрипта, который нужно загрузить, и колбэка, который нужно вызвать, когда этот скрипт загрузится). Этот третий параметр — ещё один колбэк, который вызывается в случае ошибки при загрузке скрипта (если, например, возникли проблемы с сетью, или обнаружилась циклическая зависимость). Путь скрипта, который не удалось загрузить, передаётся в качестве единственного аргумента при вызове этого колбэка.

В библиотеке Helios Kernel также есть удобная функция getStatistics(), которая сообщает детальную информацию о состоянии загружаемых скриптов. Эту функцию можно использовать для того, чтобы проинформировать пользователя о процессе загрузки с помощью какого-нибудь индикатора в интерфейсе.

Более подробно всё описано в документации (290 kb): helios-kernel-0.9-guide.pdf
Загрузить библиотеку можно здесь (8 kb): helios-kernel-0.9.tar.gz
Домашняя страничка проекта тут: home.gna.org/helios/kernel (хотя, там написано примерно то же самое, только кратко и на английском).

Предыстория


Два года назад я опубликовал вот эту заметку: Helios Javascript Framework. В ней я рассказал о том, что замышляю сделать целый фреймворк для разработки веб-приложений, и показал демку с гламурным калькулятором. Эта простенькая демка содержит довольно много кода — по сути там реализована библиотека виджетов. Но для широкого использования эти наработки были малопригодны. Мне хотелось поскорее посмотреть, как оно всё будет работать, поэтому писалось всё на скорую руку, и я даже забил на документацию к коду. Впрочем, документация там и не нужна: это был, что называется, proof of concept, и моя первая попытка написать библиотеку для виджетов (поэтому она весьма ужасна).

По задумке, Helios Framework состоит из набора библиотек, которые работают поверх главной библиотеки, разруливающей зависимости между скриптами. Поэтому у библиотеки Helios Kernel такое «пафосное» название — я надеюсь, мне хватит времени и воли, чтобы дописать и однажды зарелизить весь фреймворк, с либами и виджетами.

В той демке с калькулятором был и свой Helios Kernel, который обеспечивал базовую функциональность для функции include() и загружал нужные зависимости. Но тот kernel был также ужасен и примитивен, как и библиотека виджетов. В общем, я решил, что эксперимент с фреймворком удачен, и нужно им вплотную заняться. И начал писать ядро, но уже вдумчиво, для людей и с документацией.

Для меня этот проект — что-то вроде антипода тому, чем я занимаюсь по работе. Здесь нет бюджета, заказчика со своими пожеланиями, дедлайнов и ограничений. Иногда я месяцами не работал над проектом, а иногда наоборот фигачил с утками напролёт. Пару раз было так, что у меня возникала идея, что можно вообще всё переделать совсем по-другому, и тогда будет работать лучше/быстрее, и я так и делал — переписывал всё с чистого листа. И это продолжалось до тех пор, пока я не привёл Helios Kernel в некоторое «идеальное» состояние (по моему мнению). Ну а результат вы можете увидеть выше.

Теперь я буду думать, что кодить дальше. Надеюсь, следующий мой отчёт будет раньше, чем через два года :-)
Tags:
Hubs:
Total votes 62: ↑53 and ↓9 +44
Views 6.9K
Comments Comments 43