JavaScript|HTML Preprocessor

    Здравствуйте, дорогие друзья!


    В один чудесный день в один чудесный час возникла острейшая необходимость в JS|HTML препроцессоре и как обычно поиск готового решения не увенчался успехом, везде чего-то не хватало (не было глобальных переменных, вставки строк, замены строк, импорта и т.п.). Ну и поскольку я суровый якутский парень, то выход был один — сделать все самому. Ну? что ж, результат моего труда я решил выложить на мнение комьюнити.

    Введение



    Препроцессор предназначен для js(json) и html(xhtml) файлов, эти файлы должны быть с соответствующими расширениями. Препроцессор поддерживает следующий ряд функций:

    • Вставка по условию и без (поддерживается многострочность)
    • Замена строки\строк\подстрок по условию и без (поддерживается замена части строки/строк (да одна управляющая конструкция может заменять части сразу в наборе строк), которая удовлетворяет регулярному выражению)
    • Поддерживаются глобальные переменные (определяются в отдельном файле) и локальные переменные, определяемые внутри файла (имеют больший приоритет)
    • Импорт файла по условию и без, при этом css файлы, при соответствующей настройке в управляющей конструкции, обрамляются тэгом style


    Для вставки управляющих конструкций используются комментарии, по-этому они не мешают работе кода до обработки препроцессором.

    Способ запуска



    Препроцессор представляет из себя обычный groovy скрипт, которому необходим один обязательный аргумент:

    project.sourceDir — путь к начальному каталогу, в котором будет происходить замена.

    а также можно указать два необязательных

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

    Для запуска по мимо стандартных средств можно использовать и maven.

    Операции



    Внимание атрибуты в операциях должны следовать в строгом порядке (порядок будет описан напротив команды ниже), но необязательные атрибуты (pattern, if, type) можно не использовать, ниже я помечу их ?. В любой операции, кроме define, последним атрибутом может быть if=^condition^, где condition — условие, если оно записано в формате key=value, то операция выполнится если значение глобальной или локальной переменной с именем key совпадает с value, в другом случае операция выполнится, если существует глобальная или локальная переменная с именем condition.

    Далее я приведу полный набор операций и их использование в примерах, я не буду приводить примеры с if так как, как его использовать я описал выше.

    Открывающая и закрывающая управляющие конструкции должны быть на разных строчках, вставляемый/заменяемый текст должен быть между ними!

    Вставка (insert ?if)

    Примеры использования:


    html


    <!--insert
            <script type="text/javascript" src="vendors/release/dojo/dojo-mini.js" ></script>
            <script type="text/javascript" src="vendors/release/dijit/dijit-mini.js" ></script>
            <script type="text/javascript" src="vendors/release/dojox/dojox-mini.js" ></script>
    /insert-->
    
    


    js


    /*insert
            var mode = 'dev'
    /insert*/
    


    Замена (replace to ?pattern ?if)

    to — строка, на которую будет произведена замена (поддерживает плэйсхолдеры)
    pattern — шаблон для замены подстроки

    Примеры


    html


    <!--replace to=^<script type="text/javascript" src="vendors/release/dojox/dojox-mini.js" ></script>^-->
    <script type="text/javascript" src="vendors/release/dojox/dojox-mini.js" ></script>
    <!--/replace-->
    


    Заменит все, что находится между управляющими комментариями, на значение атрибута to.

    <!--replace to=^/release/^ pattern=^/dev/^-->
            <link rel="stylesheet" type="text/css" href="vendors/dev/dijit/themes/tundra/tundra.css">
            <link rel="stylesheet" type="text/css" href="vendors/dev/dojox/grid/resources/Grid.css">
            <link rel="stylesheet" type="text/css" href="vendors/dev/dojox/image/resources/Lightbox.css">
    <!--/replace-->
    


    Заменит все подстроки совпадающие с значением атрибута pattern на значение атрибута to в каждой строчке между комментариями.

    js


    window.appVersion = /*replace to=^${project.version}^*/0.6/*\replace*/;
    


    Заменит строку между управляющими комментариями на значение атрибута to.

    /*replace to=^dojo^ pattern=^dijit^*/
        dojo.require("dijit.layout.LayoutContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("dijit.form.TextBox");
    /*/replace*/
    


    Заменит все подстроки совпадающие с значением атрибута pattern на значение атрибута to в каждой строчке между комментариями.

    Импорт файлов (import file ?type ?if)

    file — путь к файлу, лучше всего писать абсолютный (поддерживает плэйсхолдеры)
    type — тип файла, от этого зависит дополнительная обработка файла (на данный момент поддерживается тип css, при этом содержимое файла упаковывается в одну строку и обрамляется тегом style

    Примеры

    html


    <!--import file=^path^ type=^css^-->
    


    js


    //import file=^path^ type=^css^
    


    Локальные переменные (define key=value|key)

    Инициализация локальной переменной (область ее видимости текущий файл). Если указан только ключ, то будет создана, пустая переменная.
    key — имя переменной
    value — значение

    Примеры

    html


    <!--define debug=true-->
    <!--define env=qa-->
    


    js


    //define debug=true
    //define env=qa
    


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

    Глобальные переменные


    Препроцессору можно указать файл, в котором находятся глобальные переменные, которые можно использовать в операциях.

    Пример указания файла с переменными с помощью maven (можно использовать аргументы командной строки)

    <project.confPath>${pom.basedir}/configuration/qa.json</project.confPath>
    


    Формат файла


    key0:value0
    key1:value1

    Использование плэйсхолдеров


    window.appVersion = /*replace to=^${version}^*/0.6/*/replace*/;

    Выражение ${version} будет заменено на значение соответствующей глобальной или локальной переменной переменной.

    Помимо этого есть поддержка операций над переменными, в данный момент реализована только одна — удаление кавычек с конца и начала значения переменной:
    ${rootPath:removeQuotes}

    Заключение


    Ну вот в принципе и все, если кому пригодится буду рад, за найденные баги и предложения буду признателен.

    GitHub


    Исходники и тестовые странички: github.com/iseeyou911/JSPP
    Файл конфигурации tests/qa.json. Чтобы сработал импорт в index.html нужно поправить
    в строчке
    <!--define path=../tests/-->

    абсолютный путь до этой папки.
    Поделиться публикацией
    Комментарии 2
      0
      Рассматривали в качестве варианта GPP? Если да, то чем не подошел?
        0
        Нет, не попался он мне.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое