gulp.js: Watch all folders - gulp

Ich habe gulp.js so konfiguriert, dass die Ordnerstruktur im src Order auch im dist Ordner erhalten bleibt. Alle Dateien werden also in den selben Ordner (im dist-Ordner) ausgegeben.
.
+-- src
| +-- header
| | +-- index.html
| | +-- style.scss
| +-- footer
| +-- index.html
| +-- style.scss
+-- dist
+-- header
| +-- index.html
| +-- style.css
+-- footer
+-- index.html
+-- style.css
I solved this by using a function to output the folder structure and then performing a specific task for each folder:
/* Get Folders */
function get_folders(dir) {
var folders = fs.readdirSync(dir);
var structure = [];
folders.forEach(function(folder) {
if(fs.statSync(path.join(dir, folder)).isDirectory()) {
var isParent = false;
fs.readdirSync(path.join(dir, folder)).forEach(function(subfolder) {
if(fs.statSync(path.join(dir, folder, subfolder)).isDirectory()) {
isParent = true;
structure.push(folder + "/" + subfolder);
}
});
if(!isParent) {
structure.push(path.join(folder));
}
}
});
return structure;
}
/* Generate Styles */
async function generate_styles() {
var folders = get_folders(theme.compontents.root);
return folders.map(function(folder) {
return gulp.src([...theme.static.styles, ...theme.vendor.styles, path.join(dir.src, "components", folder, '/**/*.scss')])
.pipe(sourcemaps.init())
.pipe(concat('styles.scss'))
.pipe(sass.sync({
allowEmpty: true,
outputStyle: theme.minify ? 'compressed' : 'expanded',
includePaths: ['./node_modules', './static/scss']
}))
.pipe(autoprefixer())
.pipe(sourcemaps.write('/'))
.pipe(gulp.dest(path.join(dir.dist, folder)))
});
}
/* Watch files */
function watcher() {
gulp.watch(theme.compontents.styles, generate_styles);
}
/* Init */
exports.default = gulp.series(
gulp.parallel(generate_styles),
watcher
);
The problem now is that all data, from all folders, is regenerated as soon as I change just one file. So if I make changes to the style.scss in the header folder, then the style.scss in the footer folder is also recompiled.
This is because each time a change is made, the get_folders function is called and the appropriate compilation is applied to each file. So I only need to apply this to the folder where the data has changed.

Related

Gulp Sass v4 not creating css file

