Skip to content

Commit

Permalink
- Re-written entire file to be updated with Gulp 4+
Browse files Browse the repository at this point in the history
- Added Port to config

- Fixed Styles order by renaming tailwindcss to a.tailwindcss as Gulp follows alphabetic order in concatination

- Fixed dev and build folders name being hardcoded in cleaning process

- Added External folder which will be excluded in js concatination
  • Loading branch information
manjumjn committed Nov 7, 2020
1 parent 2ac7ed0 commit 26cd720
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 168 deletions.
3 changes: 2 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
config: {
"tailwindjs": "./tailwind.config.js"
tailwindjs: "./tailwind.config.js",
port: 9050
},
paths: {
root: "./",
Expand Down
286 changes: 125 additions & 161 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,181 +1,145 @@
/*=====================================================================*/
/* Gulp with Tailwind Utility framework */
/* Author : Manjunath G */
/* URL : manjumjn.com */
/* Twitter : twitter.com/manju_mjn */
/*=====================================================================*/
/**
* Gulp with Tailwind Utility framework
* Author : Manjunath G
* URL : manjumjn.com
* Twitter : twitter.com/manju_mjn
**/

/*
Usage ::
=======================================================================
1. npm install //To install all dev dependencies of package
2. npm run dev //To start development and server for live preview
3. npm run prod //To generate minifed files for live server
Usage:
1. npm install //To install all dev dependencies of package
2. npm run dev //To start development and server for live preview
3. npm run prod //To generate minifed files for live server
*/

const { src, dest, task, watch, series } = require('gulp');
const { src, dest, task, watch, series, parallel } = require('gulp');
const del = require('del'); //For Cleaning build/dist for fresh export
const options = require("./config"); //Options : paths and other options from config.js
const options = require("./config"); //paths and other options from config.js
const browserSync = require('browser-sync').create();

const sass = require('gulp-sass'); //For Compiling SASS files
const concat = require('gulp-concat'); //For Concatinating js,css files
const postcss = require('gulp-postcss'); //For Compiling tailwind utilities with tailwind config
const concat = require('gulp-concat'); //For Concatinating js,css files
const uglify = require('gulp-uglify');//To Minify JS files
const imagemin = require('gulp-imagemin'); //To Optimize Images
const cleanCSS = require('gulp-clean-css');//To Minify CSS files
const purgecss = require('gulp-purgecss');
const purgecss = require('gulp-purgecss');// Remove Unused CSS from Styles

//Note : Webp still not supported in majpr browsers including forefox
//const webp = require('gulp-webp'); //For converting images to WebP format
//const replace = require('gulp-replace'); //For Replacing img formats to webp in html
const logSymbols = require('log-symbols'); //For Symbolic Console logs :) :P

//Load Previews on Browser on dev
task('livepreview', (done) => {
browserSync.init({
server: {
baseDir: options.paths.dist.base
},
port: 1234
});
done();
});

//Reload functions which triggers browser reload
function livePreview(done){
browserSync.init({
server: {
baseDir: options.paths.dist.base
},
port: options.config.port || 5000
});
done();
}

// Triggers Browser reload
function previewReload(done){
console.log("\n\t" + logSymbols.info,"Reloading Preview.\n");
browserSync.reload();
done();
console.log("\n\t" + logSymbols.info,"Reloading Browser Preview.\n");
browserSync.reload();
done();
}

//Development Tasks
function devHTML(){
return src(`${options.paths.src.base}/**/*.html`).pipe(dest(options.paths.dist.base));
}

function devStyles(){
const tailwindcss = require('tailwindcss');
return src(`${options.paths.src.css}/**/*`).pipe(sass().on('error', sass.logError))
.pipe(postcss([
tailwindcss(options.config.tailwindjs),
require('autoprefixer'),
]))
.pipe(concat({ path: 'style.css'}))
.pipe(dest(options.paths.dist.css));
}

function devScripts(){
return src([
`${options.paths.src.js}/libs/**/*.js`,
`${options.paths.src.js}/**/*.js`,
`!${options.paths.src.js}/**/external/*`
]).pipe(concat({ path: 'scripts.js'})).pipe(dest(options.paths.dist.js));
}

function devImages(){
return src(`${options.paths.src.img}/**/*`).pipe(dest(options.paths.dist.img));
}

function watchFiles(){
watch(`${options.paths.src.base}/**/*.html`,series(devHTML, previewReload));
watch([options.config.tailwindjs, `${options.paths.src.css}/**/*`],series(devStyles, previewReload));
watch(`${options.paths.src.js}/**/*.js`,series(devScripts, previewReload));
watch(`${options.paths.src.img}/**/*`,series(devImages, previewReload));
console.log("\n\t" + logSymbols.info,"Watching for Changes..\n");
}

function devClean(){
console.log("\n\t" + logSymbols.info,"Cleaning dist folder for fresh start.\n");
return del([options.paths.dist.base]);
}

//Production Tasks (Optimized Build for Live/Production Sites)
function prodHTML(){
return src(`${options.paths.src.base}/**/*.html`).pipe(dest(options.paths.build.base));
}

function prodStyles(){
return src(`${options.paths.dist.css}/**/*`).pipe(purgecss({
content: ['src/**/*.{html,js}'],
defaultExtractor: content => {
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || []
return broadMatches.concat(innerMatches)
}
}))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(dest(options.paths.build.css));
}

function prodScripts(){
return src([
`${options.paths.src.js}/libs/**/*.js`,
`${options.paths.src.js}/**/*.js`
])
.pipe(concat({ path: 'scripts.js'}))
.pipe(uglify())
.pipe(dest(options.paths.build.js));
}

function prodImages(){
return src(options.paths.src.img + '/**/*').pipe(imagemin()).pipe(dest(options.paths.build.img));
}

function prodClean(){
console.log("\n\t" + logSymbols.info,"Cleaning build folder for fresh start.\n");
return del([options.paths.build.base]);
}

function buildFinish(done){
console.log("\n\t" + logSymbols.info,`Production build is complete. Files are located at ${options.paths.build.base}\n`);
done();
}

task('dev-html', () => {
return src(options.paths.src.base+'/**/*.html')
//Note : Webp still not supported in majpr browsers including forefox
//.pipe(replace('.jpg', '.webp'))
//.pipe(replace('.png', '.webp'))
//.pipe(replace('.jpeg','.webp'))
.pipe(dest(options.paths.dist.base));
});

task('build-html', () => {
return src(options.paths.src.base+'/**/*.html')
//Note : Webp still not supported in majpr browsers including forefox
//.pipe(replace('.jpg', '.webp'))
//.pipe(replace('.png', '.webp'))
//.pipe(replace('.jpeg','.webp'))
.pipe(dest(options.paths.build.base));
});

//Compiling styles
task('dev-styles', ()=> {
const tailwindcss = require('tailwindcss');
return src(options.paths.src.css + '/**/*')
.pipe(sass().on('error', sass.logError))
.pipe(postcss([
tailwindcss(options.config.tailwindjs),
require('autoprefixer'),
]))
.pipe(concat({ path: 'style.css'}))
.pipe(dest(options.paths.dist.css));
});

//Compiling styles
task('build-styles', ()=> {
return src(options.paths.dist.css + '/**/*')
.pipe(purgecss({
content: ["src/**/*.html", "src/**/.*js"],
defaultExtractor: content => {
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || []
return broadMatches.concat(innerMatches)
}
}))
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(dest(options.paths.build.css));
});

//merging all script files to a single file
task('dev-scripts' ,()=> {
return src([options.paths.src.js + '/libs/**/*.js',options.paths.src.js + '/**/*.js'])
.pipe(concat({ path: 'scripts.js'}))
.pipe(dest(options.paths.dist.js));
});


//merging all script files to a single file
task('build-scripts' ,()=> {
return src([options.paths.src.js + '/libs/**/*.js',options.paths.src.js + '/**/*.js'])
.pipe(concat({ path: 'scripts.js'}))
.pipe(uglify())
.pipe(dest(options.paths.build.js));
});

task('dev-imgs', (done) =>{
src(options.paths.src.img + '/**/*')
//Note : Webp still not supported in majpr browsers including forefox
//.pipe(webp({ quality: 100 }))
.pipe(dest(options.paths.dist.img));
done();
});

task('build-imgs', (done) =>{
src(options.paths.src.img + '/**/*')
//Note : Webp still not supported in majpr browsers including forefox
//.pipe(webp({ quality: 100 }))
.pipe(imagemin())
.pipe(dest(options.paths.build.img));
done();
});


//Watch files for changes
task('watch-changes', (done) => {

//Watching HTML Files edits
watch(options.config.tailwindjs,series('dev-styles',previewReload));

//Watching HTML Files edits
watch(options.paths.src.base+'/**/*.html',series('dev-styles','dev-html',previewReload));

//Watching css Files edits
watch(options.paths.src.css+'/**/*',series('dev-styles',previewReload));

//Watching JS Files edits
watch(options.paths.src.js+'/**/*.js',series('dev-scripts',previewReload));

//Watching Img Files updates
watch(options.paths.src.img+'/**/*',series('dev-imgs',previewReload));

console.log("\n\t" + logSymbols.info,"Watching for Changes made to files.\n");

done();
});

//Cleaning dist folder for fresh start
task('clean:dist', ()=> {
console.log("\n\t" + logSymbols.info,"Cleaning dist folder for fresh start.\n");
return del(['dist']);
});

//Cleaning build folder for fresh start
task('clean:build', ()=> {
console.log("\n\t" + logSymbols.info,"Cleaning build folder for fresh start.\n");
return del(['build']);
});

//series of tasks to run on dev command
task('development', series('clean:dist','dev-html','dev-styles','dev-scripts','dev-imgs',(done)=>{
console.log("\n\t" + logSymbols.info,"npm run dev is complete. Files are located at ./dist\n");
done();
}));

task('optamizedBuild', series('clean:build','build-html','dev-styles','build-styles','build-scripts','build-imgs',(done)=>{
console.log("\n\t" + logSymbols.info,"npm run build is complete. Files are located at ./build\n");
done();
}));


exports.default = series('development','livepreview','watch-changes');
exports.build = series('optamizedBuild');
exports.default = series(
devClean, // Clean Dist Folder
parallel(devStyles, devScripts, devImages, devHTML), //Run All tasks in parallel
livePreview, // Live Preview Build
watchFiles // Watch for Live Changes
);

exports.prod = series(
prodClean, // Clean Build Folder
parallel(prodStyles, prodScripts, prodImages, prodHTML), //Run All tasks in parallel
buildFinish
);
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "gulpfile.js",
"scripts": {
"dev": "gulp",
"prod": "gulp build"
"build": "gulp prod",
"prod": "gulp prod"
},
"keywords": [
"gulp",
Expand Down
7 changes: 5 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ npm run prod
To change the path of files and destination/build folder, edit options in **config.js** file
```sh
{
...
config: {
...
port: 9050 // browser preview port
},
paths: {
root: "./",
src: {
Expand All @@ -47,4 +50,4 @@ To change the path of files and destination/build folder, edit options in **conf
}
...
}
```
```
File renamed without changes.
8 changes: 6 additions & 2 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h1 class="hero-heading">Gulp with TailwindCSS Kit</h1>
<div class="mx-auto py-20 max-w-lg">
<img class="shadow border border-gray-400 rounded hover:shadow-lg mb-10" src="img/cover.jpg" alt="Gulp with TailwindCSS">
<div class="instructions">
<div class="mb-20 text-gray-600">
<div class="mb-20 text-gray-700">
<h4 class="sub-title">Usage</h4>
<p>Use the following commands to get started.</p>
<code class="code">
Expand All @@ -39,7 +39,11 @@ <h4 class="sub-title">Usage</h4>
<h4 class="sub-title">Options</h4>
<p>To change the path of files and destination/build folder configure at <b class="font-bold">config.js</b> file</p>
<!-- Ignore the messay code :P only for demo -->
<code class="code pre">paths: {
<code class="code pre">config: {
...
port: 9050 <em>//Update port here</em>
},
paths: {
root: "./",
src: {
base: "./src",
Expand Down
1 change: 1 addition & 0 deletions src/js/external/external.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// External JS file like jquery etc which you do not wish to inlcuded in minification
2 changes: 1 addition & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
//main.js file
//main.js file

0 comments on commit 26cd720

Please sign in to comment.