Laravel minify css and js files - javascript

I receive custom js and css script as a string through html form. This strings are then saved in files on filesystem. The question is how to minify those files every time they are generated/updated. I am using gulp and laravel elixir.
My first idea was to call exec("gulp something") but not sure how to configure gulp.

Requirments:
gulp-newer
minifyCss
gulp-uglify
First step:(install plugins)
minifyCss and gulp-uglify are used by laravel-elixir. You have to install gulp-newer by npm install gulp-newer --save-dev.
Second step:(define task)
You need to define different tasks for css and js.
CSS task
gulp.task('cssTask', function() {
return gulp.src(cssSrc)
.pipe(newer(cssDest))//compares the css source and css destination(css files)
.pipe(minifyCss())//minify css
.pipe(gulp.dest(cssDest));//save minified css in destination directory
});
Js task
gulp.task('jsTask', function() {
return gulp.src(jsSrc)
.pipe(newer(jsDest))//compares the js source and js destination(js files)
.pipe(uglify())//minify js
.pipe(gulp.dest(jsDest));//save minified js in destination directory
});
Third step:(define custom watch)
You should have a watch task which watches your source directories(cssSrc and jsSrc) and calls its related task.
gulp.task('custom', function() {//Watch task
gulp.watch(cssSrc, ['cssTask']);//watch your css source and call css task
gulp.watch(jsSrc, ['jsTask']);//watch your js source and call js task
});
Fourth step:(run custom watch)
Finally, you must run the custom task by gulp custom.
Conclusion:
Every time, when file is added to the source directory. Gulp will minify the file and store it in destination directory. This is tested locally and it works perfectly.
Completed Gulp file
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var newer = require('gulp-newer');
var minifyCss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
cssSrc = 'cssSrc/*.css';//Your css source directory
cssDest = 'cssDest';//Your css destination directory
jsSrc = 'jsSrc/*.js';//Your js source directory
jsDest = 'jsDest';//Your js destination directory
gulp.task('cssTask', function() {
return gulp.src(cssSrc)
.pipe(newer(cssDest))//compares the css source and css destination(css files)
.pipe(minifyCss())//minify css
.pipe(gulp.dest(cssDest));//save minified css in destination directory
});
gulp.task('jsTask', function() {
return gulp.src(jsSrc)
.pipe(newer(jsDest))//compares the js source and js destination(js files)
.pipe(uglify())//minify js
.pipe(gulp.dest(jsDest));//save minified js in destination directory
});
gulp.task('custom', function() {//Watch task
gulp.watch(cssSrc, ['cssTask']);//watch your css source and call css task
gulp.watch(jsSrc, ['jsTask']);//watch your js source and call js task
});
Edited after comment:
I would like something like this: gulp custom srcFile destFile.
For that situation, you need to install new plugin which is called yargs.
Installation:
You can install yargs by npm install yargs --save-dev and then you have to pass source directory and destination directory when custom task is called.
gulp custom --cssSrc=cssSource --cssDest=cssDestination --jsSrc=jsSource --jsDest=jsDestination
For example:
gulp custom --cssSrc=cssSrc/*.css --cssDest=cssDest --jsSrc=jsSrc/*.js --jsDest=jsDest
The completed Gulp file:
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var newer = require('gulp-newer');
var minifyCss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var argv = require('yargs').argv;
cssSrc = argv.cssSrc;
cssDest = argv.cssDest;
jsSrc = argv.jsSrc;
jsDest = argv.jsDest;
gulp.task('cssTask', function() {
return gulp.src(cssSrc)
.pipe(newer(cssDest))
.pipe(minifyCss())
.pipe(gulp.dest(cssDest));
});
gulp.task('jsTask', function() {
return gulp.src(jsSrc)
.pipe(newer(jsDest))
.pipe(uglify())
.pipe(gulp.dest(jsDest));
});
gulp.task('custom', function() {
gulp.watch(cssSrc, ['cssTask']);
gulp.watch(jsSrc, ['jsTask']);
});
Note: Every time, the source directory or destination directory is changed, gulp task must be called again.

Use the below gulp modules.
https://www.npmjs.com/package/gulp-minify-css - Minify all your css files.
https://www.npmjs.com/package/gulp-concat-css - Merge all your css in to one file.
https://www.npmjs.com/package/gulp-uglify - Minigy all your JS files.
https://www.npmjs.com/package/gulp-sass - SASS
Refer this answer:
Gulp minify multiple js files to one
Below is sample Gulp File Snippet.
var gulp = require('gulp'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
rename = require('gulp-rename'),
clean = require('gulp-clean'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
livereload = require('gulp-livereload'),
lr = require('tiny-lr'),
server = lr();
// Clean
gulp.task('clean', function() {
return gulp.src(['css', 'js', 'img'], {
read: false
})
.pipe(clean());
});
gulp.task('styles', function() {
return gulp.src('sass/styles.scss')
.pipe(sass({
style: 'expanded'
}))
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('css'))
.pipe(notify({
message: 'Styles task complete'
}));
});
// Concatenate & Minify JS
gulp.task('scripts', function() {
return gulp.src('js/*.js')
.pipe(concat('all.js'))
.pipe(gulp.dest('dist'))
.pipe(rename('all.min.js'))
.pipe(uglify())
.pipe(gulp.dest('dist'));
});
// Watch
gulp.task('watch', function() {
// Watch .scss files
gulp.watch('sass/**/*.scss', ['styles']);
// Watch .js files
gulp.watch('js/**/*.js', ['scripts']);
// Watch image files
gulp.watch('img/**/*', ['images']);
// Create LiveReload server
var server = livereload();
// Watch any files in dist/, reload on change
gulp.watch(['sass/**', 'js/**', 'img/**', '*.html']).on('change', function(file) {
server.changed(file.path);
});
});
gulp.task('default', ['styles', 'scripts', 'watch']);

At first place, you need to store the content in a new file. A good place for this is resources/assets/js:
$jsContent = $request->get('js_custom_content');
file_put_contents(base_path('resources/assets/js/custom.js'), $jsContent);
Ok, once created the javascript file, you need to tell to elixir to minify the custom script:
// it will look for resources/assets/js/custom.js
// and it will compress the output to public/assets/js/custom.min.js
mix.scripts(['custom.js'], 'public/assets/js/custom.min.js');
Optionally, you can version it. That means that everytime the script's content change, gulp will generate a new version in order to avoid browser's cache issues:
mix.version(['public/assets/js/custom.min.js']);
Finally, load the script in your view:
<script type="text/javascript" src="{{ url('assets/js/custom.min.js')) }}"></script>
Or with version:
<script type="text/javascript" src="{{ url(elixir('assets/js/custom.min.js')) }}"></script>

Related

Gulp development workflow and the 'dist' folder

I'm relatively new to gulp and am using it as a taskrunner to concatenate and compile .js and sass/css files. Those aspects are currently working in a development environment.
What I'm confused about is a workflow issue. Right now my concatentated files are in these folders:
-css (myapp.css)
-js (myappconcat.js)
If I'm working locally, I don't want to minify these yet for debugging purposes (right?).
However, reading up on gulp, I see that build tasks are normally set up to minify the assets into a 'dist' folder for production. How do I manage this in my HTML files?
For example, in my development HTML file I would have CSS and js includes like so:
<link href="/css/myapp.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="/js/myappconcat.js"></script>
However, when I build my minified files to a 'dist' directory, I would have to change the paths in the includes above for every HTML file.
How does one go about managing a gulp build to a dist folder without having to change the paths in each include in the HTML? Similarly, when I minify for production, don't I also have to change the .js and CSS filenames in the HTML includes as well? Or should I be using minified files in development?
EDIT: Here's the basic site structure:
wwwroot
-.html files
- gulpfile.js
- package.json
/css
-main.css
/dist
/js
/scss
AND the gulpfile.js
// Required gulp modules
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
sass = require('gulp-sass'),
maps = require('gulp-sourcemaps'),
del = require('del'),
jshint = require('gulp-jshint'),
stylish = require('jshint-stylish'),
gutil = require( 'gulp-util' ),
merge = require('merge-stream'),
imagemin = require('gulp-imagemin'),
cleanCSS = require('gulp-clean-css');
// error reporter in progress
var reportError = function( err ) {
gutil.beep();
var title = 'Error';
if( err.plugin === 'gulp-sass' ) {
title = 'SCSS Compilation Error';
}
var msg = '\n============================================\n\n';
msg += title += '\n\n';
msg += err.message + '\n\n';
msg += '============================================';
gutil.log( gutil.colors.red( msg ) );
if( err.plugin === 'gulp-sass' ) {
this.emit('end');
}
};
// Concatenate .js files with lint-js as the dependency
gulp.task("concatScripts", ["lint-js"], function() {
return gulp.src([
'js/*.js'
,'node_modules/jquery-placeholder/jquery.placeholder.js'
])
.pipe(maps.init())
.pipe(concat('zConcat.js'))
.pipe(maps.write('./'))
.pipe(gulp.dest('dist/js'));//write to separate dir than src otherwise
overwrites itself!
});
// Minify .js files with concatscripts as the dependency
gulp.task("minifyScripts", ["concatScripts"], function() {
return gulp.src("dist/js/zConcat.js")
.pipe(uglify())
.pipe(rename('zConcat.js'))
.pipe(gulp.dest('dist/js'));
});
// .js Linter for catching errors when any .js changes
gulp.task('lint-js', function () {
return gulp.src([
'js/*.js', // all custom .js
//'!_js/public/js/html5shiv.js', // ignore shiv
])
.pipe(jshint())
.pipe(jshint.reporter(stylish)); // color-coded line by line errors
});
// Compile sass files
gulp.task('compileSass', function() {
return gulp.src("scss/main.scss")
.pipe(maps.init())
.pipe(sass(
{
outputStyle: 'expanded'
}
).on( 'error', reportError) ) //sass.logError
.pipe(maps.write('./'))
.pipe(gulp.dest('css'));
});
// Minify CSS after compiling
gulp.task('minifyCSS', () => {
return gulp.src('css/*.css')
.pipe(maps.init())
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename('main.min.css'))
.pipe(maps.write('./'))
.pipe(gulp.dest('css'));
});
// Watch and process SASS and .js file changes
gulp.task('watchFiles', function() {
gulp.watch(['scss/**/*.scss','scss/*.scss'], ['compileSass']);
gulp.watch( 'css/*.css', ['minifyCSS']);
gulp.watch('js/**/*.js', ['concatScripts']);
});
this might be late, but no one answered.
For me, I create two production files (or folders if the output is more than one file, with each folder containing a set of files). One is minified, and the other is not.
For development and testing purposes, I use the non-minified version. Once the product is ready for production, I retest but using the minified version, and typically this is the one I release.
So I write my scripts to produce two files (or file sets if I have more than a file to produce).
Hope this helps.

Browsersnyc not auto reloading on changes made to css

Got Browsersync to work with my Gulp file but I've really been struggling with getting browsersync to auto reload my static site when I make changes to the main.scss file. I've followed all the documentation on there webpage thoroughly and I still cant get page to auto refresh.
I know parts of my integration with gulp are working because when I run my default gulp task which is linked to the browser-sync task a browser window fires up with the server but when I make s simple change to my main.scss file nothing auto reloads. I have to manually refresh to see changes.
Here's my gulpfile..What am I missing in here?
// refferance gulp
var gulp = require('gulp');
// browser-sync
var browserSync = require('browser-sync');
var reload = browserSync.reload;
// other packages installed
var concat = require('gulp-concat');
var cssmin = require('gulp-minify-css');
var rename = require('gulp-rename');
var scss = require('gulp-sass');
var uglify = require('gulp-uglify');
// browser-sync task
gulp.task('browser-sync',['styles'] , function(){
browserSync.init({
server:'./'
});
gulp.watch('.//src/scss/*.scss',['styles']);
gulp.watch('.//*.html').on('change',browserSync.reload);
});
// scripts task
gulp.task('scripts', function(){
// fetch all files in the .js extension in the /src/js directory
return gulp.src('./src/js/*.js')
// concatenate files and save as app.js
.pipe(concat('app.js'))
// save app.js in dest directory
.pipe(gulp.dest('./dest/js/'))
.pipe(uglify())
// minfiy file and rename to app.min.js
.pipe(rename({
suffix: '.min'
}))
// save in dest directory
.pipe(gulp.dest('./dest/js'));
});
// styles task
gulp.task('styles', function(){
// fetch all files with scss extension in /src/scss directory
return gulp.src('./src/scss/*.scss')
// compile scss
.pipe(scss())
// output css in css dest directory
.pipe(gulp.dest('./dest/css/'))
// minify css
.pipe(cssmin())
// rename as styles.min.css
.pipe(rename({
suffix: '.min'
}))
// save in same directory
.pipe(gulp.dest('./dest/css'))
// reload browser by injecting css into browser via browsersync
// .pipe(reload({stream:true}));
.pipe(browserSync.stream());
});
gulp.watch('./src/js/*.js', ['scripts']);
// we use the watch task in the default task bellow
gulp.task('watch',function(){
// watch js
gulp.watch('./src/js/*.js',['scripts']);
// watch scss
gulp.watch('./src/scss/*.scss',['styles']);
});
// default task allows us to run all tasks at once by just running `gulp` in command line
gulp.task('default', ['scripts', 'styles', 'browser-sync', 'watch']);
If you take out
gulp.watch('.//src/scss/*.scss',['styles']);
gulp.watch('.//*.html').on('change',browserSync.reload);
and replace with
gulp.watch('dest/**/*.html').on('change', browserSync.reload);
you should see changes providing that you are looking at a HTML file located under the dest directory.
I would also check that your styles and scripts tasks are firing. You should see this in the terminal/cli. If they are firing, any reload will also be logged too.
Hope that helps you out!

Gulp Watch not working

I'm using Gulp to dome some tasks on my SCSS and CSS. Now the problem is that when I run Gulp it's starting the watch but nothing is happening: no css is being created. I triple checked the folder structure and it's can.
This is my code:
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var watch = require('gulp-watch');
gulp.task('sass', function () {
return gulp.src('resources/assets/sass/**/*.scss')
.pipe(plumber())
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer({browsers: ['last 2 version']}))
.pipe(rename({suffix: '.min'}))
.pipe(minifycss())
.pipe(gulp.dest('./public/css'))
});
gulp.task('default', function () {
watch('resources/assets/sass/**/*.scss', function () {
gulp.start('sass');
});
});
Temporary Solution
After a long search with some people it's just PHPStorm that's not showing the updated file. The file has to be accessed first. It's like a sort of caching.
When I save the .scss file, and immediatly open it with notepad, or access a php file which uses the file, then it also updates in PHPStorm.
Try this one
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
gulp.task('sass', function () {
return gulp.src('resources/assets/sass/**/*.scss')
.pipe(plumber())
.pipe(sass({errLogToConsole: true}))
.pipe(autoprefixer({browsers: ['last 2 version']}))
.pipe(rename({suffix: '.min'}))
.pipe(minifycss())
.pipe(gulp.dest('./public/css'))
});
gulp.task('default', function () {
gulp.watch('resources/assets/sass/**/*.scss', ['sass']);
});
I don't think you really need another plugin to complie your sass files, gulp.watch works just fine.
So basically what I am doing here is, I am just telling gulp to watch all the sass files in that folder and whenever there's a change, just run the task in the given array ['sass'].
The solution is a PHPStorm Setting
It seems that PHPStorm uses a form of file caching, that's why I didn't see the reflected changes. The solution can be found here!
How to prevent phpstorm to reload file without prompt when file on disk is changed?

Gulp JS doesn't output CSS file

