I have successfully got all my scss including bootstraps to combine into one minified file using gulp. Now I am trying to do the same with my js and bootstraps. The problem is that uglify keeps throwing errors at me like Unexpected token: name ($) etc. And won't minify / compile bootstrap js because of this. Now I'm starting to believe I am going the wrong way about this.
This is my file structure:
app/js(my.js files in here)/vendor/bootstrap/js/src/(boostrap js files here)
As you can see, what I have done is just copy the bootstrap js files into my files in the hope that they would be minified / compiled along with mine. But with the scss I imported the files like you usually do. So am I doing this the wrong way?
here's my gulp.js code
var gulp = require('gulp');
var sass = require('gulp-sass');
var cleanCss = require('gulp-clean-css');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var gulpSequence = require('gulp-sequence');
var autoPrefixer = require('gulp-autoprefixer');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var csslint = require('gulp-csslint');
var htmlReporter = require('gulp-csslint-report');
var plumber = require('gulp-plumber');
var sourcemaps = require('gulp-sourcemaps');
//plumber error
var onError = function (err) {
console.log(err);
};
//create sourcemaps, convert scss to css, lint check, minify and prefix
gulp.task('css', function(){
return gulp.src('app/scss/**/*.scss')
.pipe(plumber({
errorHandler: onError
}))
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(csslint())
.pipe(htmlReporter())
.pipe(cleanCss())
.pipe(rename({
suffix: '.min'
}))
.pipe(autoPrefixer({
browsers: ['last 3 versions'],
cascade: false
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/css'))
});
//create sourcemaps, lint check, compile into one file, minify
gulp.task('js', function() {
return gulp.src('app/js/**/*.js')
.pipe(plumber({
errorHandler: onError
}))
.pipe(sourcemaps.init())
.pipe(jshint())
.pipe(jshint.reporter('gulp-jshint-html-reporter', {
filename: __dirname + '/jshint-output.html',
createMissingFolders : false
}))
.pipe(concat('all.js'))
.pipe(uglify())
.pipe(rename({
suffix: '.min'
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js'))
});
//copy php files to app
gulp.task('phpCopy', function(){
return gulp.src('app/*.php')
.pipe(plumber({
errorHandler: onError
}))
.pipe(gulp.dest('dist'));
});
//functions to run on file save
gulp.task('watch', function(){
gulp.watch('app/scss/**/*.scss', ['css']);
gulp.watch('app/*.php', ['phpCopy']);
gulp.watch('app/js/**/*.js', ['js']);
});
gulp.task('default', ['css', 'js', 'phpCopy']);
To any body struggling with this here is what I did to fix this problem.
//create sourcemaps, lint check, compile into one file, minify
gulp.task('js', function() {
return gulp.src([
'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/dist/js/bootstrap.js',
'app/js/**/*.js'
])
.pipe(plumber({
errorHandler: onError
}))
.pipe(sourcemaps.init())
.pipe(jshint())
.pipe(jshint.reporter('gulp-jshint-html-reporter', {
filename: __dirname + '/jshint-output.html',
createMissingFolders : false
}))
.pipe(concat('all.js'))
.pipe(uglify())
.pipe(rename({
suffix: '.min'
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js'))
});
I had to point to the bootstrap file inside node_modules instead of copying them into my files. Here's a tutorial that helped me http://george.webb.uno/posts/gulp-and-npm-for-front-end-web-development
And if you copy this code be aware that sourcemaps isn't working properly yet. I will continue to work on this.
Related
Below is a copy of my gulpfile.js. For some reason /util.js, /alert.js & push.js are not being compiled into my scripts.js file when I run "gulp scripts" from the terminal in VSCode. I would appreciate an advice to help me sort out this problem. I'm new to gulpfile format, so I wouldn't be surprised if I've
made a mistake somewhere
const gulp = require('gulp');
const sass = require('gulp-sass');
const browserSync = require('browser-sync').create();
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
function scripts() {
return gulp.src(
'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/js/dist/util.js',
'node_modules/bootstrap/js/dist/alert.js',
'node_modules/var/push.js',
'js/main.js',
'js/other.js'
)
.pipe(concat('scripts.js'))
.pipe(gulp.dest('js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('./js'));
}
// compile scss into css
function style() {
// 1 where is scss file
return gulp.src('scss/**/*.scss')
// 2 pass that file through sass compiler
.pipe(sass().on('error', sass.logError))
// 3 where do iI have the compiled css?
.pipe(gulp.dest('./css'))
// 4 stream changes to all browsers
.pipe(browserSync.stream());
}
function watch() {
browserSync.init({
server: {
baseDir: './'
}
});
gulp.watch('scss/**/*.scss', style);
gulp.watch('*.html').on('change', browserSync.reload);
gulp.watch('js/**/*.js').on('change', browserSync.reload);
}
exports.style = style;
exports.watch = watch;
exports.scripts = scripts;
When passing several globs or paths to gulp.src, you should wrap them in an array:
return gulp.src([
'node_modules/jquery/dist/jquery.js',
'node_modules/bootstrap/js/dist/util.js',
'node_modules/bootstrap/js/dist/alert.js',
'node_modules/var/push.js',
'js/main.js',
'js/other.js'
])
So I have the following basic project structure that I use throughout all my projects:
Where the src folder looks like this:
I use Pug(Jade), sass compiling and useref js compilation.
This is my Jade views structure:
And this is my Jade index file:
This is my Jade scripts file, that is included in the index:
This is my pre-build index file, which is constructed by the index.pug:
And this is the build version of the index file:
My Gulpfile looks like this:
var gulp = require('gulp'),
sass = require('gulp-sass'),
plumber = require('gulp-plumber'),
changed = require('gulp-changed'),
gutil = require('gulp-util'),
pug = require('gulp-pug'),
concat = require('gulp-concat'),
browserSync = require('browser-sync').create(),
useref = require('gulp-useref'),
uglify = require('gulp-uglify'),
gulpIf = require('gulp-if'),
cssnano = require('gulp-cssnano'),
imagemin = require('gulp-imagemin'),
cache = require('gulp-cache'),
del = require('del'),
cssAdjustUrlPath = require('gulp-css-adjust-url-path'),
runSequence = require('run-sequence');
function handleError(err) {
gutil.beep();
console.log(err.toString());
this.emit('end');
}
gulp.task('sass', function () {
return gulp.src('src/scss/**/*.scss')
.pipe(plumber({
errorHandler: handleError
}))
.pipe(sass()) // Using gulp-sass
.pipe(gulp.dest('src/css'))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('sass-dist', function () {
return gulp.src('src/scss/**/*.scss')
.pipe(cssAdjustUrlPath(/(url\(['"]?)[/]?(assets)/g))
.pipe(sass()) // Using gulp-sass
.pipe(gulp.dest('dist/css'))
});
gulp.task('views', function buildHTML() {
return gulp.src('src/views/*.pug')
.pipe(changed('src', {
extension: '.html'
}))
.pipe(pug({
pretty: true
}))
.pipe(gulp.dest('src/'))
});
gulp.task('views-dist', function buildHTML() {
return gulp.src('src/views/*.pug')
.pipe(changed('src', {
extension: '.html'
}))
.pipe(pug({
pretty: true
}))
.pipe(gulp.dest('dist/'))
});
gulp.task('watch', ['browserSync', 'views', 'sass'], function () {
gulp.watch('src/scss/**/*.scss', ['sass']);
gulp.watch('src/views/**/*.pug', ['views']);
// Reloads the browser whenever HTML or JS files change
gulp.watch('src/js/**/*.js', browserSync.reload);
gulp.watch('src/*.html', browserSync.reload);
});
gulp.task('browserSync', function () {
browserSync.init({
server: {
baseDir: 'src'
},
port: 3000
});
});
gulp.task('useref', function () {
return gulp.src('src/*.html')
.pipe(useref())
.pipe(gulpIf('*.js', uglify()))
// Minifies only if it's a CSS file
.pipe(gulpIf('*.css', cssnano()))
.pipe(gulp.dest('dist'));
});
gulp.task('useref-dist', function () {
return gulp.src('src/**/*.html')
.pipe(useref())
.pipe(gulpIf('*.js', uglify()))
// Minifies only if it's a CSS file
.pipe(gulpIf('*.css', cssnano()))
.pipe(gulp.dest('dist'));
});
gulp.task('images', function () {
return gulp.src('src/images/**/*.+(png|jpg|jpeg|gif|svg)')
// Caching images that ran through imagemin
.pipe(cache(imagemin({
interlaced: true
})))
.pipe(gulp.dest('src/images/'));
});
gulp.task('images-dist', function () {
return gulp.src('src/images/**/*.+(png|jpg|jpeg|gif|svg)')
// Caching images that ran through imagemin
.pipe(cache(imagemin({
interlaced: true
})))
.pipe(gulp.dest('dist/images/'));
});
gulp.task('fonts', function () {
return gulp.src('src/fonts/**/*')
.pipe(gulp.dest('dist/fonts'));
});
gulp.task('clean:dist', function () {
return del.sync('dist');
});
gulp.task('build', function (callback) {
runSequence('clean:dist', ['sass-dist', 'useref-dist', 'images-dist', 'fonts', 'views-dist'],
callback
);
});
gulp.task('default', function (callback) {
runSequence(['views', 'sass', 'browserSync', 'watch'],
callback
);
});
When I run the build task gulp build, all is well, except the relative/absolute paths inside the outputted CSS files, and the JS that runs the final product, whereas fonts/backgrounds/icons and JS functionality is not translated into the final build.
What is wrong with my Gulp file, and how can I fix it?
I'm new with js, node and all things related.
I'm trying to set up a front end development environment from scratch, using gulp, bower, browser sync, and other plugins.
I'm almost done, it's working in some way, except for a couple of details I can't resolve because I'm not sure if it's something in the code syntax or the order of the functions executed in my gulpfile.js file, or because the plugins are not being used correctly. I have already tried to change the order of them, change some path, etc with no results.
Now I'm experiencing the following issues:
The main.scss needs to be saved two times before see the changes reflected in the browser.
When I run gulp in the console this is what I receive (these errors are new and appeared after a minor change proposed by Poeta in his answer, which helped me a lot.
[16:38:08] Starting 'html'...
[16:38:08] 'html' errored after 41 ms
[16:38:08] ReferenceError: injectFiles is not defined
at Gulp. ([full_path]\gulpfile.js:50:18)
at module.exports ([full_path]\node_modules\orchestrator\lib\runTask.js:34:7)
at Gulp.Orchestrator._runTask ([full_path]\node_modules\orchestrator\index.js:273:3)
at Gulp.Orchestrator._runStep ([full_path]\node_modules\orchestrator\index.js:214:10)
at [full_path]\node_modules\orchestrator\index.js:279:18)
at finish ([full_path]\node_modules\orchestrator\lib\runTask.js:21:8)
at [full_path]\node_modules\orchestrator\lib\runTask.js:52:4
at f ([full_path]\node_modules\once\once.js:17:25)
at DestroyableTransform.onend ([full_path]\node_modules\end-of-stream\index.js:31:18)
at emitNone (events.js:91:20)
This is my gulpfile.js content:
var gulp = require('gulp');
var sass = require('gulp-sass');
var inject = require('gulp-inject');
var wiredep = require('wiredep').stream;
var plumber = require('gulp-plumber');
var imagemin = require('gulp-imagemin');
var browserSync = require('browser-sync');
var uglify = require('gulp-uglify');
gulp.task('styles', function(){
var injectAppFiles = gulp.src(['!src/styles/main.scss', 'src/styles/*.scss'], {read: false});
var injectGlobalFiles = gulp.src('src/global/*.scss', {read: false});
function transformFilepath(filepath) {
return '#import "' + filepath + '";';
}
var injectAppOptions = {
transform: transformFilepath,
starttag: '// inject:app',
endtag: '// endinject',
addRootSlash: false
};
var injectGlobalOptions = {
transform: transformFilepath,
starttag: '// inject:global',
endtag: '// endinject',
addRootSlash: false
};
return gulp.src('src/styles/main.scss')
.pipe(plumber())
.pipe(wiredep())
.pipe(inject(injectGlobalFiles, injectGlobalOptions))
.pipe(inject(injectAppFiles, injectAppOptions))
.pipe(sass())
.pipe(gulp.dest('dist/styles'));
});
gulp.task('html', ['styles'], function(){
var injectAppFiles = gulp.src('src/styles/*.scss', {read: false});
var injectOptions = {
addRootSlash: false,
ignorePath: ['src', 'dist']
};
return gulp.src('src/index.html')
.pipe(plumber())
.pipe(inject(injectFiles, injectOptions))
.pipe(gulp.dest('dist'));
});
gulp.task('imagemin', function() {
gulp.src('src/assets/*.{jpg,jpeg,png,gif,svg}')
.pipe(plumber())
.pipe(imagemin())
.pipe(gulp.dest('dist/assets'));
});
gulp.task('uglify', function() {
gulp.src('src/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
gulp.task('sass', function() {
gulp.src('src/styles/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest('dist/styles/'));
});
gulp.task('browser-sync', function() {
browserSync.init(["styles/*.css", "js/*.js","index.html"], {
server: {
baseDir: "dist"
}
});
});
gulp.task('watch', function() {
gulp.watch('src/js/*.js', ['uglify']).on('change', browserSync.reload);
gulp.watch('src/styles/*.scss', ['sass']).on('change', browserSync.reload);
gulp.watch('src/assets/*.{jpg,jpeg,png,gif,svg}', ['imagemin']).on('change', browserSync.reload);
gulp.watch('src/index.html', ['html']).on('change', browserSync.reload);
});
gulp.task('default', ['html', 'sass','imagemin', 'uglify', 'browser-sync', 'watch']);
So, could you please point me in the right direction to get this enviroment set in the proper way?
Update about previous problem: The following was resolved thanks to Bruno Poeta's answer.
Plumber found unhandled error: Error in plugin 'gulp-sass'
Message: src\styles\main.scss
Error: An #import loop has been found: (full_path)/src/styles/main.scss imports src/styles/main.scss on line 526 of src/styles/main.scss
After that message...
[15:11:18] Finished 'styles' after 4.48 s
[15:11:18] Starting 'html'...
[15:11:19] gulp-inject 1 files into index.html.
[15:11:19] Finished 'html' after 1.44 s
[15:11:19] Starting 'default'...
[15:11:19] Finished 'default' after 6.98 μs
[Browsersync] Access URLs:
Local: localhost : 3000
External: 192.168 .0.4 :3000
UI: localhost :3001
UI External: 192.168 .0.4 :3001
[Browsersync] Serving files from: dist
[Browsersync] Watching files...
Note: the line 526 doesn't exist since it is generated by the gulp-inject plugin. These are the last lines in the main.css file, line 520 and 521:
// inject:app
// endinject
The error as you may have noticed is in your styles task. The problem is that you are importing all .scss files, including main.scss itself. That is your loop, right there. Remove main.scss from the files that should be injected, like this:
gulp.task('styles', function(){
var injectAppFiles = gulp.src(['!src/styles/main.scss', 'src/styles/*.scss'], {read: false});
// ...
It should work right now.
Below is my current Gulpfile.js and when I'm attempting to run gulp minify I'm getting the error, "Task 'minify' is not in your gulpfile". However, I'm able to run gulp sass with no issues. I also have each module installed with npm.
module.exports = function(gulp) {
'use strict'
var sass = require('gulp-sass');
var browserSync = require('browser-sync');
var cssnano = require('gulp-cssnano');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
gulp.task('sass', function() {
return gulp.src('app/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('app/css'))
.pipe(browserSync.reload({
stream: true
}))
});
gulp.task('minify', function() {
return gulp.src('app/css/**/*.css')
.pipe(cssnano())
.pipe(concat('style.min.css'))
.pipe(gulp.dest('app/css/min'))
.pipe(browserSync.reload({
stream: true
}))
});
gulp.task('watch', ['browserSync', 'sass', 'cssnano'], function() {
gulp.watch('app/scss/**/*.scss', ['sass']);
gulp.watch('app/*.html', browserSync.reload);
gulp.watch('app/js/**/*.js', browserSync.reload);
});
gulp.task('browserSync', function() {
browserSync({
server: {
baseDir: 'app/'
},
})
})
}
You should not treat the gulpfile.js as a node module and drop the following part
module.exports = function(gulp) {
(don't forget to remove the closing curly (}) at the end of the gulpfile.js)
Then, you should require gulp
var gulp = require('gulp');
That should make it run smoothly.
Why it does run your gulp sass, I don't know. I just created a simple test file in a fresh directory, and it didn't recognise the sass task for me. Maybe you installedgulp, sass or both globally at some point (e.g. earlier project).
I have a gulp file that I just wrote and I'm new at this. It's working but I have more tasks than I think I need.
Can anyone help me string the javascript tasks together as one task?
I need four separate js files all uglified when I'm done.
relevant code snippet from gulpfile.js:
var gulp = require('gulp')
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
del = require('del');
gulp.task('clean', function(cb) {
del(['css/*', 'js/min/*'], cb)
});
gulp.task('featuretest', function() {
return gulp.src('js/feature-test.js')
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
});
// This file: '/js/excanvas.min.js' is only loaded via lte IE8 conditional statement
gulp.task('excanvas', function() {
return gulp.src('js/polyfills/excanvas.js')
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
});
// This file: '/js/charts.min.js' is only used on very few pages
gulp.task('charts', function() {
return gulp.src(['js/highcharts-4.0.1.js', 'js/usfa-theme.js'])
.pipe(concat('charts.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
});
// This file: '/js/main.min.js' is a concat of 'libs/jquery', a few polyfills (except excanvas.js and the highcharts)
gulp.task('scripts', function() {
return gulp.src(['js/libs/*.js', 'js/plugins/*.js', 'js/polyfills/*.js', '!js/excanvas.js', '!js/highcharts-4.0.1.js', 'js/custom.js'])
.pipe(concat('main.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
.pipe(notify({ message: 'Scripts task complete' }));
});
gulp.task('watch', function() {
// Watch .js files
gulp.watch('js/**/*.js', ['featuretest', 'excanvas', 'charts', 'scripts']);
});
gulp.task('default', ['clean'], function() {
gulp.start('featuretest', 'excanvas', 'charts', 'scripts');
});
What I was trying to do:
var gulp = require('gulp')
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
del = require('del');
gulp.task('clean', function(cb) {
del(['css/*', 'js/min/*'], cb)
});
gulp.task('scripts', function() {
// This file: '/js/feature-test.js' is loaded in the doc <head>
return gulp.src('js/feature-test.js')
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
// This file: '/js/excanvas.min.js' is only loaded via lte IE8 conditional statement at the end of the doc
return gulp.src('js/polyfills/excanvas.js')
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
// This file: '/js/charts.min.js' is only used on very few pages and is loaded only when needed at the end of the doc
return gulp.src(['js/highcharts-4.0.1.js', 'js/usfa-theme.js'])
.pipe(concat('charts.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
// This file: '/js/main.min.js' is a concat of 'libs/jquery', a few polyfills (except excanvas.js and the high charts), it is loaded at the end of every doc
return gulp.src(['js/libs/*.js', 'js/plugins/*.js', 'js/polyfills/*.js', '!js/excanvas.js', '!js/highcharts-4.0.1.js', 'js/custom.js'])
.pipe(concat('main.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('js/min'))
.pipe(notify({ message: 'Scripts task complete' }));
});
gulp.task('watch', function() {
// Watch .js files
gulp.watch('js/**/*.js', ['scripts']);
});
gulp.task('default', ['clean'], function() {
gulp.start('scripts');
});
If you're asking the question how do I combine separate operations into a single task, you can combine streams with gulp-util.
var gulp = require('gulp')
uglify = require('gulp-uglify'),
util = require('gulp-util');
gulp.task('scripts', function() {
var featureTest = gulp.src('js/feature-test.js')...
var excanvas = gulp.src('js/polyfills/excanvas.js')...
var charts = gulp.src(['js/highcharts-4.0.1.js', 'js/usfa-theme.js'])...
var scripts = gulp.src(['js/libs/*.js', 'js/plugins/*.js', 'js/polyfills/*.js', '!js/excanvas.js', '!js/highcharts-4.0.1.js', 'js/custom.js'])...
// combine streams
return util.combine(featureTest, excanvas, charts, scripts);
});
This will give you a single task, but it's not any faster. If you're not forcing things to be sequential, gulp will be as fast as it's gonna be.