Разработка внешнего интерфейса с помощью Gulp, Twig и SCSS - HTML-страницы

Как сделать автоматизировать HTML-страницы, созданные с помощью GulpJS. Набор инструментов Javascript для интерфейсной веб-разработки, который помогает вашему рабочему процессу разработки автоматизировать повторяющиеся задачи и потоковую передачу вашей системы сборки.

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

Итак, почему мы начали этот проект, используя twig или другую библиотеку шаблонов в качестве движка шаблонов?
Что ж, можете ли вы представить, когда ваш HTML-проект становится все больше и больше со множеством ресурсов, которые трудно поддерживать ? Ваш ответ - использование шаблонизатора. Это позволило вам разделить и включить части ваших HTML-тегов, чтобы их можно было включать в страницы, которые используются только для этих частей, вместо того, чтобы поддерживать и обновлять всю HTML-страницу одну за другой.

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

Начало работы
Откройте проект Gulp, мы должны продолжить с того места, на котором остановились, чтобы создать вещи, необходимые для создания проекта на основе HTML. Или, может быть, для напоминания просто введите в консоли:

$ npm install browser-sync gulp gulp-autoprefixer gulp-concat gulp-data gulp-plumber gulp-sass gulp-sourcemaps gulp-twig gulp-watch

Обновлен файл package.json:

{
  "name": "gulp-twig-scss",
  "version": "1.0.0",
  "description": "Frontend development using Gulp, Twig and SCSS",
  "main": "gulpfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/dyarfi/gulp-twig-scss"
  },
  "keywords": [
    "twig",
    "gulp",
    "HTML",
    "frontend",
    "SCSS"
  ],
  "author": "Defrian Yarfi",
  "license": "ISC",
  "homepage": "https://dyarfi.github.io",
  "dependencies": {
    "browser-sync": "^2.26.3",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-concat": "^2.6.1",
    "gulp-data": "^1.3.1",
    "gulp-plumber": "^1.2.0",
    "gulp-sass": "^4.0.2",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-twig": "^1.2.0",
    "gulp-watch": "^5.0.1"
  }
}

Обновлен файл gulpfile.js:

/*global require*/
"use strict";
var gulp = require('gulp'),
    path = require('path'),
    data = require('gulp-data'),
    twig = require('gulp-twig'), // Decided to use twig, because already familiar with it
    prefix = require('gulp-autoprefixer'),
    sass = require('gulp-sass'),    
    plumber = require('gulp-plumber'),
    concat = require('gulp-concat'),
    sourcemaps = require('gulp-sourcemaps'),
    browserSync = require('browser-sync'),
    fs = require('fs');
/*
 * Directories here
 */
var paths = {
  build: './build/',
  scss: './scss/',
  data: './client/data/',
  js: './client/js/'
};
/**
 * Compile .twig files and pass in data from json file
 * matching file name. index.twig - index.twig.json
 */
gulp.task('twig', function () {
 return gulp.src(['./client/templates/*.twig'])
  // Stay live and reload on error
  .pipe(plumber({
      handleError: function (err) {
         console.log(err);
         this.emit('end');
      }})
   )
   // Load template pages json data
   .pipe(data(function (file) {
     return JSON.parse(fs.readFileSync(paths.data + path.basename(file.path) + '.json'));  
 }))
   .pipe(
        twig().on('error', function (err) {
            process.stderr.write(err.message + '\n');
            this.emit('end');
        })
    )
   .pipe(gulp.dest(paths.build));
});
/**
 * Recompile .twig files and live reload the browser
 */
gulp.task('rebuild', ['twig'], function () {
  // BrowserSync Reload
  browserSync.reload();
});
/**
 * Wait for twig, js and sass tasks, then launch the browser-sync Server
 */
gulp.task('browser-sync', ['sass', 'twig', 'js'], function () {
  browserSync({
    server: {
      baseDir: paths.build
    },
    notify: false,
    browser:"google chrome"
  });
});
/**
 * Compile .scss files into build css directory With autoprefixer no
 * need for vendor prefixes then live reload the browser.
 */
gulp.task('sass', function () {
    return gulp.src(paths.scss + 'vendors/main.scss')
        .pipe(sourcemaps.init())
        // Stay live and reload on error
        .pipe(plumber({
            handleError: function (err) {
                console.log(err);
                this.emit('end');
            }
        }))
        .pipe(
            sass({
                includePaths: [paths.scss + 'vendors/'],
                outputStyle: 'compressed'
            }).on('error', function (err) {
                console.log(err.message);
                // sass.logError
                this.emit('end');
            })
        )
        .pipe(prefix(['last 15 versions','> 1%','ie 8','ie 7','iOS >= 9','Safari >= 9','Android >= 4.4','Opera >= 30'], {
            cascade: true
        })) 
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(paths.build + '/assets/css/'));
  });
