TARS, do the level of frontend routine 0%


    Frontend is getting harder every day. Tasks are more voluminous, the user interface is richer, HTML, CSS and Javascript are huge, and the front-end sleep is shorter and more restless. It is necessary to correctly structure the code, perform many routine tasks (compiling css and js preprocessors, assembling sprites, preparing and optimizing images, minifying files, etc.). If you work in a team, this automatically increases the complexity of development. To solve these problems, I created TARS, a gulpjs -based html layout compiler .

    We in 2GIS know firsthand about the frontend routine. The company creates many web projects of varying complexity: from portals and online maps, to various landing pages and promotional sites. We are tired of boring copy-paste when working with html, preparing graphics for displays with a high pixel density, minifying everything that can be minimized, etc. It seemed that the machine could safely do all these things for us. So I decided to develop a tool to automate the lion's share of the frontend routine.

    UPD: we released many new products in TARS and even wrote an article about it !

    What I wanted to get from this tool:
    • Automate everything you can;
    • use existing practices, which means using the familiar programming language - JavaScript, the familiar ecosystem - Node.js and npm;
    • basic set of functions in one tool;
    • convenient API;
    • cross-platform.

    Before writing our own, first, my colleagues and I looked for ready-made solutions. There were a lot of them. Here is a squeeze, it seems to me, of the most interesting projects:

    Each of these tools is good in its own way: somewhere there is excellent documentation, somewhere there is a well-implemented task storage system. But all these solutions are either too complicated to modify, or too simple, which is easier to write your own than to modify the existing one. At the same time, it would be necessary to expand the functionality for sure. For example, none of the solutions provided workflow for preparing graphics for screens with a high pixel density.

    Then TARS was born, which absorbed all the best from ready-made projects.

    TARS is a set of gulp tasks for automating most frontend tasks + the ability to easily add new ones if there is something missing. TARS can be called a gulp framework. Suitable for both individual developers and large teams. With TARS, it is easy to develop projects of any complexity: from landing to a huge portal. You don’t even need to know how gulp works, since everything that was possible was made in options, all the code and use cases are documented.

    Key features of TARS.
    1. Jade or Handlebars as an html template engine or regular html (when choosing Handlebars).
    2. SCSS, Less, Stylus as a css preprocessor or tube CSS (syntax supported by any of the preprocessors). The fmp project has recently appeared , in which it is also available.
    3. The ability to separate data from presentation by passing data in the form of a js-object into templates. So we use the same template many times, but with different data, without copy paste, libraries and frameworks. More on this will be described below.
    4. Watcher chokidar .
    5. Truly smart image manipulation. The development for screens with a high pixel density is greatly simplified. This will be described below.
    6. Easy to expand with your tacks. Modular structure.
    7. Great documentation.
    8. Creating an archive of the finished assembly. A trifle, but nice.

    And, of course, the concatenation, minification and optimization of everything that is possible, several assembly modes, etc.

    TARS has an impressive set of options, each of which is described in detail in the documentation.

    We have already used TARS in the development of a site about
    2GIS technologies, products and design , various landing pages ( Promotional applications of 2GIS for Windows Phone , 2GIS franchise for Kazakhstan , website of an internal conference of 2GIS developers ), 5pm website , etc.

    How does it work

    You will need:
    • Node.js (perhaps soon on IO.js, we are working on it);
    • Gulp installed globally;
    • Archive from TARS .

    After we downloaded the archive, we execute the gulp init command. It will connect the selected html-template engine and css-preprocessor (indicated in the config), create the basic file structure. Everything, you can sausage. TARS works on all desktop platforms.

    In the near future I will make a yeoman generator.

    Before you start working with the collector, I recommend that you familiarize yourself with the documentation .

    Basic build commands

    There are two main commands in total:
    • gulp build (or just gulp);
    • gulp dev.

    The first team builds the project, and the second launches TARS in development mode. In dev-mode, the project is built without minifications and with watch watchers running for files.

    Teams diluted with a small number of flags:
    • gulp build (or just gulp) (--min, --release, --ie8);
    • gulp dev (--lr, --tunnel, --ie8).

    With gulp build, you can use the --min switch, and then minified js and css files will be connected in html. When using the --release key in html, all the same minified files will be connected, in the name of which there is a random hash.

    With gulp dev, the --lr keys are used to launch livereload in a browser that opens automatically (you can select a browser in the config). The --tunnel key will share the layout from your local computer to an external web. You will receive a link in the console where the layout will be available on the web.

    Also, with any command, you can use the --ie8 switch, which will launch additional assembly tasks with support for Internet Explorer 8. The browser is special, so the workflow is special for it.

    All installation instructions are in the documentation.

    Project structure

    In the “tars” folder are all the files of the collector (built-in and user tasks with watch, various helpers) and the folder with the project sources (markup). At the root lies the collector config, dependency lists for the project, the config for checking js code style and the main gulpfile.js.

    ├── gulpfile.js                 # gulpfile сборщика
    ├── tars-config.js              # Конфигурационный файл
    ├── package.json                # Зависимости TARS
    ├── user-package.json           # Пользовательские пакеты
    └── tars/                       # Таски и хелперы для gulp
        └── helpers/                # Хелперы
        └── tasks/                  # Основные таски
        └── user-tasks/             # Пользовательские таски
        └── watchers/               # Основные вотчеры
        └── user-watchers/          # Пользовательские вотчеры
    └── markup/                     # Основная папка с проектом
        └── modules/                # Модули
        └── pages/                  # Шаблоны страниц
        └── static/                 # Различная статика (css, js и т.п.)
    └── docs/                       # Документация

    A project is a set of pages (the pages folder), a set of modules (the modules folder) and a folder with different statics (static, by default. The name can be changed in the config).

    Pages are the simplest templates into which modules are connected. The simplest example of a module is menu or footer. To make it clearer, in terms of BEM, a module is a block. And if without BEM, then the module is any independent entity on the page.

    exampleModule/                              # Пример модуля
        └── assets/                             # Различная статика для текущего модуля
        └── ie/                                 # Стили для ie8 и ie9 (ie9/ie8.scss|less|styl)
        └── data/                               # Папка для хранения данных для модуля
            ├── data.js                         # Данные для модуля в виде js-объекта
       ├── exampleModule.html                   # Html|Jade-представления модуля 
       ├── exampleModule.scss|less|styl         # Scss|Less|Stylus-представление модуля
       ├── exampleModule.js                     # Js-представление модуля

    Each module has its own html-, css- and js-presentation, a folder for various files for the module (pictures, video files, etc.), a folder for IE8 and IE9 browser styles, a folder with a data file for the modules. All listed files and folders are optional for the module. Any module may include other modules.

    It is not necessary that the module is a separate entity. You can use the modules as you like.

    A folder with statics may contain subdirectories for storing images, js-files of libraries and plug-ins, files of the selected css preprocessor + various files that should eventually be at the root of the project, for example, favicon or robots.txt

    Be sure to read how they are glued together JavaScript and CSS - this determines how you use the collector files.

    The file structure is created automatically when the project is initialized. It is generally immutable, but there are a number of optional directories, plus a number of options for changing the name of existing collector folders. The file structure is described in detail in the documentation.

    For JavaScript, separate options have been created in which you can specify where else you need to take js for gluing. Thus, you do not need to go into the files of the collector if you want to use some kind of framework in which there is not only such an entity as a module (or a view, or a directive, or something else).

    Work with templates

    Suppose we have a page that has a top, side, and bottom menu. Something like this:

    Menus are very similar to each other, but have different links, small differences in styles. Further we will speak in terms of BEM. Each menu is a block. Let's sketch a little html for implementing the menu, which we will put in the modules folder (modules / menu / menu.html):

    I will not give all the code, but it is obvious that the footcloth is quite solid. Now we will transfer all the data for this menu (links and names of menu items) to a separate file (data / data.js in the module folder):

    menu: {
        header: {
            mod: ‘header’,
            list: [
                    url: firstLinkUrl,
                    title: firstLinkTitle
        side: {
            mod: side,
            list: [
                    url: firstLinkUrl,
                    title: firstLinkTitle
        footer: {
            mod: footer,
            list: [
                    url: firstLinkUrl,
                    title: firstLinkTitle

    Now we’ll improve our menu template a bit (use handlebars):

    In this case, a certain mod was added, with the help of which we can customize the CSS for the menu depending on its position.
    It remains only to connect these menus on the page:

    {{> menu/menu menu.header}}
    {{> menu/menu menu.footer}}

    Using the ">" handlebars helper, we connect the menu module with the menu view (each module can have several views) to the page and pass certain data to it.

    In total, we have 1 template + 1 data file for the menu, which is used in two different places. Thus, it is possible to implement a module that is very convenient to reuse. It remains only to add that the same functionality is implemented for jade.

    Preparation and storage of graphics

    Today, there are many high pixel density screens. Let’s figure out what this means.

    As an example, consider the smartphones IPhone 3GS and IPhone 4. 3GS has a screen resolution of 320x480, and 4-ki has 640x960. As we can see, the resolution doubled exactly with the same diagonal, which means the pixel has become smaller. To neutralize this difference between pixel sizes (namely, we control pixels in CSS), the device-pixel-ratio (or dppx) parameter appeared, which shows how many real screen pixels are contained in a certain logical pixel, which we operate in css. For example, for an IPhone 4 display, this parameter is 2. More details can be found on the W3C website .

    Suppose we have a sprite PNG image. Such pictures have fixed sizes. If we place such a sprite on the iPhone 4 screen, then each pixel of the sprite will be blurred into two screen ones, and if you smear such a picture by the number of pixels 2 times larger than the size of the picture, the image will look terrible.

    To get rid of this problem, you can use an image 2 times larger in size, and set the size of the image in CSS based on the size of the original image (background-size property).

    At the moment, there are screens with dppx from 1 to 4 (will soon be higher). Preparing sprites for four screen sizes is a lot of work.

    Helps SVG. Vector, does not depend on dppx-screen, perfectly rendered in modern (and not only) browsers. Only one size can be made, and this image will look the same on all screens.

    Unfortunately, SVG has several disadvantages:
    • SVG poorly displays radial and other complex gradients (linear ones are displayed perfectly);
    • complex shadows are poorly displayed;
    • not displayed in IE8.

    In total, we have two approaches: SVG for everything we can. For the rest, we are preparing PNG images. For IE8, we will just rasterize the SVG images and prepare a sprite from them.

    To easily manage these approaches, two great mixins (SCSS syntax) were written:

        @include bg-svg($svg-image-name);  для SVG изображений;
        @include bg($png-image-name);  для PNG изображений.

    At the same time, everything will be generated and connected automatically for IE8, media requests will be generated for png images that connect certain png images depending on the type of screen. In general, separate css files are generated for IE8 and IE9. Files for IE8 are only created if we started the assembly with the --ie8 switch.
    An example of using mixins:

    You can imagine how much work was done automatically by the amount of generated code.

    You can read more about the assembly of graphics in the documentation, and the approach itself is perfectly described in the presentation of web developer Timofei Chaptykov.

    Custom task

    TARS already has everything you need to develop projects of any complexity, but you will not please everyone. Each may have some specificity, some additional tasks. To solve this problem, a custom task template was created (tars / user-tasks / example-task.js). On its basis, you can make your own task, which is easily integrated into the existing infrastructure of the collector.

    Each task by default can give a notification about an error or successful execution, start page reload in the browser and connect other tasks if it is necessary to make dependencies between them.

    Since the main package.json (the file where the dependencies of the collector are located) can be changed by the collector itself (for example, when executing the gulp update-deps command), user dependencies must be stored in a separate place. There is user-package.json for this. The syntax for declaring dependencies is the same as basically package.json.

    There is also an example of a user watch in the tars / user-watchers directory.

    Future plans

    There are plans to add new features:
    • move to Gulp 4 versions;
    • add template engines;
    • add pre- and post-processors for CSS;
    • add support for ES6;
    • Use Browserify or webpack.

    In the near future we will release version 1.3.0 and translate the documentation into English (it will be ready just next week). Plans to release new versions can be found on GitHub .

    I forgot to mention that this is open source, so I'm waiting for your pull requests, questions on expanding the functionality of the collector in issue . I’ll duplicate a direct link to the project repository .

    PS: March 28–29, Novosibirsk will host the largest IT conference in the Urals - CodeFest . TARS will have a separate stand at this conference. If you come to CodeFest - come and ask questions.

    Also popular now: