856 lines
24 KiB
JavaScript
856 lines
24 KiB
JavaScript
import autoprefixer from 'autoprefixer'
|
||
import concat from 'gulp-concat'
|
||
import csso from 'gulp-csso'
|
||
import { deleteAsync } from 'del'
|
||
import gulp from 'gulp'
|
||
import gulpWebp from 'gulp-webp'
|
||
import imagemin, { mozjpeg, optipng, svgo } from 'gulp-imagemin'
|
||
import imageminAvif from 'imagemin-avif'
|
||
import order from 'gulp-order'
|
||
import plumber from 'gulp-plumber'
|
||
import postcss from 'gulp-postcss'
|
||
import pug from 'gulp-pug'
|
||
import rename from 'gulp-rename'
|
||
import uglify from 'gulp-uglify-es'
|
||
import * as dartSass from 'sass'
|
||
import gulpSass from 'gulp-sass'
|
||
import sourcemap from 'gulp-sourcemaps'
|
||
import svgstore from 'gulp-svgstore'
|
||
import sync from 'browser-sync'
|
||
import { nanoid } from 'nanoid'
|
||
import postcssUrl from 'postcss-url'
|
||
import inject from 'gulp-inject'
|
||
import newer from 'gulp-newer'
|
||
import twig from 'gulp-twig'
|
||
import fs from 'fs'
|
||
import path from 'path'
|
||
import { fileURLToPath } from 'url'
|
||
import { execSync } from 'child_process'
|
||
import dotenv from 'dotenv'
|
||
|
||
const __filename = fileURLToPath(import.meta.url)
|
||
const __dirname = path.dirname(__filename)
|
||
|
||
// Загружаем переменные окружения из .env.local
|
||
const envPath = path.join(__dirname, '.env.local')
|
||
if (fs.existsSync(envPath)) {
|
||
dotenv.config({ path: envPath })
|
||
console.log('📝 Загружены настройки из .env.local')
|
||
} else {
|
||
console.log('⚠️ Файл .env.local не найден. Запустите: gulp configInit')
|
||
}
|
||
|
||
const baseUrl = '.'
|
||
const pathCss = '..'
|
||
const searchId = Date.now()
|
||
|
||
// Конфигурация для разных шаблонизаторов
|
||
const settings = {
|
||
templateEngine: process.env.TEMPLATE_ENGINE || 'pug', // 'pug' или 'twig'
|
||
dataPath: 'src/data', // путь к JSON файлам с данными
|
||
https: {
|
||
enabled: process.env.HTTPS === 'true',
|
||
keyPath: 'ssl/server.key',
|
||
certPath: 'ssl/server.crt'
|
||
},
|
||
server: {
|
||
port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3000,
|
||
host: process.env.HOST || 'localhost',
|
||
open: process.env.OPEN_BROWSER === 'true',
|
||
notify: process.env.BROWSER_SYNC_NOTIFY === 'true'
|
||
}
|
||
}
|
||
|
||
// Выводим текущие настройки при запуске
|
||
console.log('⚙️ Текущие настройки:')
|
||
console.log(` Шаблонизатор: ${settings.templateEngine}`)
|
||
console.log(` HTTPS: ${settings.https.enabled ? 'включен' : 'выключен'}`)
|
||
console.log(` Порт: ${settings.server.port}`)
|
||
console.log(` Хост: ${settings.server.host}`)
|
||
console.log(` Автооткрытие браузера: ${settings.server.open ? 'да' : 'нет'}`)
|
||
console.log(` Уведомления: ${settings.server.notify ? 'да' : 'нет'}`)
|
||
|
||
// Функция для загрузки данных из JSON файлов
|
||
const loadData = () => {
|
||
const dataPath = path.join(__dirname, settings.dataPath)
|
||
let data = {}
|
||
|
||
if (fs.existsSync(dataPath)) {
|
||
const files = fs.readdirSync(dataPath).filter(file => file.endsWith('.json'))
|
||
|
||
files.forEach(file => {
|
||
const fileName = path.basename(file, '.json')
|
||
const filePath = path.join(dataPath, file)
|
||
|
||
try {
|
||
const fileContent = fs.readFileSync(filePath, 'utf8')
|
||
data[fileName] = JSON.parse(fileContent)
|
||
} catch (error) {
|
||
console.error(`Ошибка загрузки данных из ${file}:`, error.message)
|
||
}
|
||
})
|
||
} else {
|
||
console.log(`📁 Папка с данными не найдена: ${dataPath}`)
|
||
console.log('💡 Запустите: gulp data для создания примера данных')
|
||
}
|
||
|
||
return data
|
||
}
|
||
|
||
const getImageSrcset = (path, format, params = '') => {
|
||
return [1, 2]
|
||
.map((dpr) => `${baseUrl}${path}@${dpr}x.${format}${params} ${dpr}x`)
|
||
.join(', ')
|
||
}
|
||
|
||
const getImageMime = (format) => {
|
||
switch (format) {
|
||
case 'avif':
|
||
return 'image/avif'
|
||
case 'webp':
|
||
return 'image/webp'
|
||
case 'jpeg':
|
||
case 'jpg':
|
||
return 'image/jpeg'
|
||
case 'png':
|
||
return 'image/png'
|
||
default:
|
||
return null
|
||
}
|
||
}
|
||
|
||
const sass = gulpSass(dartSass)
|
||
|
||
const clean = async () => {
|
||
return await deleteAsync(['dist'])
|
||
}
|
||
|
||
const copy = () => {
|
||
return gulp
|
||
.src(
|
||
[
|
||
'src/fonts/**/*.{woff,woff2}',
|
||
'src/img/**/*.{webm,webp,avif,jpg,jpeg,png,svg}',
|
||
'src/favicon/**/*',
|
||
'src/favicon.ico',
|
||
'src/settings.js',
|
||
'src/urls.json',
|
||
'src/robots.txt'
|
||
],
|
||
{ base: 'src', encoding: false }
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
const css = () => {
|
||
return gulp
|
||
.src('src/scss/index.scss')
|
||
.pipe(plumber())
|
||
.pipe(sourcemap.init())
|
||
.pipe(sass.sync().on('error', sass.logError))
|
||
.pipe(
|
||
postcss([
|
||
postcssUrl({
|
||
url: (asset) => {
|
||
if (asset.url.startsWith('/')) {
|
||
return `${pathCss}${asset.url}?v=${searchId}`
|
||
}
|
||
return asset.url
|
||
}
|
||
}),
|
||
autoprefixer({ remove: false })
|
||
])
|
||
)
|
||
.pipe(rename('style.css'))
|
||
.pipe(sourcemap.write('.'))
|
||
.pipe(gulp.dest('dist/css'))
|
||
.pipe(sync.stream())
|
||
.pipe(csso())
|
||
.pipe(rename('style.min.css'))
|
||
.pipe(gulp.dest('dist/css'))
|
||
}
|
||
|
||
const images = () => {
|
||
return gulp
|
||
.src('src/img/**/*.{png,jpg,jpeg,svg}', { base: 'src', encoding: false })
|
||
.pipe(newer('dist'))
|
||
.pipe(
|
||
imagemin(
|
||
[
|
||
optipng({ optimizationLevel: 5 }),
|
||
mozjpeg({ quality: 85, progressive: true }),
|
||
svgo({
|
||
plugins: [
|
||
{ name: 'removeViewBox', active: false },
|
||
{ name: 'removeXMLNS', active: false },
|
||
{ name: 'removeUnknownsAndDefaults', active: false }
|
||
]
|
||
})
|
||
],
|
||
{ silent: true }
|
||
)
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
const webp = () => {
|
||
return gulp
|
||
.src('src/img/**/*.{png,jpg,jpeg}', { base: 'src', encoding: false })
|
||
.pipe(newer({ dest: 'dist', ext: '.webp' }))
|
||
.pipe(gulpWebp({ quality: 85 }))
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
const avif = () => {
|
||
return gulp
|
||
.src('src/img/**/*.{png,jpg,jpeg}', { base: 'src', encoding: false })
|
||
.pipe(newer({ dest: 'dist', ext: '.avif' }))
|
||
.pipe(imagemin([imageminAvif({ quality: 60 })], { silent: true }))
|
||
.pipe(rename((path) => (path.extname = '.avif')))
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
const processImages = gulp.parallel(images, webp, avif)
|
||
|
||
const sprite = () => {
|
||
return gulp
|
||
.src('src/icons/**/*.svg')
|
||
.pipe(svgstore({ inlineSvg: true }))
|
||
.pipe(rename('sprite.svg'))
|
||
.pipe(gulp.dest('dist/img'))
|
||
}
|
||
|
||
const injectSprite = () => {
|
||
const spritePath = 'dist/img/sprite.svg'
|
||
|
||
// Проверяем, существует ли файл спрайта
|
||
if (!fs.existsSync(spritePath)) {
|
||
console.log('⚠️ Спрайт не найден, пропускаем инъекцию')
|
||
return Promise.resolve()
|
||
}
|
||
|
||
return gulp
|
||
.src('dist/*.html')
|
||
.pipe(
|
||
inject(gulp.src(spritePath), {
|
||
transform: (_, file) => {
|
||
return file.contents.toString()
|
||
}
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
// Инъекция спрайта только в конкретный файл
|
||
const injectSpriteToFile = (htmlFile) => {
|
||
const spritePath = 'dist/img/sprite.svg'
|
||
|
||
if (!fs.existsSync(spritePath) || !fs.existsSync(htmlFile)) {
|
||
return Promise.resolve()
|
||
}
|
||
|
||
return gulp
|
||
.src(htmlFile)
|
||
.pipe(
|
||
inject(gulp.src(spritePath), {
|
||
transform: (_, file) => {
|
||
return file.contents.toString()
|
||
}
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
const jsCommon = () => {
|
||
return gulp
|
||
.src('src/js/common/*.js')
|
||
.pipe(
|
||
plumber({
|
||
errorHandler(err) {
|
||
console.error('JS Common Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
})
|
||
)
|
||
.pipe(order(['_utils.js', '*.js']))
|
||
.pipe(sourcemap.init())
|
||
.pipe(concat('script.js'))
|
||
.pipe(sourcemap.write('.'))
|
||
.pipe(gulp.dest('dist/js'))
|
||
}
|
||
|
||
const jsCommonMin = () => {
|
||
return gulp
|
||
.src('src/js/common/*.js')
|
||
.pipe(
|
||
plumber({
|
||
errorHandler(err) {
|
||
console.error('JS Common Min Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
})
|
||
)
|
||
.pipe(order(['_utils.js', '*.js']))
|
||
.pipe(concat('script.min.js'))
|
||
.pipe(uglify.default())
|
||
.pipe(gulp.dest('dist/js'))
|
||
}
|
||
|
||
const jsVendor = () => {
|
||
return gulp
|
||
.src('src/js/vendor/*.js')
|
||
.pipe(
|
||
plumber({
|
||
errorHandler(err) {
|
||
console.error('JS Vendor Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
})
|
||
)
|
||
.pipe(concat('vendor.js'))
|
||
.pipe(gulp.dest('dist/js'))
|
||
}
|
||
|
||
const jsVendorMin = () => {
|
||
return gulp
|
||
.src('src/js/vendor/*.js')
|
||
.pipe(
|
||
plumber({
|
||
errorHandler(err) {
|
||
console.error('JS Vendor Min Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
})
|
||
)
|
||
.pipe(concat('vendor.min.js'))
|
||
.pipe(uglify.default())
|
||
.pipe(gulp.dest('dist/js'))
|
||
}
|
||
|
||
const js = gulp.parallel(jsCommon, jsCommonMin, jsVendor, jsVendorMin)
|
||
|
||
// Простая обработка Pug шаблонов
|
||
const htmlPug = () => {
|
||
const data = loadData()
|
||
|
||
return gulp
|
||
.src('src/pug/pages/**/*.pug')
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Pug Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(
|
||
pug({
|
||
pretty: true,
|
||
basedir: 'src/pug',
|
||
locals: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
}
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
// Простая обработка Twig шаблонов
|
||
const htmlTwig = () => {
|
||
const data = loadData()
|
||
|
||
return gulp
|
||
.src('src/twig/pages/**/*.twig')
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Twig Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(
|
||
twig({
|
||
base: 'src/twig',
|
||
data: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
},
|
||
functions: [
|
||
{
|
||
name: 'getSrcset',
|
||
func: getImageSrcset
|
||
},
|
||
{
|
||
name: 'getMime',
|
||
func: getImageMime
|
||
}
|
||
]
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
}
|
||
|
||
// Pug с инкрементальной сборкой
|
||
const htmlPugIncremental = () => {
|
||
const data = loadData()
|
||
|
||
return gulp
|
||
.src('src/pug/pages/**/*.pug')
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Pug Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(newer({
|
||
dest: 'dist',
|
||
ext: '.html'
|
||
}))
|
||
.pipe(
|
||
pug({
|
||
pretty: true,
|
||
basedir: 'src/pug',
|
||
locals: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
}
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
.on('end', () => {
|
||
console.log('📄 Обработаны только измененные Pug файлы')
|
||
})
|
||
}
|
||
|
||
// Twig с инкрементальной сборкой
|
||
const htmlTwigIncremental = () => {
|
||
const data = loadData()
|
||
|
||
return gulp
|
||
.src('src/twig/pages/**/*.twig')
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Twig Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(newer({
|
||
dest: 'dist',
|
||
ext: '.html'
|
||
}))
|
||
.pipe(
|
||
twig({
|
||
base: 'src/twig',
|
||
data: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
},
|
||
functions: [
|
||
{
|
||
name: 'getSrcset',
|
||
func: getImageSrcset
|
||
},
|
||
{
|
||
name: 'getMime',
|
||
func: getImageMime
|
||
}
|
||
]
|
||
})
|
||
)
|
||
.pipe(gulp.dest('dist'))
|
||
.on('end', () => {
|
||
console.log('📄 Обработаны только измененные Twig файлы')
|
||
})
|
||
}
|
||
|
||
// Универсальная функция для обработки HTML
|
||
const html = (incremental = false) => {
|
||
if (settings.templateEngine === 'twig') {
|
||
return incremental ? htmlTwigIncremental() : htmlTwig()
|
||
} else {
|
||
return incremental ? htmlPugIncremental() : htmlPug()
|
||
}
|
||
}
|
||
|
||
// Создание SSL сертификатов для разработки
|
||
const createSSLCerts = (done) => {
|
||
const sslDir = path.join(__dirname, 'ssl')
|
||
const keyPath = path.join(sslDir, 'server.key')
|
||
const certPath = path.join(sslDir, 'server.crt')
|
||
|
||
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
||
console.log('✅ SSL сертификаты уже существуют')
|
||
done()
|
||
return
|
||
}
|
||
|
||
if (!fs.existsSync(sslDir)) {
|
||
fs.mkdirSync(sslDir, { recursive: true })
|
||
}
|
||
|
||
try {
|
||
console.log('🔐 Создание SSL сертификатов для разработки...')
|
||
|
||
execSync(`openssl genrsa -out ${keyPath} 2048`, { stdio: 'pipe' })
|
||
|
||
const certCommand = `openssl req -new -x509 -key ${keyPath} -out ${certPath} -days 365 -subj "/C=RU/ST=Local/L=Local/O=Development/OU=Dev/CN=localhost"`
|
||
execSync(certCommand, { stdio: 'pipe' })
|
||
|
||
console.log('✅ SSL сертификаты успешно созданы')
|
||
console.log('⚠️ Это сертификаты только для разработки!')
|
||
|
||
} catch (error) {
|
||
console.error('❌ Ошибка создания SSL сертификатов:')
|
||
console.error('Убедитесь что OpenSSL установлен в системе')
|
||
}
|
||
|
||
done()
|
||
}
|
||
|
||
// Создание конфигурационного файла
|
||
const createHTTPSConfig = (done) => {
|
||
const configPath = path.join(__dirname, '.env.local')
|
||
|
||
if (!fs.existsSync(configPath)) {
|
||
const envContent = `# Конфигурация для разработки
|
||
# Этот файл автоматически загружается при запуске gulp
|
||
|
||
# ===== ОСНОВНЫЕ НАСТРОЙКИ =====
|
||
|
||
# Включить HTTPS (true/false)
|
||
# После изменения нужно перезапустить gulp
|
||
HTTPS=false
|
||
|
||
# Шаблонизатор (pug/twig)
|
||
# После изменения нужно перезапустить gulp
|
||
TEMPLATE_ENGINE=pug
|
||
|
||
# ===== НАСТРОЙКИ СЕРВЕРА =====
|
||
|
||
# Порт для разработки
|
||
PORT=3000
|
||
|
||
# Хост для разработки (localhost, 127.0.0.1, 0.0.0.0 для доступа извне)
|
||
HOST=localhost
|
||
|
||
# Автоматически открывать браузер при запуске (true/false)
|
||
OPEN_BROWSER=false
|
||
|
||
# Показывать уведомления BrowserSync (true/false)
|
||
BROWSER_SYNC_NOTIFY=false
|
||
`
|
||
|
||
fs.writeFileSync(configPath, envContent)
|
||
console.log('✅ Создан файл конфигурации: .env.local')
|
||
console.log('📝 Теперь вы можете настроить параметры в .env.local')
|
||
} else {
|
||
console.log('ℹ️ Файл .env.local уже существует')
|
||
}
|
||
|
||
done()
|
||
}
|
||
|
||
// Функция для перезагрузки конфигурации
|
||
const reloadConfig = (done) => {
|
||
const envPath = path.join(__dirname, '.env.local')
|
||
if (fs.existsSync(envPath)) {
|
||
// Очищаем старые значения
|
||
delete process.env.TEMPLATE_ENGINE
|
||
delete process.env.HTTPS
|
||
delete process.env.PORT
|
||
delete process.env.HOST
|
||
delete process.env.OPEN_BROWSER
|
||
delete process.env.BROWSER_SYNC_NOTIFY
|
||
|
||
// Загружаем новые
|
||
dotenv.config({ path: envPath, override: true })
|
||
|
||
// Обновляем настройки
|
||
settings.templateEngine = process.env.TEMPLATE_ENGINE || 'pug'
|
||
settings.https.enabled = process.env.HTTPS === 'true'
|
||
settings.server.port = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000
|
||
settings.server.host = process.env.HOST || 'localhost'
|
||
settings.server.open = process.env.OPEN_BROWSER === 'true'
|
||
settings.server.notify = process.env.BROWSER_SYNC_NOTIFY === 'true'
|
||
|
||
console.log('🔄 Конфигурация перезагружена!')
|
||
console.log('⚙️ Новые настройки:')
|
||
console.log(` Шаблонизатор: ${settings.templateEngine}`)
|
||
console.log(` HTTPS: ${settings.https.enabled ? 'включен' : 'выключен'}`)
|
||
console.log(` Порт: ${settings.server.port}`)
|
||
console.log(` Хост: ${settings.server.host}`)
|
||
console.log('⚠️ Для применения HTTPS и смены шаблонизатора нужен перезапуск!')
|
||
} else {
|
||
console.log('❌ Файл .env.local не найден')
|
||
}
|
||
done()
|
||
}
|
||
|
||
// Задача для создания примера структуры данных
|
||
const createDataExample = (done) => {
|
||
const dataDir = path.join(__dirname, 'src/data')
|
||
|
||
if (!fs.existsSync(dataDir)) {
|
||
fs.mkdirSync(dataDir, { recursive: true })
|
||
}
|
||
|
||
const exampleData = {
|
||
site: {
|
||
title: 'Мой сайт',
|
||
description: 'Описание сайта',
|
||
author: 'Автор'
|
||
},
|
||
navigation: [
|
||
{ title: 'Главная', url: '/' },
|
||
{ title: 'О нас', url: '/about' },
|
||
{ title: 'Контакты', url: '/contacts' }
|
||
]
|
||
}
|
||
|
||
fs.writeFileSync(
|
||
path.join(dataDir, 'global.json'),
|
||
JSON.stringify(exampleData, null, 2)
|
||
)
|
||
|
||
console.log('✅ Создан пример файла данных: src/data/global.json')
|
||
done()
|
||
}
|
||
|
||
const refresh = (done) => {
|
||
sync.reload()
|
||
done()
|
||
}
|
||
|
||
// Обработка конкретного Pug файла
|
||
const processSinglePugFile = (filePath) => {
|
||
const data = loadData()
|
||
const relativePath = path.relative('src/pug/pages', filePath)
|
||
const outputPath = path.join('dist', relativePath.replace('.pug', '.html'))
|
||
|
||
console.log(`📄 Обработка файла: ${relativePath}`)
|
||
|
||
return gulp
|
||
.src(filePath)
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Pug Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(
|
||
pug({
|
||
pretty: true,
|
||
basedir: 'src/pug',
|
||
locals: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
}
|
||
})
|
||
)
|
||
.pipe(rename(path.basename(outputPath)))
|
||
.pipe(gulp.dest(path.dirname(outputPath)))
|
||
}
|
||
|
||
// Обработка конкретного Twig файла
|
||
const processSingleTwigFile = (filePath) => {
|
||
const data = loadData()
|
||
const relativePath = path.relative('src/twig/pages', filePath)
|
||
const outputPath = path.join('dist', relativePath.replace('.twig', '.html'))
|
||
|
||
console.log(`📄 Обработка файла: ${relativePath}`)
|
||
|
||
return gulp
|
||
.src(filePath)
|
||
.pipe(plumber({
|
||
errorHandler(err) {
|
||
console.error('Twig Error:', err.toString())
|
||
this.emit('end')
|
||
}
|
||
}))
|
||
.pipe(
|
||
twig({
|
||
base: 'src/twig',
|
||
data: {
|
||
baseUrl,
|
||
searchId,
|
||
getSrcset: getImageSrcset,
|
||
getMime: getImageMime,
|
||
...data
|
||
},
|
||
functions: [
|
||
{
|
||
name: 'getSrcset',
|
||
func: getImageSrcset
|
||
},
|
||
{
|
||
name: 'getMime',
|
||
func: getImageMime
|
||
}
|
||
]
|
||
})
|
||
)
|
||
.pipe(rename(path.basename(outputPath)))
|
||
.pipe(gulp.dest(path.dirname(outputPath)))
|
||
}
|
||
|
||
// Сервер с поддержкой HTTPS
|
||
const server = () => {
|
||
let serverConfig = {
|
||
server: 'dist/',
|
||
notify: settings.server.notify,
|
||
open: settings.server.open,
|
||
cors: true,
|
||
ui: false,
|
||
port: settings.server.port,
|
||
host: settings.server.host
|
||
}
|
||
|
||
if (settings.https.enabled) {
|
||
const keyPath = path.join(__dirname, settings.https.keyPath)
|
||
const certPath = path.join(__dirname, settings.https.certPath)
|
||
|
||
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
||
serverConfig.https = {
|
||
key: keyPath,
|
||
cert: certPath
|
||
}
|
||
console.log('🔒 Запуск сервера с HTTPS')
|
||
console.log(`📍 https://${serverConfig.host}:${serverConfig.port}`)
|
||
} else {
|
||
console.log('⚠️ HTTPS включен, но сертификаты не найдены')
|
||
console.log('Запустите: gulp ssl для создания сертификатов')
|
||
}
|
||
} else {
|
||
console.log('🌐 Запуск HTTP сервера')
|
||
console.log(`📍 http://${serverConfig.host}:${serverConfig.port}`)
|
||
}
|
||
|
||
sync.init(serverConfig)
|
||
|
||
// Умное наблюдение за страницами
|
||
if (settings.templateEngine === 'twig') {
|
||
// Отслеживание изменений в страницах Twig
|
||
const twigWatcher = gulp.watch('src/twig/pages/**/*.twig')
|
||
twigWatcher.on('change', (filePath) => {
|
||
console.log(`🔄 Изменен файл: ${path.relative(__dirname, filePath)}`)
|
||
return gulp.series(
|
||
() => processSingleTwigFile(filePath),
|
||
refresh
|
||
)()
|
||
})
|
||
|
||
// Наблюдение за общими файлами - полная пересборка
|
||
gulp.watch(['src/twig/**/*.twig', '!src/twig/pages/**/*.twig'], gulp.series(() => html(false), injectSprite, refresh))
|
||
} else {
|
||
// Отслеживание изменений в страницах Pug
|
||
const pugWatcher = gulp.watch('src/pug/pages/**/*.pug')
|
||
pugWatcher.on('change', (filePath) => {
|
||
console.log(`🔄 Изменен файл: ${path.relative(__dirname, filePath)}`)
|
||
return gulp.series(
|
||
() => processSinglePugFile(filePath),
|
||
refresh
|
||
)()
|
||
})
|
||
|
||
// Наблюдение за общими файлами - полная пересборка
|
||
gulp.watch(['src/pug/**/*.pug', '!src/pug/pages/**/*.pug'], gulp.series(() => html(false), injectSprite, refresh))
|
||
}
|
||
|
||
// Наблюдение за данными - полная пересборка
|
||
gulp.watch('src/data/**/*.json', gulp.series(() => html(false), injectSprite, refresh))
|
||
|
||
// Наблюдение за спрайтами - полная пересборка с инъекцией
|
||
gulp.watch('src/icons/**/*.svg', gulp.series(sprite, () => html(false), injectSprite, refresh))
|
||
|
||
// Остальные файлы
|
||
gulp.watch('src/scss/**/*.scss', gulp.series(css))
|
||
gulp.watch('src/js/**/*.js', gulp.series(js, refresh))
|
||
gulp.watch('src/img/**/*.{png,jpg,jpeg,svg}', gulp.series(processImages, refresh))
|
||
}
|
||
|
||
// Экспорт задач
|
||
export const build = gulp.series(
|
||
clean,
|
||
copy,
|
||
css,
|
||
js,
|
||
processImages,
|
||
sprite,
|
||
() => html(false),
|
||
injectSprite
|
||
)
|
||
|
||
export const dev = gulp.series(build, server)
|
||
export const data = createDataExample
|
||
export const ssl = createSSLCerts
|
||
export const configInit = createHTTPSConfig
|
||
export const configReload = reloadConfig
|
||
|
||
// HTTPS команды
|
||
export const devSSL = gulp.series(
|
||
(done) => {
|
||
settings.https.enabled = true
|
||
done()
|
||
},
|
||
ssl,
|
||
build,
|
||
server
|
||
)
|
||
|
||
// Команды с выбором шаблонизатора
|
||
export const buildPug = gulp.series(
|
||
(done) => { settings.templateEngine = 'pug'; done() },
|
||
build
|
||
)
|
||
|
||
export const buildTwig = gulp.series(
|
||
(done) => { settings.templateEngine = 'twig'; done() },
|
||
build
|
||
)
|
||
|
||
export const devPug = gulp.series(
|
||
(done) => { settings.templateEngine = 'pug'; done() },
|
||
build,
|
||
server
|
||
)
|
||
|
||
export const devTwig = gulp.series(
|
||
(done) => { settings.templateEngine = 'twig'; done() },
|
||
build,
|
||
server
|
||
)
|
||
|
||
export const devPugSSL = gulp.series(
|
||
(done) => {
|
||
settings.templateEngine = 'pug'
|
||
settings.https.enabled = true
|
||
done()
|
||
},
|
||
ssl,
|
||
build,
|
||
server
|
||
)
|
||
|
||
export const devTwigSSL = gulp.series(
|
||
(done) => {
|
||
settings.templateEngine = 'twig'
|
||
settings.https.enabled = true
|
||
done()
|
||
},
|
||
ssl,
|
||
build,
|
||
server
|
||
) |