When I am trying to save scss files which are imported to main sccs file - every time I need resave main scss file to apply changes. therefore I have decided to install gulp-sass-glob according to this https://www.npmjs.com/package/gulp-sass-glob
but unfortunately it does not work.
Here is my code, please help me how to integrate gulp-sass-glob in my gulp file or what is wrong here. Thank you.
const { src, dest, parallel, series, watch } = require('gulp');
// Load plugins
const sass = require('gulp-sass');
const browsersync = require('browser-sync').create();
const htmlmin = require('gulp-htmlmin');
// Directories
const SRC = './src/';
const DEST = './dist/';
const DEST_CSS = `${DEST}css/`;
const SRC_CSS = `${SRC}scss/*main.scss`;
var gulp = require('gulp');
var sassGlob = require('gulp-sass-glob');
gulp.task('styles', function () {
return gulp
.src(SRC_CSS)
.pipe(sassGlob())
.pipe(sass())
.pipe(gulp.dest(DEST_CSS));
});
// Watch files
function watchFiles() {
watch(`${SRC_CSS}*`, css);
watch(`${SRC}lang`, html);
}
// BrowserSync
function browserSync() {
browsersync.init({
server: {
baseDir: DEST
},
port: PORT
});
}
// Tasks to define the execution of the functions simultaneously or in series
exports.watch = series(
clear,
parallel( css, html, copyStaticHTML, watchFiles, browserSync)
);
exports.default = series(clear, parallel(js, css, html, copyStaticHTML));
Related
I have been working on modifying this relatively simple gulpfile/project: https://github.com/ispykenny/sass-to-inline-css
The first issue I had was to update to gulp v4, but I've also tried to store variables for my src and destination folders which is a bit easier to control. So now my gulpfile looks like this:
const gulp = require('gulp');
const inlineCss = require('gulp-inline-css');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();
const plumber = require('gulp-plumber');
const del = require('del');
const srcFolder = './src'; // TODO tidy this up once working
const buildFolder = srcFolder + '/build/'; // Tidy this up once working
const src = {
scss: 'src/scss/**/*.scss',
templates: 'src/templates/**/*.html'
}
const dest = {
build: 'build/',
css: 'build/css'
};
function processClean() {
return del(`${buildFolder}**`, { force: true });
}
function processSass() {
return gulp
.src(src.scss)
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest(dest.css))
.pipe(browserSync.stream())
}
function processInline() {
return gulp
.src('./*.html')
.pipe(inlineCss({
removeHtmlSelectors: true
}))
.pipe(gulp.dest('build/'))
}
function processWatch() {
gulp.watch(['./src/scss/**/*.scss'], processSass);
gulp.watch(srcFolder).on('change', browserSync.reload);
gulp.watch(distFolder).on('change', browserSync.reload);
}
const buildStyles = gulp.series(processSass, processInline);
const build = gulp.parallel(processClean, buildStyles);
gulp.task('clean', processClean);
gulp.task('styles', buildStyles);
gulp.task('sass', processSass);
gulp.task('inline', processInline);
gulp.task('build', build);
gulp.task('watch', processWatch);
But I am now wanting to create lots of template files, store them in a subfolder and have gulp spit out each file into the destination folder. if I have index.html, test1.html etc in the root it works fine.
I tried modifying this:
function processInline() { return gulp.src('./*.html')
To this:
function processInline() { return gulp.src(src.templates) // should equate to 'src/templates/**/*html'
Now I'm seeing this error in the console:
ENOENT: no such file or directory, open 'C:\Users\myuser\pathToApp\emailTemplates\src\templates\build\css\style.css'
In the head of index.html in the root is this:
<link rel="stylesheet" href="build/css/style.css">
I actually don't really care about the css file as the final output should be inline (for email templates). But I cannot get my head around why this is happening.
Does gulp create the css file and then read the class names from there? EDIT, Ah I guess it must because it has to convert the sass to readable css first before stripping out the class names and injecting the inline styles.
Years ago I worked with grunt a fair bit, and webpack, but haven't done much with gulp.
I hope it is obvious, but if you need more information just let me know.
Folder Structure
Components
------component1
-partials
- js
- html
- scss
- component1.css
- component1.js
------component2
-partials
- js
- html
- scss
- component2.css
- component2.js
Functionality is all my js, html and scss file convert into one css and js fine but inside into the component folder.
If I create a new component I don't want every time to add them separately into gulp It will automatically add through gulp. How can I write my gulp to achieve this type of functionality ?
Help will be really appreaticed...!!!
You can use this code that I created for your case:
Project structure:
folder structure tested
gulpfile.js
/**
* Created by Anderson on 22/04/2016.
*/
'use strict';
var gulp = require('gulp');
var data = require('gulp-data');
var concat = require('gulp-concat');
var sass = require('gulp-sass');
var gcallback = require('gulp-callback');
var rename = require('gulp-rename');
var del = require('del');
var path = require('path');
var fs = require('fs');
gulp.task('main',function(){
//scan componens folder all files and folders
gulp.src("./components/**")
.pipe(data(function(file,cb){
var filepath = file.path;
var stats = fs.lstatSync(filepath);
var base = file.base;
var fpath = filepath.replace(file.base,"");
//console.log(fpath);
var array = fpath.split("\\");
var basename = path.basename(fpath);
var componentName = array[0];
//destiny
var dest = base + fpath.replace(basename,"");
dest = dest.replace("partials\\","");
//process the scss
if(stats.isDirectory() && basename == "scss"){
//console.log(array,componentName,basename);
//console.log(file.path);
var scssScan = base + fpath+"\\*.scss";
console.log("scan",scssScan );
console.log("dest",dest);
//scan dir for scss
gulp.src(scssScan)
//concat all scss in a temporary file
.pipe(concat(componentName+".scss"))
.pipe(gulp.dest(dest))
.pipe(gcallback(function(){
//scan to process the scss
var componentPath = base + componentName;
var componentScssScan = componentPath + "\\*.scss";
//console.log(componentPath,componentScssScan);
//console.log(componentPath + "\\" + componentName+".scss");
//scan the component dir for scss
gulp.src(componentScssScan)
//process the sass
.pipe(sass())
.pipe(gulp.dest(dest));
//delete the temporary scss
//.pipe(del(componentPath + "\\" + componentName+".scss"));
}));
}
//process the js
if(stats.isDirectory() && basename == "js"){
//console.log(array,componentName,basename);
//console.log(file.path);
var scssScan = base + fpath+"\\*.js";
console.log("scan",scssScan );
console.log("dest",dest);
//scan dir for js
gulp.src(scssScan)
//concat all js in a temporary file
.pipe(concat(componentName+".js"))
.pipe(gulp.dest(dest));
}
cb(undefined,undefined);
}));
});
I think what you need to do is add watcher for the css and js files and run specific task based on the changes, here's some example:
var gulp = require('gulp'),
less = require('gulp-less'),
cleancss = require('gulp-clean-css'),
server = require('gulp-server-livereload'),
rename = require('gulp-rename');
gulp.task('server', ['watch', 'webserver']);
gulp.task('styles', function() {
return gulp.src('public/assets/less/app.less')
.pipe(less())
.pipe(rename('app.css'))
.pipe(cleancss())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('public/dist/css'))
});
// Add watcher for the changes in files
gulp.task('watch', function() {
gulp.watch('public/assets/less/*.less', ['styles']);
})
gulp.task('webserver', function() {
gulp.src('public')
.pipe(server({
livereload: true,
port: 8080,
open: true,
}))
});
And you can use Livereload Chrome Extension to enable browser auto-refresh whenever there's a changes in your code as well.
This is my watch.js as written by yeoman gulp-angular generator
'use strict';
var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync');
function isOnlyChange(event) {
return event.type === 'changed';
}
gulp.task('watch', ['scripts:watch', 'markups', 'inject'], function () {
gulp.watch([path.join(conf.paths.src, '/*.html'), 'bower.json'], ['inject-reload']);
gulp.watch([
path.join(conf.paths.src, '/app/**/*.css'),
path.join(conf.paths.src, '/app/**/*.scss')
], function(event) {
if(isOnlyChange(event)) {
gulp.start('styles-reload');
} else {
gulp.start('inject-reload');
}
});
gulp.watch(path.join(conf.paths.src, '/app/**/*.jade'), ['markups']);
gulp.watch(path.join(conf.paths.src, '/app/**/*.html'), function(event) {
browserSync.reload(event.path);
});
});
It works fine for already created files, but for some reason gulp.watch doesn't see the new ones (in particular .jade, but maybe also other types), eg.
myApp/src/components/header/headerView.jade
The only solution for me to run task as markup is to stop and restart gulp serve. Then gulp will recognizes changes in my .jade files
I have this gulpfile:
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
I want to know what file trigger the watcher and his absolute path.
For example: if my project is placed in /myCode and I change the file src/main.js, I want to see /myCode/src/main.js inside minifyJS task. Is there a way to do it?
Thank you for your time.
You can do it by using gulp-ng-annotate and gulp-changed:
var gulp = require('gulp');
var changed = require('gulp-changed');
var rename = require('gulp-rename');
var ngAnnotate = require('gulp-ng-annotate'); // just as an example
var SRC = 'src/*.js';
var DEST = 'src/';
//Function to get the path from the file name
function createPath(file) {
var stringArray = file.split('/');
var path = '';
var name = stringArray[1].split('.');
stringArray = name[0].split(/(?=[A-Z])/);
if (stringArray.length>1) {stringArray.pop()};
return {folder: stringArray[0], name: name[0]}
}
gulp.task('default', function () {
return gulp.src(SRC)
.pipe(changed(DEST))
// ngAnnotate will only get the files that
// changed since the last time it was run
.pipe(ngAnnotate())
.pipe(rename(function (path) {
var createdPath = createPath(path);
path.dirname = createdPath.folder;
path.basename: createdPath.name,
path.prefix: "",
path.suffix: "",
path.extname: ".min.js"
}))
.pipe(gulp.dest(DEST));
});
Result:
Use gulp-changed npm package.
$ npm install --save-dev gulp-changed
Try the below in gulp file, (I haven't tried)
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
changed = require('gulp-changed');
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(changed('min'))
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
see the documentation of this package https://www.npmjs.com/package/gulp-changed
Based on your comment to Julien's answer this should be fairly close to what you want, or at least get you going in the right direction:
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
cache = require('gulp-cached'),
rename = require('gulp-rename'),
path = require('path');
function fileName(file) {
return file.dirname + path.sep + file.basename + file.extname;
}
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(cache('minifyJS'))
.pipe(rename(function(file) {
var nameOfChangedFile = fileName(file);
if (nameOfChangedFile == './main.js') {
file.basename = 'main.min'
}
if (nameOfChangedFile == './userView.js') {
file.basename = 'user/userView.min'
}
console.log(nameOfChangedFile + ' -> ' + fileName(file));
}))
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
This uses gulp-cached to keep an in-memory cache of all the files in your src/ folder that have passed through the stream. Only files that have changed since the last invocation of minifyJS are passed down to the gulp-rename plugin.
The gulp-rename plugin itself is then used to alter the destination path of the changed files.
Note: the cache is empty on first run, since no files have passed through the gulp-cached plugin yet. This means that the first time you change a file all files in src/ will be written to the destination folder. On subsequent changes only the changed files will be written.
So I have my Gulp file as below.
The 'watch' block seems to work absolutely fine, and do what is expected. Nodemon works in the way that it detects file changes and refreshes the server, that works too.
But I can't for the life of me get Nodemon to call the 'watch' method when a file changes.
On line 81, the .on('start' is called succesfully from nodemon, but the code inside the 'watch' method is never executed.
var gulp = require('gulp');
var gutil = require('gulp-util'); // For logging stats and warnings
var jshint = require('gulp-jshint'); // For checking JavaScript for warnings
var concat = require('gulp-concat'); // For joining together multiple files
var uglify = require('gulp-uglify'); // For minimising files
var coffee = require('gulp-coffee'); // For compiling coffee script into js
var cofLint = require('gulp-coffeelint');// For checking coffee script for errors
var less = require('gulp-less'); // For compiling Less into CSS
var cssLint = require('gulp-csslint'); // For checking the awesomeness of css
var minCss = require('gulp-minify-css');// For minifying css
var uncss = require('gulp-uncss'); // For deleting unused CSS rules
var footer = require('gulp-footer'); // For adding footer text into files
var nodemon = require('gulp-nodemon'); // For the super cool instant refreshing server
var bSync = require('browser-sync'); // Syncs the place between multiple browsers for dev
var es = require('event-stream'); // For working with streams rather than temp dirs
var sourcePath = "sources";
var destPath = "public";
var jsFileName = "all.min.js";
var cssFileName = "all.min.css";
var footerText = "";
/* JavaScript Tasks */
gulp.task('scripts', function(){
var jsSrcPath = sourcePath + '/javascript/**/*';
var jsResPath = destPath + '/javascript';
var jsFromCs = gulp.src(jsSrcPath+'.coffee')// Get all coffee script
.pipe(cofLint()) // Check CS for errors or warnings
.pipe(cofLint.reporter()) // Output the error results
.pipe(coffee()); // Convert coffee to vanilla js
var jsFromPlain = gulp.src(jsSrcPath+'.js');// get all vanilla JavaScript
return es.merge(jsFromCs, jsFromPlain) // Both js from cs and vanilla js
.pipe(jshint()) // Check js errors or warnings
.pipe(jshint.reporter('jshint-stylish')) // Print js errors or warnings
.pipe(concat(jsFileName,{newLine: ';'})) // Concatenate all files together
.pipe(uglify()) // Minify JavaScript
.pipe(footer(footerText)) // Add footer to script
.pipe(gulp.dest(jsResPath)); // Save to destination
});
/* CSS Tasks */
gulp.task('styles', function(){
var cssSrcPath = sourcePath + '/styles/**/*';
var cssResPath = destPath + '/stylesheet';
var cssFromLess = gulp.src(cssSrcPath+'.less') // Get all Less code
.pipe(less()); // Convert Less to CSS
var cssFromVanilla = gulp.src(cssSrcPath+'.css');// Get all CSS
return es.merge(cssFromLess, cssFromVanilla) // Combine both CSS
.pipe(cssLint()) // Check CSS for errors or warnings
.pipe(cssLint.reporter()) // And output the results
.pipe(concat(cssFileName)) // Concatenate all files together
.pipe(minCss({compatibility: 'ie8'})) // Minify the CSS
.pipe(gulp.dest(cssResPath)); // Save to destination
});
/* Configure files to watch for changes */
gulp.task('watch', function() {
gulp.watch(sourcePath+'/**/*.{js,coffee}', ['scripts']);
gulp.watch(sourcePath+'/**/*.{css,less}', ['styles']);
});
/* Start Nodemon */
gulp.task('demon', function () {
nodemon({
script: './bin/www',
ext: 'js coffee css less html',
env: { 'NODE_ENV': 'development'}
})
.on('start', ['watch'])//TODO: ERROR: watch is never called, even though start is called
.on('change', ['watch'])
.on('restart', function () {
console.log('restarted!');
});
});
/* Default Task */
gulp.task('default', ['demon']);
Any suggestions why this may be happening?
Is there something wrong with my Gulp file?
(and yes, I know the code is a little over-commented, I work with apprentices and they like English better than code ;)
The problem is that Nodemon and browser-sync both need to be running. This code works:
gulp.task('nodemon', function (cb) {
var called = false;
return nodemon({
script: './bin/www',
watch: ['source/**/*']
})
.on('start', function onStart() {
if (!called) { cb(); }
called = true;
})
.on('restart', function onRestart() {
setTimeout(function reload() {
bSync.reload({
stream: false
});
}, 500);
});
});
gulp.task('browser-sync', ['nodemon', 'scripts', 'styles'], function () {
bSync.init({
files: ['sources/**/*.*'],
proxy: 'http://localhost:3000',
port: 4000,
browser: ['google chrome']
});
gulp.watch(sourcePath+'/**/*.{js,coffee}', ['scripts']);
gulp.watch(sourcePath+'/**/*.{css,less}', ['styles']);
gulp.watch("sources/**/*").on('change', bSync.reload);
gulp.watch("views/**/*.jade").on('change', bSync.reload);
});
/* Default Task */
gulp.task('default', ['clean', 'browser-sync']);