├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── example.html ├── favicon.ico ├── images │ └── gulp.png ├── index.html ├── js │ ├── main.js │ └── vendors │ │ └── example.js └── scss │ ├── abstracts │ ├── _all.scss │ ├── _functions.scss │ ├── _mixins.scss │ └── _variables.scss │ ├── base │ ├── _all.scss │ ├── _base.scss │ ├── _typography.scss │ └── _utilities.scss │ ├── main.scss │ └── pages │ ├── _all.scss │ ├── _example.scss │ └── _index.scss ├── gulpfile.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Custom 3 | # 4 | 5 | # Build folder (get's generated when running any start or build commands) 6 | Build 7 | 8 | # 9 | # Standard Node .gitignore 10 | # 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | lerna-debug.log* 19 | 20 | # Diagnostic reports (https://nodejs.org/api/report.html) 21 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 22 | 23 | # Runtime data 24 | pids 25 | *.pid 26 | *.seed 27 | *.pid.lock 28 | 29 | # Directory for instrumented libs generated by jscoverage/JSCover 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | coverage 34 | *.lcov 35 | 36 | # nyc test coverage 37 | .nyc_output 38 | 39 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 40 | .grunt 41 | 42 | # Bower dependency directory (https://bower.io/) 43 | bower_components 44 | 45 | # node-waf configuration 46 | .lock-wscript 47 | 48 | # Compiled binary addons (https://nodejs.org/api/addons.html) 49 | build/Release 50 | 51 | # Dependency directories 52 | node_modules/ 53 | jspm_packages/ 54 | 55 | # TypeScript v1 declaration files 56 | typings/ 57 | 58 | # TypeScript cache 59 | *.tsbuildinfo 60 | 61 | # Optional npm cache directory 62 | .npm 63 | 64 | # Optional eslint cache 65 | .eslintcache 66 | 67 | # Microbundle cache 68 | .rpt2_cache/ 69 | .rts2_cache_cjs/ 70 | .rts2_cache_es/ 71 | .rts2_cache_umd/ 72 | 73 | # Optional REPL history 74 | .node_repl_history 75 | 76 | # Output of 'npm pack' 77 | *.tgz 78 | 79 | # Yarn Integrity file 80 | .yarn-integrity 81 | 82 | # dotenv environment variables file 83 | .env 84 | .env.test 85 | 86 | # parcel-bundler cache (https://parceljs.org/) 87 | .cache 88 | 89 | # Next.js build output 90 | .next 91 | 92 | # Nuxt.js build / generate output 93 | .nuxt 94 | dist 95 | 96 | # Gatsby files 97 | .cache/ 98 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 99 | # https://nextjs.org/blog/next-9-1#public-directory-support 100 | # public 101 | 102 | # vuepress build output 103 | .vuepress/dist 104 | 105 | # Serverless directories 106 | .serverless/ 107 | 108 | # FuseBox cache 109 | .fusebox/ 110 | 111 | # DynamoDB Local files 112 | .dynamodb/ 113 | 114 | # TernJS port file 115 | .tern-port -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Lucas Winkler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gulp Boilerplate [![Build Status](https://travis-ci.com/LucasWinkler/gulp-boilerplate.svg?token=6xPTYyj9yJazuMpzepqi&branch=master)](https://travis-ci.com/LucasWinkler/gulp-boilerplate) 2 | 3 | A simple boilerplate for front-end web development which uses [Gulp](https://gulpjs.com/) v4. 4 | 5 | This is my first time trying gulp so it won't be perfect. I just wanted to create a basic template to work off of with a file structure I liked. 6 | 7 | ## Features 8 | 9 | - Live reloading 10 | - Cache busting 11 | - SCSS converted to css, auto prefixed and minified with sourcemaps) 12 | - Javascript concatenated into a single file, minified with sourcemaps and supports ES6) 13 | - Image minifying 14 | 15 | ## Getting Started 16 | 17 | Follow these steps in order to get the website up and running locally on your machine. 18 | 19 | ### Installation 20 | 21 | - `npm install` to install any dependencies 22 | - `npm start` or `gulp watch` to start a live reload session 23 | 24 | ### Building 25 | 26 | - `npm run build` or `gulp` to build the application 27 | 28 | ### Extras 29 | 30 | - `gulp` or `gulp build` to build the application 31 | - `gulp watch` to enable live reload 32 | - `gulp clean` to delete the build folder 33 | - `gulp styles` to run the style tasks 34 | - `gulp scripts` to run the script tasks 35 | - `gulp images` to run the image tasks 36 | - `gulp favicon` to run the favicon tasks 37 | 38 | ## File Structure 39 | 40 | ```bash 41 | ├── app 42 | │ ├── images 43 | │ │ 44 | │ ├── js 45 | │ │ ├── main.js 46 | │ │ │ 47 | │ │ └── vendors 48 | │ │ 49 | │ └── scss 50 | │ ├── abstracts 51 | │ │ 52 | │ ├── base 53 | │ │ 54 | │ ├── pages 55 | │ │ 56 | │ └── main.scss 57 | │ 58 | └── build 59 | ├── images 60 | │ 61 | ├── js 62 | │ ├── app.min.js 63 | │ │ 64 | │ └── vendors.min.js 65 | │ 66 | └── css 67 | └── styles.min.css 68 | ``` 69 | 70 | ## Tips 71 | 72 | - You can use any file structure for your javascript and scss files. The one provided is an example. -------------------------------------------------------------------------------- /app/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Lucas Winkler's Gulp v4 Boilerplate | Example 11 | 12 | 13 | 14 | 15 | 16 |
17 |

Example Page

18 |

Edit this paragraph and save to watch it reload!

19 | Go back to the home page 20 |

21 | Source 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LucasWinkler/gulp-boilerplate/65233c48458f1b97fb55bc6a7cfb1c4a8fb09b06/app/favicon.ico -------------------------------------------------------------------------------- /app/images/gulp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LucasWinkler/gulp-boilerplate/65233c48458f1b97fb55bc6a7cfb1c4a8fb09b06/app/images/gulp.png -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Lucas Winkler's Gulp v4 Boilerplate 11 | 12 | 13 | 14 | 15 | 16 |
17 | Gulp Logo 18 |

Hello, Developer!

19 |

Modify any source files and your browser will refresh live!

20 | Go to another example page 21 |

22 | Source 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/js/main.js: -------------------------------------------------------------------------------- 1 | // Your main script 2 | 3 | const index = 'This is a placeholder!'; 4 | -------------------------------------------------------------------------------- /app/js/vendors/example.js: -------------------------------------------------------------------------------- 1 | // You can delete this 2 | 3 | const example = 'This is a placeholder for any vendors/libraries you may want'; 4 | -------------------------------------------------------------------------------- /app/scss/abstracts/_all.scss: -------------------------------------------------------------------------------- 1 | @import './variables'; 2 | @import './functions'; 3 | @import './mixins'; 4 | -------------------------------------------------------------------------------- /app/scss/abstracts/_functions.scss: -------------------------------------------------------------------------------- 1 | // Scss functions 2 | -------------------------------------------------------------------------------- /app/scss/abstracts/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Scss mixins 2 | -------------------------------------------------------------------------------- /app/scss/abstracts/_variables.scss: -------------------------------------------------------------------------------- 1 | // Scss variables (colours etc...) 2 | 3 | $primary-colour: #333333; 4 | -------------------------------------------------------------------------------- /app/scss/base/_all.scss: -------------------------------------------------------------------------------- 1 | @import './typography'; 2 | @import './base'; 3 | @import './utilities'; 4 | -------------------------------------------------------------------------------- /app/scss/base/_base.scss: -------------------------------------------------------------------------------- 1 | // Base styles 2 | 3 | *, 4 | *::before, 5 | *::after { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | } 10 | 11 | html, 12 | body { 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | scroll-behavior: smooth; 16 | } 17 | -------------------------------------------------------------------------------- /app/scss/base/_typography.scss: -------------------------------------------------------------------------------- 1 | // Font imports and variables 2 | 3 | $primary-font: 'Arial', sans-serif; 4 | -------------------------------------------------------------------------------- /app/scss/base/_utilities.scss: -------------------------------------------------------------------------------- 1 | // Reusuable classes 2 | 3 | .container { 4 | max-width: 1400px; 5 | margin: 0 auto; 6 | padding: 0 20px; 7 | } 8 | -------------------------------------------------------------------------------- /app/scss/main.scss: -------------------------------------------------------------------------------- 1 | @import './abstracts/all'; 2 | @import './base/all'; 3 | @import './pages/all'; 4 | -------------------------------------------------------------------------------- /app/scss/pages/_all.scss: -------------------------------------------------------------------------------- 1 | @import './index.scss'; 2 | @import './example'; 3 | -------------------------------------------------------------------------------- /app/scss/pages/_example.scss: -------------------------------------------------------------------------------- 1 | #example-page { 2 | display: flex; 3 | align-items: center; 4 | text-align: center; 5 | font-family: $primary-font; 6 | height: 100vh; 7 | color: $primary-colour; 8 | 9 | h1 { 10 | font-size: 52px; 11 | margin: 16px 0; 12 | } 13 | 14 | p { 15 | font-size: 20px; 16 | margin: 16px 0; 17 | } 18 | 19 | a { 20 | text-decoration: none; 21 | color: #2661e0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/scss/pages/_index.scss: -------------------------------------------------------------------------------- 1 | #index-page { 2 | display: flex; 3 | align-items: center; 4 | text-align: center; 5 | font-family: $primary-font; 6 | height: 100vh; 7 | color: $primary-colour; 8 | 9 | h1 { 10 | font-size: 32px; 11 | margin: 16px 0; 12 | } 13 | 14 | p { 15 | font-size: 20px; 16 | margin: 16px 0; 17 | } 18 | 19 | img { 20 | width: 100%; 21 | max-width: 35%; 22 | margin-bottom: 16px; 23 | } 24 | 25 | a { 26 | text-decoration: none; 27 | color: #2661e0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const sass = require('gulp-sass'); 3 | const babel = require('gulp-babel'); 4 | const sourcemaps = require('gulp-sourcemaps'); 5 | const concat = require('gulp-concat'); 6 | const terser = require('gulp-terser'); 7 | const rename = require('gulp-rename'); 8 | const del = require('del'); 9 | const browserSync = require('browser-sync').create(); 10 | const postcss = require('gulp-postcss'); 11 | const autoprefixer = require('autoprefixer'); 12 | const cssnano = require('cssnano'); 13 | const replace = require('gulp-replace'); 14 | const imagemin = require('gulp-imagemin'); 15 | const plumber = require('gulp-plumber'); 16 | 17 | const paths = { 18 | html: { 19 | src: './app/**/*.html', 20 | dest: './build' 21 | }, 22 | styles: { 23 | src: './app/scss/**/*.scss', 24 | dest: './build/assets/css' 25 | }, 26 | scripts: { 27 | src: './app/js/**/*.js', 28 | dest: './build/assets/js' 29 | }, 30 | vendors: { 31 | src: './app/js/vendors/**/*.js', 32 | dest: './build/assets/js' 33 | }, 34 | images: { 35 | src: './app/images/**/*', 36 | dest: './build/assets/images' 37 | }, 38 | favicon: { 39 | src: './app/favicon.ico', 40 | dest: './build' 41 | } 42 | }; 43 | 44 | const clean = () => del(['./build']); 45 | 46 | // Cache busting to prevent browser caching issues 47 | const curTime = new Date().getTime(); 48 | const cacheBust = () => 49 | gulp 50 | .src(paths.html.src) 51 | .pipe(plumber()) 52 | .pipe(replace(/cb=\d+/g, 'cb=' + curTime)) 53 | .pipe(gulp.dest(paths.html.dest)); 54 | 55 | 56 | // Copies all html files 57 | const html =() => 58 | gulp 59 | .src(paths.html.src) 60 | .pipe(plumber()) 61 | .pipe(gulp.dest(paths.html.dest)); 62 | 63 | // Convert scss to css, auto-prefix and rename into styles.min.css 64 | const styles = () => 65 | gulp 66 | .src(paths.styles.src) 67 | .pipe(plumber()) 68 | .pipe(sourcemaps.init()) 69 | .pipe(sass().on('error', sass.logError)) 70 | .pipe(postcss([autoprefixer(), cssnano()])) 71 | .pipe( 72 | rename({ 73 | basename: 'styles', 74 | suffix: '.min' 75 | }) 76 | ) 77 | .pipe(sourcemaps.write('.')) 78 | .pipe(gulp.dest(paths.styles.dest)) 79 | .pipe(browserSync.stream()); 80 | 81 | // Minify all javascript files and concat them into a single app.min.js 82 | const scripts = () => 83 | gulp 84 | .src(paths.scripts.src) 85 | .pipe(plumber()) 86 | .pipe(sourcemaps.init()) 87 | .pipe( 88 | babel({ 89 | presets: ['@babel/preset-env'] 90 | }) 91 | ) 92 | .pipe(terser()) 93 | .pipe(concat('app.min.js')) 94 | .pipe(sourcemaps.write('.')) 95 | .pipe(gulp.dest(paths.scripts.dest)); 96 | 97 | // Minify all javascript vendors/libs and concat them into a single vendors.min.js 98 | const vendors = () => 99 | gulp 100 | .src(paths.vendors.src) 101 | .pipe(plumber()) 102 | .pipe(sourcemaps.init()) 103 | .pipe( 104 | babel({ 105 | presets: ['@babel/preset-env'] 106 | }) 107 | ) 108 | .pipe(terser()) 109 | .pipe(concat('vendors.min.js')) 110 | .pipe(sourcemaps.write('.')) 111 | .pipe(gulp.dest(paths.vendors.dest)); 112 | 113 | // Copy and minify images 114 | const images = () => 115 | gulp 116 | .src(paths.images.src) 117 | .pipe(plumber()) 118 | .pipe(imagemin()) 119 | .pipe(gulp.dest(paths.images.dest)); 120 | 121 | // Copy the favicon 122 | const favicon = () => 123 | gulp 124 | .src(paths.favicon.src) 125 | .pipe(plumber()) 126 | .pipe(gulp.dest(paths.favicon.dest)); 127 | 128 | // Watches all .scss, .js and .html changes and executes the corresponding task 129 | function watchFiles() { 130 | browserSync.init({ 131 | server: { 132 | baseDir: './build' 133 | }, 134 | notify: false 135 | }); 136 | 137 | gulp.watch(paths.styles.src, styles); 138 | gulp.watch(paths.vendors.src, vendors).on('change', browserSync.reload); 139 | gulp.watch(paths.favicon.src, favicon).on('change', browserSync.reload); 140 | gulp.watch(paths.scripts.src, scripts).on('change', browserSync.reload); 141 | gulp.watch(paths.images.src, images).on('change', browserSync.reload); 142 | gulp.watch('./app/*.html', html).on('change', browserSync.reload); 143 | } 144 | 145 | const build = gulp.series( 146 | clean, 147 | gulp.parallel(styles, vendors, scripts, images, favicon), 148 | cacheBust 149 | ); 150 | 151 | const watch = gulp.series(build, watchFiles); 152 | 153 | exports.clean = clean; 154 | exports.styles = styles; 155 | exports.scripts = scripts; 156 | exports.vendors = vendors; 157 | exports.images = images; 158 | exports.favicon = favicon; 159 | exports.watch = watch; 160 | exports.build = build; 161 | exports.default = build; 162 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-boilerplate", 3 | "version": "1.0.0", 4 | "description": "A simple boilerplate for front-end web development - built with Gulp v4", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "start": "gulp watch", 8 | "build": "gulp", 9 | "clean": "gulp clean" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/LucasWinkler/gulp-boilerplate.git" 14 | }, 15 | "keywords": [ 16 | "gulp", 17 | "gulp-v4", 18 | "boilerplate", 19 | "front-end" 20 | ], 21 | "author": "Lucas Winkler", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/LucasWinkler/gulp-boilerplate/issues" 25 | }, 26 | "homepage": "https://github.com/LucasWinkler/gulp-boilerplate#readme", 27 | "devDependencies": { 28 | "@babel/core": "^7.8.3", 29 | "@babel/preset-env": "^7.8.3", 30 | "autoprefixer": "^9.7.4", 31 | "browser-sync": "^2.27.11", 32 | "cssnano": "^4.1.10", 33 | "del": "^5.1.0", 34 | "gulp": "^4.0.2", 35 | "gulp-babel": "^8.0.0", 36 | "gulp-concat": "^2.6.1", 37 | "gulp-imagemin": "^7.1.0", 38 | "gulp-plumber": "^1.2.1", 39 | "gulp-postcss": "^8.0.0", 40 | "gulp-rename": "^2.0.0", 41 | "gulp-replace": "^1.0.0", 42 | "gulp-sass": "^5.1.0", 43 | "gulp-sourcemaps": "^2.6.5", 44 | "gulp-terser": "^1.2.0" 45 | } 46 | } 47 | --------------------------------------------------------------------------------