I'm using gulp version 4 in my project and I want to compile my scss file to css file. But gulp not creating any css file.
My gulpfile.js
// Initialize modules
// Importing specific gulp API functions lets us write them below as series() instead of gulp.series()
const { src, dest, watch, series, parallel } = require('gulp');
// Importing all the Gulp-related packages we want to use
const sourcemaps = require('gulp-sourcemaps');
const sass = require('gulp-sass');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const browserSync = require('browser-sync').create();
var replace = require('gulp-replace');
// File paths
const files = {
scssPath: './assets/scss/**/*.scss',
jsPath: './assets/js/**/*.js'
}
// Sass task: compiles the style.scss file into style.css
function scssTask(cb){
return src(files.scssPath)
.pipe(sourcemaps.init()) // initialize sourcemaps first
.pipe(sass({ outputStyle: "expanded" }).on('error',sass.logError)) // compile SCSS to CSS
.pipe(postcss([ autoprefixer(), cssnano() ])) // PostCSS plugins
.pipe(sourcemaps.write('.')) // write sourcemaps file in current directory
.pipe(dest('./dist'))
.pipe(browserSync.stream());
// put final CSS in dist folder
}
// JS task: concatenates and uglifies JS files to script.js
function jsTask(){
return src([
files.jsPath
//,'!' + 'includes/js/jquery.min.js', // to exclude any specific files
])
.pipe(concat('all.js'))
.pipe(uglify())
.pipe(dest('./dist')
);
}
// Cachebust
var cbString = new Date().getTime();
function cacheBustTask(){
return src(['index.html'])
.pipe(replace(/cb=\d+/g, 'cb=' + cbString))
.pipe(dest('.'));
}
// Watch task: watch SCSS and JS files for changes
// If any change, run scss and js tasks simultaneously
function watchTask(){
watch([files.scssPath, files.jsPath],
parallel(scssTask, jsTask));
}
// Export the default Gulp task so it can be run
// Runs the scss and js tasks simultaneously
// then runs cacheBust, then watch task
exports.default = series(
parallel(scssTask, jsTask),
cacheBustTask,
watchTask
);
My Project Hiererchy
myProject
|_ assets
| |_ css
| |_ scss
| |_ js
|_ index.html
|_ node_modules
|_ gulpfile.js
|_ package.json
and when running Gulp
[14:27:33] Using gulpfile F:\blog-project\infonites\gulpfile.js
[14:27:33] Starting 'default'...
[14:27:33] Starting 'scssTask'...
[14:27:33] Starting 'jsTask'...
[14:27:33] Finished 'scssTask' after 64 ms
[14:27:37] Finished 'jsTask' after 4.36 s
[14:27:37] Starting 'cacheBustTask'...
[14:27:37] Finished 'cacheBustTask' after 7.71 ms
[14:27:37] Starting 'watchTask'...
And after running gulp my project hierarchy
myProject
|_ assets
| |_ css
| |_ scss
| |_ js
|_ index.html
|_ dist
| |_ all.js
|_ node_modules
|_ gulpfile.js
|_ package.json
This is my final output after running gulp task. I don't understand why gulp running js task but not css task.

Gulp - compile sass by folder, and modify parent directories

