Reputation: 6383
We have a combination of CSS and SCSS files. This is because we write our own styles in SCSS and some style libraries also provide a SCSS file, but we also have CSS only files where either no SCSS file is provided by the library vendor (e.g. they only provide a CSS file or a LESS file)
Below is our gulpfile.js task for SCSS files:
gulp.src([
'bower_components/simple/simple.css',
//... more CSS files
'src/scss/app.scss'
],
{base: '.'})
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/css'));
Anyway, this seems to be giving us strange behaviour such as creating a "bower_components" directory in the dist/ directory. How can we compile CSS files along with SCSS files?
Upvotes: 0
Views: 1284
Reputation: 2418
Here are a couple of things you could try
1. Using gulp passthrough
This feature is probably the easiest but the caveat is that it requires gulp version 4
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var bower_files = require('main-bower-files');
var sourcemaps = require('gulp-sourcemaps');
var filter = require('gulp-filter');
var merge = require('merge2');
gulp.task('styles', function () {
var glob = bower_files('**/*.scss') // select the sass bower files
glob.push('app/**/*.scss') // select your projects sass files
return gulp.src(glob)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(gulp.src(bower_files('**/*.css'), {passthrough: true} )) // add bower css files to stream
.pipe(concat('main.css'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
The workflow here is that you select all your initial sass files which will be from the bower components directory and also your projects directory. Then pass them to the sass compiler. Afterwards we can select all the bower downloaded css files using another gulp.src
method and by passing the passthrough option to the method we add these files to our already sass compiled files and perform other necessary operations.
2. Using merge streams
This option doesn't require gulp version 4 and is probably a better option as it allows you to perform multiple operations on the different streams.
gulp.task('styles', function () {
var scss_stream = bower_files('**/*.scss')
scss_stream.push('app/**/*.scss')
scss_stream = gulp.src(scss_stream)
.pipe(sass().on('error', sass.logError));
var css_stream = gulp.src(bower_files('**/*.css'))
return merge(scss_stream, css_stream)
.pipe(concat('main-one.css'))
.pipe(gulp.dest('dist'));
})
By selecting different type of files separately and making them their own stream, we can perform several operations on the different streams. Here in the first stream, we selected the projects and bowers scss
files and passed them to the gulp sass plugin. In the second stream we selected all the css
files. We then merged both streams together and performed operations that aren't unique for the two (concatenation
and writing to destination
)
I strongly recommend using the main-bower-files plugin to select files from bower_components
Also be careful if the order of files being selected is important. You may have to resort to actually selecting the files in the right order. You could use the stream queue plugin along with the gulp-filter plugin.
I hope this helps
Upvotes: 0
Reputation: 1160
I ran into this same problem basically gulp doesn't like your diverse folder paths in src and you would have to use 2 different tasks to processes this as you wanted.
The only simple way I found to fix this is to use this utility: npm-gulp-rename
With a line like this:
var rename = require("gulp-rename");
.pipe(rename(function (path) { return path.dirname = "./"; }))
What this will do is remove the extra folder information in the stream after it has the data so that when it outputs the files the extra folder information is removed.
My code in your example:
gulp.src([
'bower_components/simple/simple.css',
//... more CSS files
'src/scss/app.scss'
],
{base: '.'})
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write())
.pipe(rename(function (path) { return path.dirname = "./"; }))
.pipe(gulp.dest('dist/css'));
UPDATE (Based on your comment):
Personally I would go about this in a different way:
Off the top of my head it would work something like this:
gulp.task("copy", function () {
return gulp.src([
'bower_components/simple1/simple1.css'
'bower_components/simple2/simple2.css'
], {base: '.'})
.pipe(rename(function (path) { return path.dirname = './'; }))
.pipe(gulp.dest('vendor')
)};
gulp.task("scss", ["copy"], function () {
return gulp.src([ 'src/scss/app.scss' ], {base: '.'})
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/css')
)};
Now to the IMPORTANT part which you can do without my personal recommendations.
You will need to add to your app.scss the other CSS files using an @import which directly supports CSS files:
@import "../../vendor/simple1.css";
You could also use the @import directly from the bower_components folder thereby skipping my copy task:
@import "../../bower_components/simple1/simple1.css";
The second task will be the one you run which will create your CSS files all concatenated.
If you would like to not use @import in your app.scss then you can add another common gulp ad-in gulp-concat. If you would like me to expand upon how to use this just leave me a comment.
A few things to consider:
Upvotes: 0