Другой IncludeJS

    Только не смейтесь. Наверное это самая лучшая вводная фраза — так как ну на самом деле, «Как? Ещё один сборщик скриптов?». Да, в посте пойдёт речь о ещё одной «личной наработке ». Постараюсь не просто вбросить ещё одну либу, а поразмышлять над тем, чем же это решение могло бы быть лучше миллиона других. Возможно у меня не получится донести до вас, все как есть, но я попытаюсь, а вы не судите строго. Это будет вторая статья в серии о компонентах и MVP. Если интересно можете ознакомиться с первой.

    Проблема компонент


    Часто компоненты/виджэты помимо скриптов состоят из других ресурсов — html разметки, стилей, картинок, компонентов. И вот, хотелось бы получить сборщик этих самых ресурсoв. Во время разработки указываете путь к директории с компонентами/библиотеками, подключаете нужное, а во время сборки html склеится в один, стили и javascript тоже, картинки скопируются в наше приложение — «Кушать подано». Прошу не пинать больно, такие «конструкторы» уже наверняка существуют, но подходящего я не нашёл — и к тому же, моей целью было не создать конкурирующий продукт, а сделать нужную мне вещь для себя.

    Здесь(github) эту вещь можно скачать/глянуть на апи. Того, кому эта тема показалась интересной, и кто готов уделить 10 минут на эту неумелую писанину, приглашаю под кат.



    Немного истории, или что такое правильный велосипед


    Если честно, мне немного неловко называть вещи «правильными» или писать «как надо что-то делать» — ведь это все субъективно, поэтому так к этому и относитесь.
    Когда перед нами стоит задача, мы оцениваем какие инструменты у нас есть для её решения, а каких нету. Также думаем, что могло бы ускорить процесс. И вот если мы решили немножко, совсем чуть-чуть, подправить существующий инструментарий — всё, первый шаг в сотню миль к велосипеду сделан. Должно быть решено ещё много подобных задач, где по кирпичику будем выстраивать функционал. Не всё переживёт поставленные задачи, где-то мы плюнем и возьмём готовые библиотеки. А где-то просто отпадёт нужда в этих самых «чуть-чуть доделать», и тогда подобно воде, которой некуда течь, превратится в болото. Но болото, это не плохо, а напротив — оно даёт жизнь миллионам видам.
    Но если инструментарий пережил, это множественное «чуть-чуть доделывание», то в результате, мы получим «Вещь», где мы узнаем каждую запятую или наоборот, будущий Я удивится и посмеётся над Я настоящим. Где уже с лёгкостью добавляем, изменяем, правим функционал. Где ощущается ветер свободы, когда эта «Вещь» делает, то что ты хочешь, и так, как ты этого хочешь. Прошу прощение за это лирическое отступление.

    А сама история — банальна


    • Надоело писать весь скрипт в одном файле? — Разбиваем на несколько.
    • Файлов стало больше и надоело все подключать в index.html? — Немного динамики: создаём и вставлаем в dom
      Скрипты требуют стили и ajax? Вот тэг link с атрибутом href и xmlhttprequest с onreadystatechange
      Скриптам надо знать, когда вложенные/рекурсивные ресурсы загружены? Сейчас используется дерево ресурсов и eval. За eval не ругайтесь, так как первое, он упрощает нам обработку зависимостей, и таким образом нам не надо нигде больше указывать (в никаких package.json файлах), что это за модуль и что он требует. А также не надо строить конструкций вида «define». И второе, цель ведь у нас будет — собрать приложение, вот там-то этот eval уже будет отсутствовать (кроме ленивых скриптов, см. ниже). Хотя должен отметить, что даже если и не собирать приложение, то в этом eval-e нет ничего криминального, так как используется по назначению, одинаково быстр как и подключение скрипта через тэг и не является проблемой безопасности (если злой человек смог дойти до возможности использовать этот eval, то собственно он ему уже даже и не нужен).
      Нужен ленивый скрипт, который будет доступен сразу по требованию (без никаких IDeferred)? Схема простая: XMLHTTRequest → __defineGetter__ → eval. Из примера:
      include.lazy({'ui.notification':'path'}), и как только мы вызовем ui.notification./**eval происходит сейчас, далее вызываем функцию*/show('Hello World'); Обращу внимание, на то, что модуль должен быть с учётом того, как и что возвращает функция eval.
      Нужна удобная обработка путей и маршрутизация? "utils.js" — путь относительный к родительскому. "/utils.js" — путь относительный к приложению. .js({ dom: "zepto" }) — перед этим зарегистрируем наш маршрут dom: .cfg({dom: "/scripts/dom/{name}.js"}).
    • простой и неправильный пример диалогового окна, но не это главное — главное, что бы вы увидели, как просто подключается отдельный ресурс, с картинками, стилями и html разметкой. Здесь же немножко показал MaskJS в действии, а в следующей статье к ним подключится библиотека компонент, и это совсем будет торт. Хотя это снова же субъективное мнение, возможно все это ерунда, но она помогает приятно разрабатывать html5 приложения. Если знаете похожие инструменты, поделитесь ими. Также хочу предупредить, что пока это все очень сырое, но я буду продолжать над этим всем работать — приносит море удовольствия. Если бы такая штука была полезна кому-то, тогда было бы больше мотивации. Но если нет, и того хватит, что есть ;)

      Удачи.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 8

      +2
      > Если знаете похожие инструменты, поделитесь ими.
      brunch.io/ начал недавно юзать, удобно.
      github.com/cowboy/grunt
        0
        grunt уж совсем банальный — дали ему список скриптов — он собрал. A вот brunch похоже хорош, больше возможностей, но тот же принцип — собираю все что в папке по алфавиту. Или тот же конфиг файл, как у грант. Но во многих случаях и этого достаточно. Спасибо, что поделились.
          0
          Как, на ваш взгляд, должна работать конкатенация скриптов? Что именно тулза может делать автоматом?
            0
            Важно (покрайней мере мне), что бы зависимости не лежали списком в отдельных файлах, и тем более не в одном, как у инструментов выше ( это получается, если я хочу подключить доплнительный модуль, я должен указать путь к ниму, и вспомнить его зависимости, что бы тоже указать в файле для сборки. А этих зависимостей может быть много, и не только скрипты, но и хтмл, и стили). Если я хочу подключить один javascript файл, он сам должен подключить, всё что ему надо. Если он подключил другой javascript, тот в свою очередь, подключает свои зависимости, ну и т.д. Тут как раз самое важно — контекст подключение ресурсов — он должен быть в управлении самих скриптов. Вот мы и получили систему подключения ресурсов, она может работать и без сборки. По скорости не уступает разным AMD системам, и если честно, если приложение не большое, я даже редко и собираю. А вот если побольше, тут и вступает сборщик ресурсов. Собсвенно он просто склеивает ресурсы — скрипты, стили, шаблоны, ленивые скрипты(что не мало важно в большых приложениях) — но берет он это все от системы подключения ресурсов. Ну вот наверное это все по конкатенация скриптов.
              0
              Полностью согласен, однако это немного не в компетенции билдеров, скорее данные функции должны выполнять менеджеры зависимостей.

              В любом случае, бранч скоро получит поддержку оных (twitter bower, tj holowaychuk component.js) и, думаю, вопрос будет решен.
        0
        не, ну как-то слишком сложно)

        как у него с поддержкой ie9-? во время подгрузки скриптов жизнь в браузере замирает?

        я вот остановился на такой схеме: всё приложение делится на набор пакетов, пакеты на модули, в модулях уже скрипты, стили, картинки, шаблоны. сборщик пробегается по ним и «собирает пакеты». шаблоны в одну кучку, стили в другую, скрипты в третюю. при этом статически же определяются зависимости: из шаблонов определяется какие компоненты используются и подключаются одноимённые модули (целиком, со всеми ресурсами и их зависимостями), аналогично разруливаются зависимости между скриптами (используется простое соглашение: $jam.Component — модуль Component из пакета jam). в результате получается на каждый тип файла два варианта — отладочный с пофайловым подключением и релизный со слиянием воедино. есть ещё вариант со сквозной минификацией, когда атомы (http://habrahabr.ru/post/97670/) в шаблонах, стилях и скриптах заменяются на короткие

          0
          Сложно? Ничего сложного, заинклудили ресурсы — готово. Можна даже не собирать все в кучу, все будет прекрасно подгружатся, задумались о релизе — собрали. С поддержкой ие вам точно не скажу. Это все дело хорошо протестировано на wебкитах, так как сам я разрабатываю хтмл5 приложения для десктопов и мобилных с wебкит-контэйнером.
          Скрипты и прочие ресурсы подгружаются асинхронно, так что ничего не замирает. А jam использует reuirejs? или я нето нашел?
            0
            сложность в том, что нужно настраивать, инклудить. куда удобней иметь какой-нибудь аналог автолоада из пхп. причём автолоада целиком модуля (клиентские скрипты, стили, локали, серверные скрипты, документация, шаблоны).

            в иешках проблема с __defineGetter__

            а в геттере только eval происходит, но загрузка должна быть произведена заранее асинхронно?

            не то. там у меня ещё всё сыро.
            jam — микроядерный яваскриптовый фреймворк nin-jin.github.com/jam/jam/jam.doc.xml
            по ссылке собственно пример собранной документации.
            сборщик написан на коленке. пока собирает сразу все пакеты и не умеет вычитать модули одного из другого. github.com/nin-jin/web-components/tree/master/so/Compile

        Only users with full accounts can post comments. Log in, please.