Gulp (4.x) File that just works (including npm dependencies and webp-Support)

/** * Gulpfile * * Usage: * $ npm i --save-dev gulp gulp-postcss autoprefixer gulp-browserify gulp-clean-css gulp-concat del babelify gulp-uglify gulp-px-to-rem gulp-sass gulp-sourcemaps gulp-twig gulp-connect deepmerge gulp-htmlmin gulp-imagemin imagemin-webp gulp-ext-replace * $ gulp build (for deployment only) * $ gulp serve (for development) */ 'use strict'; // Import Requirements const autoprefixer = require('autoprefixer'); const babelify = require('babelify'); const browserify = require('gulp-browserify'); const cleanCSS = require('gulp-clean-css'); const concat = require('gulp-concat'); const connect = require('gulp-connect'); const deepMerge = require('deepmerge'); const del = require('del'); const extReplace = require('gulp-ext-replace'); const gulp = require('gulp'); const gzip = require('gulp-gzip'); const htmlmin = require('gulp-htmlmin'); const imagemin = require('gulp-imagemin'); const postcss = require('gulp-postcss'); const px2rem = require('gulp-px-to-rem'); const sass = require('gulp-sass'); const sourcemaps = require('gulp-sourcemaps'); const twig = require('gulp-twig'); const uglify = require('gulp-uglify'); const webp = require('imagemin-webp'); // Custom Variables const src = './src'; const components = src + '/components/**/*'; const assets = src + '/assets/**/*'; const assetsImages = src + '/assets/images/**/*'; const dist = './dist'; const twigTemplates = src + '/components/views/*.twig'; const js = [src + '/js/index.js']; const scss = [src + '/scss/index.scss']; const css = 'index.css'; const baseFontSize = 16; // base font size in pixel const languages = ['de', 'en']; const postCssPlugins = [ autoprefixer() // Use .browserslistrc ]; /** * When building html, we need to use uncached json data. * require() returns cached file content, so we delete the cache before requiring a json file. * * ! Comment: Does not work for nested json structure * TODO Solve nested json structure */ function requireUncached(module) { delete require.cache[require.resolve(module)]; return require(module); } /** * Sub-Task: Build JS * * - Compile ES6 -> ES5 * - Create Sourcemaps * - Minify (with uglify) */ // Node Modules for Gulp Task 'build:js' // "devDependencies": { // "babel-preset-es2015": "^6.24.1", // "babelify": "^7.3.0", // "gulp-sourcemaps": "^2.6.5", // "gulp-uglify": "^3.0.2", // "gulp-browserify": "^0.5.1" // } gulp.task( 'build:js', () => gulp .src(js) .pipe( browserify({ debug: true, transform: [ babelify.configure({ presets: ['es2015'], sourceMaps: true }) ] }) ) .pipe(sourcemaps.init({ loadMaps: true })) // init sourcemaps .pipe(uglify()) // minify // .pipe(gzip()) .pipe(sourcemaps.write('.')) // write sourcemaps .pipe(gulp.dest(dist)) // output .pipe(connect.reload()) // reload ); /** * Sub-Task: Build CSS * * - Compile SCSS -> CSS * - Add Browserprefixes * - Minify * - Concat to a single File * - Create Sourcemaps */ gulp.task( 'build:css', () => gulp .src(scss) .pipe(sourcemaps.init()) // init sourcemaps .pipe(sass()) // do the sass .pipe(postcss(postCssPlugins)) .pipe(cleanCSS()) // cleanup & minify .pipe(px2rem({ rootPX: baseFontSize })) // convert pixels to rem .pipe(concat(css)) // zusammenführen der Dateien (hier nur eine) // .pipe(gzip()) .pipe(sourcemaps.write('.')) // write sourcemaps .pipe(gulp.dest(dist)) // output .pipe(connect.reload()) // reload ); /** * Sub-Task: Build HTML * * - Compile Twig -> HTML */ gulp.task('build:html', () => { const data = Object.assign( {}, { data: requireUncached(src + '/data/data.js'), interface: requireUncached(src + '/data/interface.js') } ); return Promise.all( languages.map(lang => { return new Promise(resolve => { return gulp .src(twigTemplates) .pipe( twig({ data: deepMerge.all([data, { lang, data: { lang } }]), filters: [ { name: 'withModifier', func: function(prefix, modifier) { let classes = [prefix]; const modifiers = modifier[0] || []; classes = [ ...classes, ...modifiers.filter(suffix => suffix).map(suffix => `${prefix}--${suffix}`) ]; return classes.join(' '); } }, { name: 'slugify', func: function(text) { return text .toString() .toLowerCase() .replace(/\s+/g, '-') // Replace spaces with - .replace(/[^\w\-]+/g, '') // Remove all non-word chars .replace(/\-\-+/g, '-') // Replace multiple - with single - .replace(/^-+/, '') // Trim - from start of text .replace(/-+$/, ''); // Trim - from end of text } }, { name: 'removeExtension', func: function(filename) { return filename .split('.') .slice(0, -1) .join('.'); } }, { name: 'getExtension', func: function(filename) { return filename.split('.').pop(); } } ] }) ) .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest(lang === 'de' ? `${dist}` : `${dist}/${lang}`)) .pipe(connect.reload()) // reload .on('end', resolve); }); }) ); }); /** * Sub-Task: Build Assets * * - Add Assets to Distribution * - Excludes /assets/images (see build:png, build:jpg, build:svg, build:webp) */ gulp.task('build:assets', () => gulp.src([assets, '!' + assetsImages]).pipe(gulp.dest(dist + '/assets/')) ); /** * Sub-Task: Build PNG * * - Reduce Filesize * - Add Assets to Distribution */ gulp.task('build:png', () => gulp .src(assetsImages + '.png') .pipe( imagemin([ // https://github.com/imagemin/imagemin-optipng (comes with gulp-imagemin) imagemin.optipng({ optimizationLevel: 3 }) ]) ) .pipe(gulp.dest(dist + '/assets/images')) ); /** * Sub-Task: Build JPG * * - Reduce Filesize * - Add Assets to Distribution */ gulp.task('build:jpg', () => gulp .src(assetsImages + '.{jpg,jpeg}') .pipe( imagemin([ // https://github.com/imagemin/imagemin-jpegtran (comes with gulp-imagemin) imagemin.jpegtran({ progressive: true }) ]) ) .pipe(gulp.dest(dist + '/assets/images')) ); /** * Sub-Task: Build SVG * * - Add Assets to Distribution */ gulp.task('build:svg', () => gulp.src(assetsImages + '.svg').pipe(gulp.dest(dist + '/assets/images')) ); /** * Sub-Task: Build Webp * * - Create webp files from jpg, jpeg and png files * - Add Assets to Distribution */ gulp.task('build:webp', () => gulp .src(assetsImages + '.{jpg,jpeg,png}') .pipe( imagemin([ // imagemin-webp from https://github.com/imagemin/imagemin-webp webp({ quality: 75 }) ]) ) .pipe(extReplace('.webp')) .pipe(gulp.dest(dist + '/assets/images')) ); /** * Task: Clean * * - Remove the Distribution folder */ gulp.task('clean', () => { return del([`${dist}**/*`]); }); /** * Task: Connect */ gulp.task('connect', function() { connect.server({ host: '0.0.0.0', root: ['dist/', 'dist/en'], livereload: true }); }); /** * Task: Watch */ gulp.task('watch', function(cb) { // Watch SCSS gulp.watch(src + '/scss/**/*.scss', gulp.series('build:css')); gulp.watch(components + '.scss', gulp.series('build:css')); gulp.watch(components + '.css', gulp.series('build:css')); // Watch JS gulp.watch(src + '/js/**/*.js', gulp.series('build:js')); gulp.watch(components + '.js', gulp.series('build:js')); // Watch TWIG Views gulp.watch(components + '.twig', gulp.series('build:html')); gulp.watch(`${src}/**/*.json`, gulp.series('build:html')); cb(); }); /** * Task: Build * * The Distribution of this build can be deployed * * - Start Task "Clean" * - Start Sub-Tasks */ gulp.task( 'build', gulp.series( 'clean', gulp.parallel( 'build:js', 'build:css', 'build:html', 'build:assets', 'build:png', 'build:jpg', 'build:svg', 'build:webp' ) ) ); /** * Task: Serve * * Start a local server to serve files from dist/ */ gulp.task('serve', gulp.series('build', gulp.parallel('connect', 'watch'))); /** * Task: Default * * Watch for changes and Re-Build * Usage in command line: `$ gulp` * * - Start watching SCSS, JS and HTML Files */ gulp.task('default', gulp.series('build', 'watch'));
→ What it does

- Compile SCSS to CSS
- Clean Up CSS
- Prefix CSS (including CSS Grid for IE11)
- Compile ES6 to ES5
- Compile Twig to HTML
- Duplicate Assets
- Minify Images
- Create Webp Files
- Serve File on localhost (via `gulp serve`)

→ Usage

- Build: run `gulp build` to create a Distribution in /dist that can be deployed to any Server.
- Serve: run `gulp serve` for Development. It will start a local Server (default: http://localhost:8080/) and refresh once you update CSS, JS or HTML.

→ Install Dependencies
- see comments in file above

Be the first to comment

You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.