I have the following folder structure:
theme
assets
build
css
style.css
src
theme
buttons.scss
style.scss
components
hero
hero.html
hero.scss
index.html
I'm trying to get everything to compile into style.css. This includes:
- Any changes that occur in any
.scssfile insrcthemefolder - Any changes in
style.scssshould compile thecssagain - Any changes to a components
scssfile (i.e.hero.scss) should compile thecssagain.
To achieve the above, I have the following gulpfile:
const base = '/',
assetsSRC = 'theme/assets/src/',
assetsDST = 'theme/assets/build/',
components = 'theme/components/';
const gulp = require('gulp'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps'),
fs = require('fs'),
path = require('path'),
merge = require('merge-stream'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
plumber = require('gulp-plumber'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
strip = require('gulp-strip-comments'),
fileinclude = require('gulp-file-include');
const componentCSS = components + '**/component.scss',
componentJS = components + '**/component.js',
globalCSS = assetsSRC + 'scss/style.scss';
configCSS = assetsSRC + 'scss/config/**.scss';
themeCSS = assetsSRC + 'scss/theme/**.scss';
globalJS = assetsSRC + 'js/*.js';
libJS = assetsSRC + 'js/lib/*.js';
gulp.task('fileinclude', function() {
gulp.src(['index.html'])
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('./'));
});
var sassOptions = {
errLogToConsole: true,
outputStyle: 'compressed'
};
function getFolders(dir) {
return fs.readdirSync(dir).filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
function css() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(components, folder);
return gulp.src(path.join(src, '/**/src/component.scss'))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(rename(function(file) {
file.dirname = path.dirname(file.dirname);
file.basename = file.basename;
return file;
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(src));
});
return merge(tasks);
}
function mainCSS() {
var dst = path.join(assetsDST + 'css/');
return gulp.src(globalCSS, { allowEmpty: true })
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
}
function javascript() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(components, folder);
return gulp.src(path.join(src, '/**/src/component.js'))
.pipe(plumber())
.pipe(uglify())
.pipe(rename(function(file) {
file.dirname = path.dirname(file.dirname);
file.basename = file.basename;
return file;
}))
.pipe(gulp.dest(src));
});
return merge(tasks);
}
function mainJS() {
var dst = path.join(assetsDST + 'js/dist');
return gulp.src([
globalJS
])
.pipe(plumber())
.pipe(concat('scripts-min.js'))
.pipe(strip())
.pipe(uglify())
.pipe(gulp.dest(dst));
}
function libraryJS() {
var dst = path.join(assetsDST + 'JS/lib');
return gulp.src(libJS).pipe(gulp.dest(dst));
}
function watch() {
gulp.watch([globalCSS,configCSS,themeCSS],mainCSS);
gulp.watch([globalJS],mainJS);
gulp.watch([componentCSS], css);
gulp.watch([componentJS], javascript);
}
exports.mainCSS = mainCSS;
exports.mainJS = mainJS;
exports.libraryJS = libraryJS;
exports.css = css;
exports.javascript = javascript;
exports.watch = watch;
const build = gulp.series(watch);
gulp.task('default', build);
However, when I run gulp css, I get the error:
Error: ENOENT: no such file or directory, scandir '/components/'
I have tried running npm rebuild node-sass, but no luck.
Edit
I have made some progress. However, with my below gulp setup, multiple css files are created in my css folder. For example:
build
css
style.css
hero.css
Whereas I need everything to compile into style.css.
const assetsSRC = 'assets/src/',
assetsDST = 'assets/build/',
components = 'components/';
const gulp = require('gulp'),
sass = require('gulp-sass')(require('sass')),
sourcemaps = require('gulp-sourcemaps'),
fs = require('fs'),
path = require('path'),
merge = require('merge-stream'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
plumber = require('gulp-plumber'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
strip = require('gulp-strip-comments');
const componentCSS = components + '**/*.scss',
componentJS = components + '**/*.js',
globalCSS = assetsSRC + 'scss/style.scss';
configCSS = assetsSRC + 'scss/config/**.scss';
themeCSS = assetsSRC + 'scss/theme/**.scss';
globalJS = assetsSRC + 'js/*.js';
libJS = assetsSRC + 'js/lib/*.js';
var sassOptions = {
errLogToConsole: true,
outputStyle: 'compressed'
};
function getFolders(dir) {
return fs.readdirSync(dir).filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
function css() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(assetsDST + 'css');
return gulp.src(path.join(src, '/**/*.scss'))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
});
return merge(tasks);
}
function mainCSS() {
var dst = path.join(assetsDST + 'css/');
return gulp.src(globalCSS, { allowEmpty: true })
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
}
function libraryJS() {
var dst = path.join(assetsDST + 'JS/lib');
return gulp.src(libJS).pipe(gulp.dest(dst));
}
function watch() {
gulp.watch([globalCSS,configCSS,themeCSS, componentCSS],mainCSS);
}
exports.mainCSS = mainCSS;
exports.mainJS = mainJS;
exports.libraryJS = libraryJS;
exports.css = css;
exports.javascript = javascript;
exports.watch = watch;
const build = gulp.series(watch);
gulp.task('default', build);
Edit 2
With my below code, everything that is named component.scss under the components folder merges into component.css.
Seems like I’m at the last hurdle, where instead of a new file called component.css being created when I run gulp css, I need everything to merge and append to style.css instead.
function css() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(assetsDST + 'css/');
return gulp.src(path.join(src, '**/component.scss'))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(rename(function(file) {
file.dirname = path.dirname(file.dirname);
file.basename = file.basename;
return file;
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
});
return merge(tasks);
}
Edit 3
Looking into it deeper, not all component.scss files are merged into component.css (for example, if there are 3 component.scss files, component.css only has the styles for one of them).