/**
 * Compile script.js files into build assets js directory concat to script.min.js
*/
gulp.task('js', function(){
    return gulp.src(paths.js + 'script.js')
        .pipe(sourcemaps.init())
        .pipe(concat('script.min.js'))
        .on('error', function (err) {
            console.log(err.toString());
            this.emit('end');
        })
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(paths.build +'assets/js'));
});
/**
 * Watch scss files for changes & recompile
 * Watch .twig files run twig-rebuild then reload BrowserSync
 */
gulp.task('watch', function () {
    // Script JS
    gulp.watch(paths.js + 'script.js', ['js', browserSync.reload]);
    // SCSS files or main.scss
    gulp.watch(paths.scss + '**/*.scss', ['sass', browserSync.reload]);
    // Assets Watch and copy to build in some file changes
    gulp.watch(['client/templates/**/*.twig','client/data/*.twig.json'], {cwd:'./'}, ['rebuild']);
});
// Build task compile sass and twig.
gulp.task('build', ['sass', 'twig']);
/**
 * Default task, running just `gulp` will compile the sass,
 * compile the project site, launch BrowserSync then watch
 * files for changes
 */
gulp.task('default', ['browser-sync', 'watch']);

После этого мы можем запустить $ gulp в терминале и дождаться, пока браузер загрузит наш проект. Я включаю в этот проект некоторые внешние ресурсы, такие как jQuery, Bootstrap JS и зависимости, шрифты и изображения. Вы можете скачать v4.1.2 или последнюю Bootstrap SCSS в их репозитории для использования в этом проекте.

1. Заголовок
Я собираюсь обновить свой ./client/template/includes/header.twig файл, чтобы добавить навигацию к страницам, которые мы создадим.

<header>
      <!-- /.navbar -->
      <nav class="navbar navbar-expand-md navbar-light bg-light shadow-sm">
         <div class="container-fluid font-weight-bold">
             <a class="navbar-brand ml-3" href="#"><i class="text-warning ">//</i> <span class="text-success">IOTA Connect</span></a>
             <button class="navbar-toggler text-white" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                 <span class="navbar-toggler-icon"></span>
             </button>      
             <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav ml-auto text-right">
                     <li class="nav-item active">
                        <a class="nav-link" href="index.html">Home<span class="sr-only">(current)</span></a>
                     </li>
                     <li class="nav-item">
                        <a class="nav-link" href="about.html">About</a>
                     </li>
                     <li class="nav-item">
                        <a class="nav-link" href="service.html">Service</a>
                     </li>
                     <li class="nav-item">
                        <a class="nav-link" href="contact.html">Contact</a>
                     </li>
                </ul>
             </div>
         </div>
     </nav>
</header>

2. Скрипты
В заголовок мы уже включили панель навигации BS 4 по умолчанию для нашей навигации. Добавление других JS-библиотек для обновлений наших HTML-страниц. Измените и добавьте JS начальной загрузки и другие зависимости в теги скриптов ./client/templates/includes/scripts.twig:

    <!-- jquery.slim.min.js -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <!-- popper.min.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <!-- bootstrap.min.js -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
    <!-- script.min.js -->
    <script src="./assets/js/script.min.js"></script>

3. Создание данных JSON для страниц шаблона HTML
В каталоге client / data / мы создаем новый файл с именем about.twig.json или смотрим например, этот client / data / about.twig.json, и браузер перезагрузится.

{   
   "title" : "About page title",
   "description" : "About description content page"
}

4. Создание страниц HTML-шаблонов
В каталоге client / templates / создайте новый файл с именем about.twig или посмотрите следующий код на client / templates / about.twig

{% extends "layouts/default.twig" %}
{% block content %}
   <!-- ================== Block Main Top ================== -->
   {% include 'blocks/block-main-top.twig' %}
   <div class="container">
      <div class="col-lg-7 text-center mx-auto border border-warning py-4 px-5 my-5">
      <h1 class="display-1 text-warning">{{title}}</h1>
      <span class="text-secondary">{{description}}</span>
      </div>
   </div>
   <!-- ================== Block Main Bottom ================== -->
   {% include 'blocks/block-main-bottom.twig' %}
{% endblock %}

Gulp gulp-data с gulp-twig автоматизирует сборку файла HTML после того, как мы создадим about.twig, и вставит данные в файл HTML из ранее созданного about.twig.json.

Папка сборки будет папкой конечных результатов из автоматически сгенерированных страниц HTML-шаблонов из этого проекта gulp:

$ tree build
build
├── about.html
├── assets
│   ├── css
│   │   ├── main.css
│   │   └── main.css.map
│   └── js
│       ├── script.min.js
│       └── script.min.js.map
├── contact.html
├── index.html
└── service.html

Полный и окончательный проект исходного кода в этом сообщении: https://github.com/dyarfi/gulp-twig-scss/tree/development/

Предварительный просмотр на HTML-страницах автоматизированной сборки:
https://dyarfi.github.io/gulp-twig-scss/development/

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

Спасибо, что заглянули, и удачного кодирования!

Ссылки:
https://sass-lang.com/
https://gulpjs.com/