So I'm using gulp.js to manage and automate some tasks and I have a specific task styles that compiles my scss files into css and another to run a server using gulp-connect plugin that provides a livereload integration.
I also have a task watch to watch my changes and trigger the livereload.
gulp.task('watch', function () {
gulp.watch([ stylesPath + '/**/*.scss'], ['styles']);
gulp.watch([ scriptsPath + '/**/*.coffee'], ['scripts']);
gulp.watch([
'./app/**/*.html',
'./app/assets/scripts/**/*.js',
'./app/assets/styles/**/*.css'
], connect.reload);
});
This does not always works, actually it works less times than more. I really don't know why. I have the same logic with my .coffee files and it works perfectly for them.. but not to my css files.
Bellow are another related tasks.
gulp.task('connect', connect.server({
root: './app',
port: 1337,
livereload: true,
open: {
file: 'index.html',
browser: 'Google Chrome'
}
}));
gulp.task('styles', function () {
gulp.src('.sass-cache').pipe(clean({read:false}));
return gulp.src(stylesPath + '/**/*.scss')
.pipe(sass())
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest(stylesPath));
});
Actually it was an embarassing mistake of mine.
I included the stylesheet twice in my html file for mistake, for some reason this stopped livereload to work.
Frankly I don't see anything wrong with this.
It'd be best if you report this on Gulp github page. Might be some kind of bug. https://github.com/gulpjs/gulp
Related
I have a task like the following:
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')({ camelize: true });
gulp.task('styles-compile', function() {
return gulp.src(['less/site.less',
'less/special-*.less',
'less/editor-styles.less'])
.pipe(plugins.sourcemaps.init())
.pipe(plugins.less())
.pipe(plugins.autoprefixer('last 15 versions', 'ie 8', 'ios 6', 'android 4'))
.pipe(plugins.sourcemaps.write('.', {sourceRoot: '../less', includeContent: false}))
.pipe(gulp.dest('css'))
});
And I just seem to be unable to configure it to get sourcemaps working.
This is the closest I get to a working version - the only issue is that the generated sourcemap includes the file it is for in it's sources list - eg for site.css.map I get:
{"version":3,"sources":["site.css","../font/icon/css/fontawesome.css","site.less"...,"names":[],"mappings":"...","file":"site.css","sourceRoot":"../less"}
For one, I'm fairly sure that there is no need for the destination file itself (site.css) to appear in the sources list, but for another, it does not appear in the less directory - it is in the css directory. So when I load this up in dev tools, it is not found.
If I remove autoprefixer it all works fine, so I guess what I am seeing here is the fact that autoprefixer uses site.css for both source and destination file, so it considers there to be a mapping between them.
Based on some suggestions elsewhere, I tried adding calls to sourcemaps.write() then sourcemaps.init() in between less() and autoprefixer(), however this does not resolve the issue and, in fact adds an additional sourceMappingURL comment to the generated CSS.
Is there an accepted/better way to do this?
Based on comments from #seven-phases-max, I've changed the task up slightly:
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')({ camelize: true }),
autoprefixer = require('autoprefixer');
gulp.task('styles-compile', function() {
return gulp.src(['less/site.less',
'less/special-*.less',
'less/editor-styles.less'])
.pipe(plugins.sourcemaps.init())
.pipe(plugins.less())
.pipe(plugins.postcss([autoprefixer]))
.pipe(plugins.sourcemaps.write('.', {sourceRoot: '../less', includeContent: false}))
.pipe(gulp.dest('css'))
});
Unfortunately the output seems exactly the same, I'm still getting site.css as the first source.
Im trying to get my head around Gulp and i am using.
Yeoman´s webapp
Im trying to add some css-files to the project and hopefully get it to end up in the dist/styles-folder.
When adding scss-files to my app/styles-folder and build the project, the files end up in a .tmp-folder. I suppose this is the task that does it:
gulp.task('styles', () => {
return gulp.src('app/styles/*.scss')
.pipe($.plumber())
.pipe($.sourcemaps.init())
.pipe($.sass.sync({
outputStyle: 'expanded',
precision: 10,
includePaths: ['.']
}).on('error', $.sass.logError))
.pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
.pipe($.sourcemaps.write())
.pipe(gulp.dest('.tmp/styles'))
.pipe(reload({stream: true}));
});
The get compiled from scss to css which should be a good thing but how do I get them from the .tmp-folder tom my dist/index?
I tried: <link rel="stylesheet" href="./.tmp/styles/style.css">
It returned a 404 but even so, I cant imagine that this is the right way? Or swill my dist-folder have access to the .tmp-folder? Help appreciated.
Thanks
It seems you want to set the destination folder to dist, not tmp:
.pipe(gulp.dest('dist/styles'))
I'm trying to create a gulp task to compress and create a source map at the same time. The compression and source map creation works, but I can't seem how to figure out how to get the output names right when using the gulp-rename plugin.
To simplify: I have a source.js file in the /src folder and I want to create both the .min.js and .js.map file in the /dist folder.
Here's what I have:
gulp.task('scripts', function () {
// compressed
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('./', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('./dist'));
});
This works in that it creates the following in /dist:
jquery-resizable.min.js (all good - compressed, map ref and right name)
jquery-resizable.js.min.map (map is there, but name is bad - should be jquery-resizable.js.map)
I've tried a ton of variations but I can't figure out how to get the map and compression to build and get the correct file names.
I also tried renaming the files in a separate step, but due to the async nature of gulp, that doesn't work reliably - sometimes it works sometimes it doesn't so that doesn't seem like an option either.
What am I missing?
I'm not married to creating the sourcemaps in just this way, but what is the proper way to do this? All the examples I've seen seem to do what I do above, except they don't rename the output file to min.js which seems like an important part of the process.
I would suggest using gulp-filter to remove the .map files from the pipeline during the rename.
var jsFilter = require('gulp-filter')([ '*.js', ], { restore: true, });
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('./', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(jsFilter)
.pipe(rename({ suffix: '.min' }))
.pipe(jsFilter.restore)
.pipe(gulp.dest('./dist'));
That said, our workflow does the rename before the sourcemaps and it generates the maps correctly.
gulp.src(['src/*.js'])
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(rename({ suffix: '.min', }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./dist'));
#bdukes answer mostly solved my problem and led me to the right solution. I'm posting the actual solution that worked for me in the specific case I mentioned above which is based on his answer.
One of my issues was related to not being able to generate the raw sources files along with the compressed and map files. I was able to make it work with an extra step explicitly moving the files in a separate .pipe(gulp.dest('./dist')) operation:
gulp.task('scripts', function () {
// compress and source map
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('.', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(jsFilter)
.pipe(rename({ suffix: '.min' }))
.pipe(jsFilter.restore)
.pipe(gulp.dest('./'));
// also copy source files
gulp.src(['src/*.js'])
.pipe(gulp.dest('./dist'));
});
Moral of the story - don't overthink things - I was trying to get it all to work in one operation.
I'm new to using gulp and I think I have it setup correctly, but it does not seem to be doing what it should be doing.
My gulpfile.js has
gulp.task('compass', function() {
return gulp.src('sites/default/themes/lsl_theme/sass/**/*.scss')
.pipe(compass({
config_file: 'sites/default/themes/lsl_theme/config.rb',
css: 'css',
sass: 'scss'
}))
.pipe(gulp.dest('./sites/default/themes/lsl_theme/css'))
.pipe(notify({
message: 'Compass task complete.'
}))
.pipe(livereload());
});
with
gulp.task('scripts', function() {
return gulp.src([
'sites/default/themes/lsl_theme/js/**/*.js'
])
.pipe(plumber())
.pipe(concat('lsl.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
// .pipe(stripDebug())
.pipe(uglify('lsl.js'))
.pipe(rename('lsl.min.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
.pipe(sourcemaps.write())
.pipe(notify({
message: 'Scripts task complete.'
}))
.pipe(filesize())
.pipe(livereload());
});
and the watch function
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./sites/default/themes/lsl_theme/js/**/*.js', ['scripts']);
gulp.watch('./sites/default/themes/lsl_theme/sass/**/*.scss', ['compass']);
});
when I run gulp, the result is
[16:14:36] Starting 'compass'...
[16:14:36] Starting 'scripts'...
[16:14:36] Starting 'watch'...
[16:14:37] Finished 'watch' after 89 ms
and no changes are registered.
for file structure, my gulpfile.js is in the root directory and the sass, css, and js are all in root/sites/default/themes/lsl_theme with the sass folder containing the folder 'components' full of partials.
My assumption is that you are on windows? Correct me if I'm wrong.
There is this problem that gulp-notify tends to break the gulp.watch functions. Try commenting out
// .pipe(notify({
// message: 'Scripts task complete.'
// }))
and see if the problem still exists.
If that does fix the issue, a solution from this thread may be helpful.
You can use the gulp-if
plugin in combination with
the os node module
to determine if you are on Windows, then exclude gulp-notify, like
so:
var _if = require('gulp-if');
//...
// From https://stackoverflow.com/questions/8683895/variable-to-detect-operating-system-in-node-scripts
var isWindows = /^win/.test(require('os').platform());
//...
// use like so:
.pipe(_if(!isWindows, notify('Coffeescript compile successful')))
It turns out that a large part of my issue was just simply being a rookie with Gulp. When I removed 'scripts' from my gulp watch it started working.
I then made the connection that it was watching the same directory that it was placing the new concatenated and minified js files in so it was putting the new file, checking that file, and looping over and over causing memory issues as well as not allowing 'compass' to run.
After creating a 'dest' folder to hold the new js everything started working just peachy.
I am basing my project off Google Web Starter Kit and am looking to integrate gulp-preprocess into the gulp pipeline.
I have managed to get it to work for the gulp serve:dist task, the relevant code is:
gulp.task('htmlIncludes', function() {
gulp.src('app/*.html')
.pipe(preprocess({context: { NODE_ENV: 'production', DEBUG: true}}))
.pipe(gulp.dest('./dist/'))
});
gulp.task('default', ['clean'], function (cb) {
runSequence('styles', ['jshint', 'html', 'images', 'fonts', 'copy', 'htmlIncludes'], cb);
});
However, I am having trouble getting it to work for the gulp:serve task which includes browser sync:
gulp.task('serve', ['styles'], function () {
browserSync({
notify: false,
server: ['.tmp', 'app']
});
I would like to add the htmlIncludes task, so that it is re-run when files are updated while running gulp:serve. However, simply adding it to the list which currently includes 'styles' does not have the desired effect. Any idea what I need to change?
You are totally right, you have to add it to the dependencies of this task to be run at least once. However, this is just half of the story. You have to run your task each time your HTML files have changed, so add it to the respective watch process:
gulp.task('serve', ['styles', 'htmlIncludes'], function () {
browserSync({
notify: false,
logPrefix: 'WSK',
server: ['.tmp', 'app']
});
// here's the change
gulp.watch(['.tmp/**/*.html', 'app/**/*.html'], ['htmlIncludes', reload]);
gulp.watch(['app/styles/**/**/**/**/*.{scss,css}'], ['styles', reload]);
gulp.watch(['app/scripts/**/*.js'], ['jshint']);
gulp.watch(['app/images/**/*'], reload);
});
You also see that this browserSync call just serves .tmp and app folders, while your output is stored in dist. So you have to change your htmlIncludes task, too:
gulp.task('htmlIncludes', function() {
return gulp.src('app/*.html')
.pipe(preprocess({context: { NODE_ENV: 'production', DEBUG: true}}))
.pipe(gulp.dest('./.tmp/'))
.pipe(gulp.dest('./dist/'))
});
If you need separate configurations for each output, we have to tackle it again. But for now it should work as planned.
It also might be possible that you have to run the 'html' task in sequence first, but I'm not that fit in the WSK Gulpfile to answer you that ;-)