Hello World,
Всё начилось с простой идеи: мне захотелось, чтоб я мог в шапке скрипта написать что-то вроде
а ниже использовать объекты, объявленные в скрипте someLibrary.js. Так появилась библиотека Helios Kernel.
Эта библиотека определяет функцию include(), отслеживает зависимости между файлами, и следит, чтоб требуемые исходники инициализировались до того, как будет вызван код их использующий.
В итоге, каждый скрипт выглядит примерно следующим образом:
Все скрипты, путь к которым передаётся в качестве параметра для include(), должны иметь такую же структуру, то есть, их код должен находится внутри функции init(), и они могут иметь свои зависимости, объявленные через include(). Helios Kernel подключает требуемые скрипты, и инициализирует их в нужном порядке.
Update: Здесь наверное будет уместно пояснить, чем эта библиотека отличается от десятка других библиотек для загрузки скриптов. Helios Kernel предоставляет такой же подход к определению зависимостей между модулями, какой используется во многих других языках программирования и обычно доступен там «из коробки» — это возможность определять зависимости модуля в шапке самого модуля. То есть теперь, если нужно загрузить какой-то модуль, не нужно беспокоиться о том, чтоб предварительно загрузить другие модули, которые ему требуются для работы. Указывать зависимости модуля — задача для автора модуля, а не для его пользователей. Пользователь просто сообщает, что ему нужен какой-то модуль, и библиотека Helios Kernel сама загружает необходимые зависимости и инициализирует их в соответствующем порядке.
Я постарался сделать эту библиотеку максимально простой (в плане функциональности). Она также содержит несколько полезных штук, которые естественным образом её дополняют.
Библиотека объявляет ещё две полезные функции: kernel.require() и kernel.release(), которые могут использоваться для того, чтобы динамически в рантайме загружать и выгружать необходимые скрипты (вместе со всеми зависимостями). Выглядит это примерно так:
Эти две функции (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 в некоторое «идеальное» состояние (по моему мнению). Ну а результат вы можете увидеть выше.
Теперь я буду думать, что кодить дальше. Надеюсь, следующий мой отчёт будет раньше, чем через два года :-)
Всё начилось с простой идеи: мне захотелось, чтоб я мог в шапке скрипта написать что-то вроде
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 в некоторое «идеальное» состояние (по моему мнению). Ну а результат вы можете увидеть выше.
Теперь я буду думать, что кодить дальше. Надеюсь, следующий мой отчёт будет раньше, чем через два года :-)