I'm a Gulp JS beginner. Currently I'm trying to compile some simple less code to CSS. My Gulp task should output a new CSS file for this but after I run the task, nothing happens. I've included the gulp-util module to try to debug the task execution but it doesn't show me any errors.
Here's my Gulp file:
// gulpfile.js
// --- INIT
var gulp = require('gulp'),
util = require('gulp-util'),
less = require('gulp-less'), // compiles less to CSS
minify = require('gulp-minify-css'), // minifies CSS
concat = require('gulp-concat'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'); // minifies JS
// Paths variables
var paths = {
'dev': {
'less': './laravel/public/assets/less/'
},
'assets': {
'css': './laravel/public/assets/css/ ',
'js': './laravel/public/assets/js/',
'vendor': './laravel/public/assets/bower_vendor/'
}
};
// --- TASKS
// Auth CSS
gulp.task('auth.css', function(){
return gulp.src(paths.dev.less + 'auth.less')
.pipe(less().on('error', util.log))
.pipe(gulp.dest(paths.assets.css))
.pipe(minify({keepSpecialComments:0}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.assets.css));
});
// --- WATCH
// --- DEFAULT
gulp.task('default', ['auth.css']);
I'm using Laravel 4. This file lives in the root directory. I have changed the paths but that doesn't seem to work either. Any ideas?
Try removing the extra space at the end of your path.assets.css.
Just fixed. It seems, the path had to be something like: "./public/assets/css/". Now the file has been generated.

Gulpfile not watching scss

I have a simple gulpfile that loads a javascript object from a json file (to get paths based on environment), compiles my scss files, moves them to my public directory, and also moves any javascript files to the public directory.
So my assets in /app/Http/assets/js and scss
are compiled and moved to /public/assets/js and css
Here is my gulpfile.js:
var gulp = require('gulp');
var gutil = require('gulp-util');
var notify = require('gulp-notify');
var sass = require('gulp-sass');
var autoprefix = require('gulp-autoprefixer');
// Load the application config
var config = require('./env.config.json');
// Where do you store your Sass files?
var sassDir = 'app/Http/Assets/scss';
// Which directory should Sass compile to?
var targetCSSDir = config.assets_path + '/css';
// Where do you store your CoffeeScript files?
var jsDir = 'app/Http/Assets/js';
// Which directory should CoffeeScript compile to?
var targetJSDir = config.assets_path + '/js';
/** Tasks **/
// Compile Sass, autoprefix CSS3, and save to target CSS directory
gulp.task('css', function () {
return gulp.src(sassDir + '/**/*.scss')
.pipe(sass())
.pipe(autoprefix('last 10 version'))
.pipe(gulp.dest(targetCSSDir))
.pipe(notify('CSS minified'))
});
// Move Javascript
gulp.task('js', function () {
return gulp.src(jsDir + '/**/*.js')
.pipe(gulp.dest(targetJSDir))
});
// Keep an eye on Sass and Javascript files for changes...
gulp.task('watch', function () {
gulp.watch(sassDir + '/**/*.scss', ['css']);
gulp.watch(jsDir + '/**/*.js', ['js']);
});
// What tasks does running gulp trigger?
gulp.task('default', ['css', 'js', 'watch']);
This is working fine for my javascript. Also, when I run "gulp" the first time, it compiles all my scss files and moves them accordingly. However, the watch task is not working for my scss files. It DOES work for javascript files. What's really weird (to me) is that when I change my scss source to a specific file, the watch works. So,
gulp.task('css', function () {
return gulp.src(sassDir + '/**/app.scss')
.pipe(sass())
// and the rest is the same
will watch AND compile any changes to my app.scss file, but obviously not to any other scss files.
I have re-arranged and googled all I can. I don't understand why it won't work for watching scss.
EDIT: Strangely, it seems to be notify that is breaking the css watcher. When I comment it out like so:
gulp.task('css', function () {
return gulp.src(sassDir + '/**/*.scss')
.pipe(sass())
.pipe(autoprefix('last 10 version'))
.pipe(gulp.dest(targetCSSDir))
//.pipe(notify('CSS minified'))
});
everything works as expected.
Thanks in advance.

Categories