Pull to refresh

Comments 87

Прочитал «Идея и миссия фреймворка» — так и не понял что это, для чего и зачем, причем абсолютно. Дальше не читал. Думаю стоит сразу описать суть идеи в паре предложений, иначе людям не понять — надо ли это им. Ну это мое мнение, учесть его или нет — ваше дело.
Цель — не создать крутой фреймворк, а изучить и раскрыть подходы для его создания.
Тогда, возможно, желающим сделать это — будет намного легче, когда есть детально описанный опыт, код и идеи.
А может и стоящий проект получится.
Не вижу смысла, я написал просто и понятно и на родном языке чего мне не понятно и чего мне не хватает — вы или не вы просто минусуете и все:) — флаг в руки. Мне до сих пор не понятно «что это и зачем». Продолжайте минусовать, хоть неадекватов посчитаем. А так жаль, что статья тесть, а толку в ней пока не могу найти.
Ну смотри, ты вот jQuery интересуешься, выкатываешь неплохую статью под названием «Оптимизируем производительность селекторов jQuery». Первым же комментом от Dimon012 получаешь: «Вообще не понял что это, для чего и зачем, дальше не читал». Что начнешь делать? Объяснять, что такое производительность, что такое селекторы или что такое jQuery?
Я даже не знаю, но дело в том что с js т.п. в какой-то мере знаком, с web-разработкой тоже. О чем тут не понимаю. Ну блин дайте ссылки что прочесть, раз разъяснить не можете о чем тут написано.
в общем написано все довольно интересно
Но посту наверное всеже не на главной, так как местный пролетариат не понимает.
Хотя, если бы я тут описал бы тоже самое например на lua — меня бы, наверное, совсем бы никто не понял.
Так что сегера — впиливай в тему, как говорил макс фрай
Тему чего?:) я так и не добился этого. JS я знаю, MVC тоже не первый год применяю, тут о чем?:)
про MVC тут вообще ни слова.
Тут вообще пара базисов триксов с муутоолс и ничего особенного.
Но чужой expirence всегда полезен и интересен.
Я вот узнал новый способ анонимизировать создания классов.
Раньше такого и не знал, и завтра забуду.
Но где-то в спинном мозге останеться
Спасибо, хоть один человек понял, чего я хочу, буду изучать, авось и прок этой статьи пойму:)
Дык это же в названии статьи указано:)
Считайте что я самый тупой на свете и я не в курсе о чем речь, но я знаком с web-разработкой и хотелось бы узнать новое.
можно погуглить, узнав смежные тематики, что такое node.js, что такое javascript, что такое сервер, что такое интернет. я не знаю, какой у вас пробел в знаниях этого вопроса, но я не могу каждый топик начинать с нуля. везде есть какая-нибудь отправная точка, остальное, если вдруг забылось, гуглится. или хотя-бы спрашивается, например «Ребята, что такое node.js?», вместо «Ничерта не понял, топик — дерьмо, дальше первого абзаца не читал»
Node.js MVC Framework, все ведь понятно уже из названия, разве нет?
Вай-вай в карму гадят негодяи:) Мне не понятно что это и с чем это едят, я об этом написал, попросил объяснить — в итоге ничего не объяснили, выставили дураком, спасибо.
Отличная статья! Спасибо! Как раз в кассу, хотел заняться node.js!
Если в указаном примере mootools заменить на что-то более подходящее по смыслу — получилось бы еще лучше.
Я про то — что если и экпортировать классы в семантическое пространство имен — то делать это до конца
могло бы получиться что-то типа
SAPI.implimentClass('map.entity.NavRect',{
	 Extends:['map.overlay.rect',
			  'map.entity.zbase',
			  'map.overlay.standartTooltip'],
	 
	 getTemplate:function(){......

В примере правда еще множественное наследование, примеси и декораторы в одном стакане
В Мутулз тоже все это есть. Очевидных преимуществ не вижу.
В упорстве
exports['Helper.AnotherClass'] = function (spirit) {
	var mysql = spirit.loadLib('mysql-libmysqlclient');
	
	return new Class({
		Extends : spirit.load('Name.Space.ClassName'),

равнозначно
(function (spirit) {
	var mysql = spirit.loadLib('mysql-libmysqlclient');
	
	var sometmpval=new implimentClass('Helper.AnotherClass',{
		Extends : 'Name.Space.ClassName',
...
})();

Тоесть — если переходите на использование справочника имен классов — переходите :)
Надо всего-то рядом с moo положить кусочек dojo
Extends : 'Name.Space.ClassName', — и какой класс он включит? смогу ли я подключить класс Name.Space.ClassName из фреймворка, если такого нету в приложении. И смогу ли я насильно его подключить из фреймворка, даже если он есть в приложении?
Смотрите последний пример с переопределением метода exports['Router.Regexp']
Второй вопрос — где тут возьмется spirit? Разве что записать так:
exports = function (spirit) {
	var mysql = spirit.loadLib('mysql-libmysqlclient');
	
	var sometmpval=new implimentClass('Helper.AnotherClass',{
		Extends : 'Name.Space.ClassName',
...
};

Но с таким подходом я мог отказатся и от индекса у себя, но правило писать индекс введено специально — для дополнительного контроля за ошибками, который с implimentClass('Helper.AnotherClass' на уровне Spirit не получится.

вообще код который я привел должен был выглядеть как
(function (spirit) {
	var sometmpval=spirit.implimentClass('Helper.AnotherClass',{
..})(somespiritinst);

Тоесть можно четко указать некий экземпляр или ветку которая будет разрешать имена.
Да и разрешать можно их как угодно.
Например изначально добавляя в начало или конец имени параметры модуля. Чтобы потом иметь возможность выбрать нужный.
И написать, например, Extends: 'Name.Space.ClassName|core' — это как раз тот момент который дает больше возможностей чем ограничений.

Хитрый вопрос номер два — в примере с логеров в роутере — как можно написать код так чтобы логирование могло вызваться до или после, или и до и после оригинальной функции, и при этом бы не содержало явный вызов парента. А просто бы работало как нормальная функция нормального декоратора?
а как вы spirit в функцию передавать собрались? вот у нас есть файл "/Classes/Helper/AnotherClass.js". Где вы возьмете somespiritinst в нем?

и при этом бы не содержало явный вызов парента.

А зачем? Вы мне ставите странные условия, которые не имеют смысла.
exports['Class.Name'] = function (spirit) {
	return new Class({
		Extends : spirit.load('Class.Name', true),
		method : function () {
			log('method', 0);
			this.parent();
			log('method', 1);
		}
	});
};
В чем смысл использования nginx перед nodejs? Насколько я понял нож сам очень хороший вариант для раздачи статики.
Сам он статику раздавать не умеет. Нужно писать свой модуль. Как бы читать файл и отдавать его большой проблемы нет, но если сделать все по хорошему — надо отдавать много всяких заголовков — Content-Length, Last-Modified — это первое что приходит в голову. А правильный mime отдать для Content-Type — вай, а кеширование — Cache-Control, If-Modified-Since, 304 статус отдавать когда надо, все варианты правильно разрулить. Все как бы решаемо, но проще nginx использовать.
nginx проверенный годами тесак и ножи пока его не заменят.
к тому же в ноде надо будет все же пусть и маленький но скриптик написать для чтения/отдачи файлов.
в общем, за nginx как-то спокойней.
Пока одно приложение/сайт на сервере крутится, можно обойтись и без nginx. А вот когда захочется второй сайт на том же сервере запустить, достаточно будет подправить конфиг nginx, чтобы он раскидывал запросы к разным сайтам на разные порты.
по производительности в отдаче статики nodejs ненамного, но всё же быстрее nginx, просто нужно написать нормальный модуль для отдачи статики
Когда смотрел презенташки по nodejs видел, что у кого-то проскакивал график сравнения, и там nodejs выдерживал больше конкурентных запросов, чем это делал nginx при одной и той же latency. Но чего-то теперь я эту презенташку не могу отыскать, но зато когда искал, нашёл более убедительное сравнение, что в статике nginx всё же уделывает nodejs, особенно на больших файлах — на них response time nodejs взмывает вверх, тогда как nginx остаётся на том же уровне.

так что беру свои слова назад :)
оки. но на самом деле еще в нгинкс — это просто удобно)
3. Создание каркаса фреймворка

Заклинило на этом пункте. ЕМНИП, «framework» как раз и переводится как «каркас».
Извините за оффтоп :)
ага, тоже думал об этом, но как сказать корректнее не придумал.
Может быть «скелет фреймворка» подойдёт?
По идее addRoutes из роутера нужно пробрасывать сначала в хелпер, потому что роутер не должен знать ни о каких регекспах, иначе зачем вообще хелпер.
согласен, есть рациональное зерно
Больше каркасов хороших и разных.

>В директорию lib мы будем сбрасывать все необходимые нам библиотеки.
Не малую часть поста и множество работ над «фреймворком» сократится если использовать канонический путь загрузки оных в ~/.node-libraries и/или npm. И с путями проще и с загрузкой и с обновлением и т.д.

>return new Class(
Вот этот стиль мне тоже не особо нравится использовать в js. Надо будет глянуть в паттерны и их производительность, не зря же он мне не нравится.

По библиотекам согласен, но одно дело складывать в общие для проектов папки атомарные модули, и совсем другое — файлы контроллеров. Доступ к контроллерам из других проектов — наверное, не совсем правильно по соображениям секьюрности. Тут автору лучше использовать что-то вроде nodules или на крайний случай использовать require.paths.unshift, что впрочем не снимает всех проблем с секьюрностью.
>По библиотекам согласен, но одно дело складывать в общие для проектов папки атомарные модули, и совсем другое — файлы контроллеров. Доступ к контроллерам из других проектов — наверное, не совсем правильно по соображениям секьюрности.

Секьюрность однако. Не знаю при чем она тут, но я о том чтобы хранить файлы сторонних библиотек в созданной для них же нодой директории. Говоря о папке lib, в описанной выше структуре каталогов, мы как раз про них и говорим.
А «контроллеры» проекта, как я понимаю, хранятся у каждого свои где-то в engine/classes.
А, тогда все понятно. Мне подумалось, что вы о том, чтобы сложить контроллеры в .node-libraries и грузить их обычным require, тогда и кода бы поуменьшилось. А вы имели ввиду сам spirit и mootols — здесь вы точно правы, такие вещи нужно складывать в общие директории.
Что не понравилось.
1. Все «домашние библиотеки лежать в ./node_libraries» как тут уже сказали
Но если не хочеться, то проше сделать require.paths.unshift(__dirname + "/path/to/my/lib");
2. exports['Helper.AnotherClass'] — это похоже на извращение.

А в целом, ваш MVC framework больше напоминает обычный router, которых хватает для nodejs
Есть expressjs, он добавляет обратоку форм, парсит querystring, добавляет подержку шаблонизаторов, да и роутер там по симпатичнее, лучше пока не нашел.
MVC frameworkа еще нету. expressjs видел и использовал. я так и не понял, как согласно их философии разные ф-ции обработки роутов скинуть в директорию в отдельные файлы, чтобы не загромождать один.

1. и mysql-libmysqlclient пришлось бы иклудить так:
require('mysql-libmysqlclient/mysql-libmysqlclient');
2. мне особо нравится, как оно подсвечивается что в IDE, что здесь, на Хабре. если бы не это преимущество, то искал бы другой путь.
expressjs видел и использовал. я так и не понял, как согласно их философии разные ф-ции обработки роутов скинуть в директорию в отдельные файлы, чтобы не загромождать один.

Способов масса, первое, что приходит в голову:

app.get('/blog/posts/:id', function(req, res, next){
    require('./controllers/blog-posts')(req, res, next);
});

а в файле ./controllers/blog-posts.js:

module.exports = function(req, res, next){
    // .... обработка роута
}

Код, который загружается через require, компилится и кешируется, и после разогрева приложение летает :).

Вообще expressjs — очень хороший, стабильный и быстрый движок на node с очень качественным набором middleware, в том числе и роутером. Я вот тоже пишу свой MVC-велосипед, но уже поверх expressjs. Хотя, если учитывать ваши цели — вскипятить интерес к node, то свой велик с нуля тоже нужная вещь :)
Первый очевиден, но не очень красив) на самом деле стоило написать тогда уже так:

app.get('/blog/posts/:id', require('./controllers/blog-posts'));

Что, впринципе, приемлимый вариант. Но лично я не люблю указывать все роуты. Пусть лучше оно само ищет подходящий контроллер, а роуты оставим на крайний случай.

Я не согласен с тем, что писать велосипеды — это плохо. Вот был прекрасный фреймворк prototype. А что было бы, если автор JQuery подумал бы, что писать велосипеды это плохо? Не было бы не менее прекрасного, но совершенно другого фреймворка JQuery.
Так я ж за велосипеды :)
они как бы не конкуренты изначально были. это теперь они уже набрались друг у друга и стали конкурировать.
ну дык и я не конкурент expressjs =)
> Все библиотеки, в т.ч. и Spirit будут находится в директориях отдельных от сообственно приложений — это позволит держать несколько приложений на одном сервере, не дублируя список всех библиотек.

а при обновлении либ для одного приложения будем в срочном порядке допиливать все приложения под новые версии либ?

> Каждое приложение имеет две ключевые директории — engine, в которой мы будем хранить серверную логику и public, весь контент которой мы будем отдавать клиенту.

тогда уж private и public надо

> немного расширил прототип строки, добавив методы htmlEscape, ucfirst и lcfirst.

а как же regexpEscape, uriEscape, realMySqlEscape?

> var libPath = __dirname + '/../../lib';

чем это отличается от `var libPath = './../../lib';`?
чем это отличается от `var libPath = './../../lib';`?

Почти ничем. Кроме того, что когда я писал сокращатель ссылок, в котором стоял такой код:
fs.readFile('./index.html'

Все отлично работало у меня на компе ровно до того момента, пока я не вынес его на сервер, не оформил как демон. Когда оформил как демон — перестало видеть этот файл впритык. Помог следующий код:
fs.readFile(__dirname + '/index.html'


regexpEscape

под названием escapeRegExp

uriEscape

В Javascript под названием escape, encodeURI, и encodeURIComponent

realMySqlEscape?

conn.escapeSync() в mysql-libmysqlclient

тогда уж private и public надо

в привате разные папки могут быть: logs, engine. public — это дополнительный намек, что папка не защищенная.

а при обновлении либ для одного приложения будем в срочном порядке допиливать все приложения под новые версии либ?

Стабильные версии Либ обычно одного апи. Можно ввести версионность. Например «mootools-1.2». Но вообще — надо развивать своё приложение и старатся следовать api последних версий библиотек.
chdir( __dirname ) не спас бы отца русской демократии?

> под названием escapeRegExp
> В Javascript под названием escape, encodeURI, и encodeURIComponent
> conn.escapeSync() в mysql-libmysqlclient

почему они не в свойствах строки?

> в привате разные папки могут быть: logs, engine. public — это дополнительный намек, что папка не защищенная.

а по поводу остальных папок предлагается гадать, защищённая она или нет?

> Но вообще — надо развивать своё приложение и старатся следовать api последних версий библиотек.

надо, но это не все же приложения одновременно переписывать под новые версии?
остальные папки — защищенные. очевидно ведь.
ни капельки. особенно в свете того, что пустые папки имеют свойство пропадать
можете использовать такой формат директорий, который вам удобен и очевиден. можете даже выложить его схему здесь, в комментах
> чем это отличается от `var libPath = './../../lib';`?
Различной обработкой симлинков, хотя и так иногда косяки вылезают.
> /articles-15/page-3

минус — плохой разделитель. /artist-vienna+teng/page-3

>
> /articles-15/page-3

минус — плохой разделитель. /artist-vienna+teng/page-3

> </article-:D/page-:D

к чему этот куцый велосипед?

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

сам не люблю все эти роуты, но иногда они позволяют достичь красивых адресов, которые не достичь без них
нужно вывести на страницу 2 другие страницы. как передать параметры этим 2 страницам сохраняя читабельность урла? подгружаемые страницы могут быть произвольными.
я вас не понял. что это значит и зачем может применятся?
нужно сравнить 2 ревизии 2 форков 2 файлов из проекта на гитхабе. какой ты сделаешь урл такой страницы?
такую штуку буду делать через get параметры, для чего они и созданы, имхо

example.com/compare?file1=cffc1324&file2=ffdfdfd
если очень критично чпу можно сделать банально так:
example.com/compare/cffc1324/ffdfdfd
(мы можем сравнивать две ревизии одного файла, потому путь не подходит, надо именно код ревизии указывать)
example.com/compare/cffc1324/ffdfdfd — это не чпу
в чпу должны быть имена мейнтейнеров форков, пути к файлам (файл может быть перенесён и переименован), названия веток или номера ревизий
кому такое чпу нужно? может вы в урл еще и весь контент страницы засунете?
покажи, как ссылка сделана на гитхабе
там нет такого функционала
а как ты представляешь такой урл?
а хз о0"
думаю что-то типа

compare|file:p/a/t/h:master|file:p/a/t/h:branch

то есть на каждом уровне свой сепаратор. символ разделитель определяется символом после первого слова
compare|file:p/a/t/h:master|file:p/a/t/h:branch
file:p/a/t/h:master
file|p/a/t/h|master
p/a/t/h

понял. добавил в топик раздел, где описано, как я вижу решение этой проблемы.
кстати, если настоиваете именно на таком шаблоне, как показали, то route можно переписать так:
"</compare|:P|:P>"

я бы хотел чтобы это был универсальный парсер, а не нагромождение роутов. что-то типа:

(\w+)([|/\\:])(?:\2([\s\S]*))*
мне автоматическую коробку передач
эта хрень: (\w+)([|/\\:])(?:\2([\s\S]*))* — это фаллоиммитатор, а не автоматическая коробка передач
я задел больную тему?
=) удачи с автоматической коробкой передачи
скажи, какой урл хочешь получить и я скажу, как бы я его оформил
Сами разрабатывать собираетесь или можно поучаствовать?
в топике указано в разделе «Идея и миссия фреймворка» ;) Напишите мне, если есть предложения)
UFO just landed and posted this here
Sign up to leave a comment.

Articles