I'm new on gulpfile and i can't figure out how can I iterate through multiple folders using a single task
My src folder structure
folder1
assets
style.scss
folder2
assets
style.scss
folder3
subfolder1
assets
style.scss
subfolder2
assets
style.scss
Into dist folder i want something like this ( without 'assets' folder )
folder1
style.css
folder2
style.css
folder3
subfolder1
style.css
subfolder2
style.css
I have a few tasks that work properly but I want them to be a single task
How can I achieve that?
var pack1 = ['folder1', 'folder2'];
var pack2 = ['subfolder1', 'subfolder2'];
gulp.task('scss_pack1', function () {
pack1.map(function (element) {
return gulp.src('src/'+element+ '/assets/*.scss')
.pipe(sass())
.pipe(gulp.dest('/dist/'+element+'/));
})
gulp.task('scss_pack2', function () {
pack2.map(function (element) {
return gulp.src('src/folder3/'+element+ '/assets/*.scss')
.pipe(sass())
.pipe(gulp.dest('/dist/folder3/'+element+'/));
})
Try this:
const gulp = require("gulp");
const sass = require("gulp-sass");
const flatten = require('gulp-flatten');
gulp.task('default', function () {
return gulp.src("src/**/assets/style.scss")
.pipe(sass())
// flatten subPath(0, -1) will strip off the last folder, i.e., 'assets'
// extracts the first element through the second-to-last element in the sequence.
// so subfolder1/assets -> subfolder1 (the second-to-last element is subfolder1)
// and assets/ -> nothing (since there is no second-to-last element!!)
.pipe(flatten({ subPath: [0, -1] }))
.pipe(gulp.dest("dist/"));
});
gulp-flatten

Gulp - Watch multiple folders and output to relative dist folder

I want to use gulp to compile SASS for my custom Wordpress plugins.
All plugin folder share same folder structure:
wp-content/plugins/pluginname
assets
dist -
src - scss
GULP TASK
gulp.task('plugin-css', () => {
// Main SASS Style Sheet
const pluginSass = gulp.src(`wp-content/plugins/**/assets/src/*.scss`)
.pipe(plumber(plumberErrorHandler))
.pipe(sass());
// Merge the two streams and concatenate their contents into a single file
return merge(pluginSass)
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(gulp.dest(function(file) {
return file.base;
}));
});
Currently my compiled css file is being output into the same folder as the src sass. How can I output my compiled sass into 'dist' folder?
It is not clear to me what you are trying to do with the merges (so NOTE I simplified those out) but here is something that should help you get to putting your result into a dist folder where you want it to be:
var path = require('path');
var rename = require('gulp-rename');
gulp.task('default', function () {
const pluginSass = gulp.src("wp-content/plugins/**/assets/src/*.scss")
.pipe(sass())
// return merge(pluginSass)
.pipe(rename(function (file) {
var temp = path.dirname(file.dirname);
console.log('temp = ' + temp);
file.dirname = path.join(temp, "dist");
console.log("file.dirname = " + file.dirname);
}))
.pipe(cssmin())
// .pipe(autoprefixer())
.pipe(gulp.dest("wp-content/plugins"));
});
gulp-rename is useful for these situations and always seems to be easier to use that gulp.dest(function... path manipulation).
Pass the dist folder to the gulp.dest function.
const path = require('path')
return merge(pluginSass)
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(gulp.dest(function (file) {
return path.join(file.base, './dist') // ← Put your folder path here
}));
See docs here: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpdestpath-options

Gulp doesn't work when multiple tasks are run

I'm trying to grap my head around gulp. I managed to write gulpfile.js for my basic page scaffolding, but i've problems with running serveral task in order.
I'm trying to generate css/main.css file from scss files, copy it to dist/css/ and then inject my js and css files into index.html (with gulp-inject).
(function (r) {
var gulp = r('gulp');
var del = r('del');
var wiredep = r('wiredep');
var $ = r('gulp-load-plugins')();
// var runSequence = require('run-sequence');
var config = {
css_files: './css/*.css',
sass_files: './scss/*.scss',
main_sass: './scss/main.scss',
main_css: './css/main.css',
css_dir: './css/',
js_files: './js/*.js',
main_js: './js/main.js',
index: [
'./index.html',
'**/index.html',
'!node_modules/**/*.*',
'!bower_components/**/*.*',
],
dist: './dist/',
};
function clean(cb) {
del.sync([
config.css_files,
config.dist + config.css_files,
config.dist + config.js_files,
config.dist + config.index[0],
config.dist + config.index[1],
config.dist + '**/*.map',
]);
cb();
}
gulp.task('clean', function (cb) {
clean(cb);
});
gulp.task('scss', function (cb) {
gulp
.src(config.sass_files)
.pipe($.plumber())
.pipe($.sass())
.pipe(gulp.dest(config.css_dir));
cb();
});
gulp.task('js', function (cb) {
gulp
.src(config.js_files)
.pipe($.concat('main.js'))
.pipe($.sourcemaps.init())
.pipe($.uglify())
.pipe($.sourcemaps.write('./'))
.pipe(gulp.dest(config.dist + 'js/'));
cb();
});
gulp.task('css', ['scss'], function (cb) {
gulp
.src(config.css_files)
.pipe($.sourcemaps.init())
.pipe($.uglifycss())
.pipe($.sourcemaps.write('./'))
.pipe(gulp.dest(config.dist + 'css/'));
cb();
});
function wd(cb) {
wiredep({ ignorePath: '../..', src: config.main_sass, directory: './bower_components' });
wiredep({ ignorePath: '../..', src: config.index[0], directory: './bower_components' });
cb();
}
gulp.task('wd', function (cb) {
wd(cb);
});
gulp.task('inject-dev', ['wd'], function (cb) {
var src = ['!dist/**/*.*'].concat(config.index);
gulp
.src(src)
.pipe($.inject(gulp.src([config.css_files, config.js_files])))
.pipe(gulp.dest('./'));
cb();
});
gulp.task('inject-dist', ['copy-index'], function (cb) {
var src = gulp.src([config.dist + 'css/**/*.*', config.dist + 'js/**/*.*']);
var target = gulp.src(config.dist + '**/index.html');
target.pipe($.inject(src, { relative: true }))
.pipe(gulp.dest(config.dist));
cb();
});
gulp.task('watch', function (cb) {
gulp.watch(config.sass_files, ['scss']);
cb();
});
gulp.task('copy-index', function (cb) {
gulp
.src(config.index, { base: './' })
.pipe(gulp.dest(config.dist));
cb();
});
gulp.task('build-dist', ['clean', 'css', 'js', 'inject-dist']);
})(require);
ATM result of build-dist is generated js/main.js file, copied index.html and about/index.html, generated main.css in dev dir, but not in dist. Files are not injected in dist/index.html aswell.
λ szuja html-scaffold → λ git master* → tree -L 3 -I 'bower_components|node_modules'
.
├── about
│   └── index.html
├── bower.json
├── css
│   └── main.css
├── dist
│   ├── about
│   │   └── index.html
│   ├── index.html
│   └── js
│   ├── main.js
│   └── main.js.map
├── gulpfile.js
├── index.html
├── js
│   ├── main2.js
│   └── main.js
├── LICENSE
├── package.json
├── README.md
└── scss
└── main.scss
Edit:
Looks like gulp doesn't care about waiting for tasks to finish ignoring callback functions:
[16:15:47] Using gulpfile ~/workdir/html-scaffold/gulpfile.js
[16:15:47] Starting 'clean'...
[16:15:47] Finished 'clean' after 15 ms
[16:15:47] Starting 'scss'...
[16:15:47] Finished 'scss' after 75 ms
[16:15:47] Starting 'css'...
[16:15:47] Finished 'css' after 44 ms
[16:15:47] Starting 'js'...
[16:15:47] Finished 'js' after 74 ms
[16:15:47] Starting 'copy-index'...
[16:15:47] Finished 'copy-index' after 4.27 ms
[16:15:47] Starting 'inject-dist'...
[16:15:47] Finished 'inject-dist' after 13 ms
[16:15:47] Starting 'build-dist'...
[16:15:47] Finished 'build-dist' after 9.01 μs
[16:15:47] gulp-debug: 0 items
[16:15:47] gulp-debug: 0 items
[16:15:47] gulp-debug: scss/main.css
[16:15:47] gulp-debug: 1 item
Works with run-sequence and returning a promise instead of waiting for callback function. I was trying this method before, but somehow managed to pass parameters as an array, so they were running in parallel..
(function (r) {
var gulp = r('gulp');
var del = r('del');
var wiredep = r('wiredep');
var $ = r('gulp-load-plugins')();
var runSequence = require('run-sequence');
var config = {
css_files: './css/*.css',
sass_files: './scss/*.scss',
main_sass: './scss/main.scss',
main_css: './css/main.css',
css_dir: './css/',
js_files: './js/*.js',
main_js: './js/main.js',
index: [
'./index.html',
'**/index.html',
'!node_modules/**/*.*',
'!bower_components/**/*.*',
],
dist: './dist/',
};
function clean(cb) {
del.sync([
config.css_files,
config.dist + config.css_files,
config.dist + config.js_files,
config.dist + config.index[0],
config.dist + config.index[1],
config.dist + '**/*.map',
]);
cb();
}
gulp.task('clean', function (cb) {
clean(cb);
});
gulp.task('scss', function () {
return gulp
.src(config.sass_files)
.pipe($.plumber())
.pipe($.sass())
.pipe($.debug())
.pipe(gulp.dest(config.css_dir));
});
gulp.task('js', function () {
return gulp
.src(config.js_files)
.pipe($.concat('main.js'))
.pipe($.sourcemaps.init())
.pipe($.uglify())
.pipe($.sourcemaps.write('./'))
.pipe(gulp.dest(config.dist + 'js/'));
});
gulp.task('css', ['scss'], function () {
return gulp
.src(config.css_files)
.pipe($.sourcemaps.init())
.pipe($.uglifycss())
.pipe($.sourcemaps.write('./'))
.pipe($.debug())
.pipe(gulp.dest(config.dist + 'css/'));
});
function wd(cb) {
wiredep({ ignorePath: '../..', src: config.main_sass, directory: './bower_components' });
wiredep({ ignorePath: '../..', src: config.index[0], directory: './bower_components' });
cb();
}
gulp.task('wd', function (cb) {
wd(cb);
});
gulp.task('inject-dev', ['wd'], function () {
var src = ['!dist/**/*.*'].concat(config.index);
return gulp
.src(src)
.pipe($.inject(gulp.src([config.css_files, config.js_files])))
.pipe($.debug())
.pipe(gulp.dest('./'));
});
gulp.task('inject-dist', ['copy-index'], function () {
var src = gulp.src([config.dist + 'css/**/*.*', config.dist + 'js/**/*.*']);
var target = gulp.src(config.dist + '**/index.html');
return target.pipe($.inject(src, { relative: true }))
.pipe($.debug())
.pipe(gulp.dest(config.dist));
});
gulp.task('watch', function (cb) {
gulp.watch(config.sass_files, ['scss']);
cb();
});
gulp.task('copy-index', function () {
return gulp
.src(config.index, { base: './' })
.pipe(gulp.dest(config.dist));
});
gulp.task('build-dist', function (cb) {
runSequence('clean', 'js', 'css', 'inject-dist', cb);
});
})(require);

GulpJS copy folders and files from folder "foo" to folder "bar" and retain folder structure

I've got a folder "foo" and folder "bar", and I want to copy and run specific tasks on a specific files files.
Problem: I can copy files, run tasks on them and retain folder structure, but when I move files to folder "bar" it creates a folder "foo" inside folder "bar" and stores all copied files inside it.
Tried: Tried to change base: '.' to base: '../' but that just makes it compile everything to parent folder of bar.
Folder structure:
.
├── foo
│ ├── app.js
│ ├── models
│ ├── public
│ │ ├── images
│ │ └── js
│ ├── routes
│ └── scss
├── bar
│ └── ...
└── gulpfile.js
Gulpjs.js File:
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var sass = require('gulp-ruby-sass');
var cssmin = require('gulp-minify-css');
var rename = require('gulp-rename');
var htmlmin = require('gulp-htmlmin');
var paths = {
'ssjs' : ['foo/app.js', 'foo/routes/*.js', 'foo/models/*.js'],
'csjs' : ['foo/public/js/*.js'],
'sass' : ['foo/scss/*.scss', 'foo/scss/modules/*.scss'],
'html' : ['foo/public/*.html'],
'build' : 'bar',
'public': 'public'
};
gulp.task('ssjs', function() {
return gulp.src(paths.ssjs, {'base': '.'})
.pipe(uglify({'preserveComments': 'some'}))
.pipe(gulp.dest(paths.build));
});
gulp.task('csjs', function() {
return gulp.src(paths.csjs, {'base': '.'})
.pipe(uglify({'preserveComments': 'some'}))
.pipe(gulp.dest(paths.build));
});
gulp.task('sass', function() {
return gulp.src(paths.sass, {'base': '.'})
.pipe(sass())
.pipe(cssmin())
.pipe(gulp.dest(paths.build));
});
gulp.task('html', function() {
return gulp.src(paths.html, {'base': '.'})
.pipe(htmlmin({'collapseWhitespace': true}))
.pipe(gulp.dest(paths.build));
});
gulp.task('watch', function() {
gulp.watch(paths.ssjs, ['ssjs']);
gulp.watch(paths.csjs, ['csjs']);
gulp.watch(paths.scss, ['sass']);
});
gulp.task('default', [ 'ssjs', 'csjs', 'sass', 'html', 'watch' ]);
Solution: change 'base': '.' to 'base': 'foo'