/
topboy
/
Gulp-template
Обзор
Документация
Войти
/
topboy
/
Gulp-template
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
module
gulpfile.mjs
137 строк
4 KB
Sergey Kolmakov
refactor to module
23 янв 2026, 07:39
23 янв 2026, 07:39
06e87cc
Код
Авторство
О чём код?
import { src, dest, watch, parallel, series } from 'gulp'; import gulpSass from 'gulp-sass'; import * as sass from 'sass'; import concat from 'gulp-concat'; import imagemin from 'gulp-imagemin'; import rename from 'gulp-rename'; import nunjucksRender from 'gulp-nunjucks-render'; import uglify from 'gulp-uglify-es'; import browserSync from 'browser-sync'; import autoprefixer from 'gulp-autoprefixer'; import clean from 'gulp-clean'; import fs from 'fs'; import path from 'path'; const bs = browserSync.create(); const DATA_DIR = 'app/data'; // Компилятор SCSS const sassCompiler = gulpSass(sass); // Шаблоны Nunjucks function nunjucks() { return src('app/*.njk') .pipe(nunjucksRender({ path: ['app/templates/'], manageEnv: function (env) { const jsonCache = {}; function loadJson(filename) { if (filename.includes('..') || path.isAbsolute(filename)) { throw new Error(`Запрещённый путь: ${filename}`); } const filePath = path.join(DATA_DIR, `${filename}.json`); if (!fs.existsSync(filePath)) { throw new Error(`Файл не найден: ${filename}.json`); } if (!jsonCache[filePath]) { jsonCache[filePath] = JSON.parse(fs.readFileSync(filePath, 'utf8')); } return jsonCache[filePath]; } env.addGlobal('import_json', loadJson); } })) .pipe(dest('dist')) .pipe(bs.stream()); } // Скрипты function scripts() { return src([ 'app/js/main.js', 'node_modules/jquery/dist/jquery.js', ]) .pipe(concat('main.min.js')) .pipe(uglify.default()) .pipe(dest('dist/js')) .pipe(bs.stream()); } // Стили function styles() { return src('app/scss/style.scss') .pipe(sassCompiler({ outputStyle: 'compressed', includePaths: ['app/scss'] }).on('error', sassCompiler.logError)) // 1. Сначала компилируем .pipe(autoprefixer({ overrideBrowserslist: ['last 5 versions'], grid: true })) // 2. Потом префиксы .pipe(rename({ suffix: '.min' })) .pipe(dest('dist/css')) .pipe(bs.stream()); // Инъекция стилей без перезагрузки } // Оптимизация изображений function images() { return src('app/images/**/*.{jpg,jpeg,png,gif,webp,svg,avif}', { encoding: false }) .pipe(imagemin([ imagemin.gifsicle({ interlaced: true }), imagemin.mozjpeg({ quality: 75, progressive: true }), imagemin.optipng({ optimizationLevel: 5 }), imagemin.svgo({ plugins: [ { removeViewBox: true }, { cleanupIDs: false } ] }) ])) .pipe(dest('dist/images')); } // Копирование без обработки (например, если не поддерживается .avif в imagemin) function copyImages() { return src('app/images/**/*.{jpg,jpeg,png,gif,webp,svg}', { encoding: false }) .pipe(dest('dist/images')); } // Сервер function browser(done) { bs.init({ server: { baseDir: 'dist/' }, notify: false }); done(); // Теперь это сработает } function copyFonts() { return src('app/fonts/**/*', { encoding: false }) // encoding: false обязателен для шрифтов .pipe(dest('dist/fonts')) .pipe(bs.stream()); } // Отслеживание изменений function watching() { // Попробуй БЕЗ точки в начале, но с использованием 'app/...' watch('app/scss/**/*.scss', { usePolling: true, interval: 500 }, styles); watch('app/js/**/*.js', { usePolling: true, interval: 500 }, scripts); watch(['app/**/*.njk', 'app/templates/**/*.njk', 'app/data/**/*.json'], { usePolling: true, interval: 500 }, nunjucks); } // Очистка папки dist function cleanDist() { return src('dist', { allowEmpty: true }) .pipe(clean()); } // Экспорт export { styles, scripts, images, copyImages, nunjucks, watching, browser, cleanDist }; export default series(cleanDist, parallel(nunjucks, styles, scripts, copyImages, copyFonts), browser, watching);