grunt-contrib-cssmin takes 10 minutes to complete - gruntjs

I currently have an issue that my grunt-contrib-cssmin task takes nearly 10 minutes to complete. This problem occured after I updated grunt and all plugins to current versions. I did not update them for nearly a year before. Before the update, the cssmin task took arount 5 seconds to complete.
What could be the cause of this increase in run time after updating? My task definition is:
cssmin: {
target: {
options: {
banner: '/*! app.min.css <%= grunt.template.today("dd-mm-yyyy") %> */\n',
filename: 'app.min.' + grunt.template.today("ddmmyyyyHHMMss") + '.css'
},
files: {
'app/css/<%= cssmin.target.options.filename %>': [
'app/lib/bower_components/angular-motion/dist/angular-motion.css',
'app/lib/bower_components/ng-sortable/dist/ng-sortable.min.css',
'app/lib/bower_components/pines-notify/pnotify.core.css',
'app/lib/bower_components/pines-notify/pnotify.picon.css',
'app/lib/bower_components/pines-notify/pnotify.buttons.css',
'app/lib/bower_components/pines-notify/pnotify.history.css',
'app/lib/bower_components/angular-bootstrap-colorpicker/css/colorpicker.css',
'app/lib/bower_components/ng-sortable/dist/ng-sortable.min.css',
'app/lib/patches/ui.dynatree.css',
'app/lib/bower_components/selectize/dist/css/selectize.bootstrap3.css',
'app/lib/bower_components/angular-ui-grid/ui-grid.css',
'app/lib/bower_components/angular-resizable/angular-resizable.min.css',
'app/css/screen.css',
'app/css/ie.css'
]
}
}
},

Found the cause of the issue. grunt-contrib-cssmin uses internally the task clean-css. This task has an option "advanced". This option can also be set for grunt-contrib-cssmin, which delegates it to clean-css.
If the advanced option is set to true, the execution times are around 10 minutes. if it is set to false, my execution times for this task are around 6 seconds.

Related

is this Service Worker configuration risky?

I am working on one e-commerce using Next JS. I am trying to improve the page load speed, this website loads a lot of JS files due to the amount of third parties vendors it has (and can't delete). I am planning to cache some static assets with Service Workers.
I am going to use the library next-offline that uses the workbox-webpack-plugin. This is the configuration I am planning to use:
workboxOpts: {
swDest: '../public/service-worker.js',
maximumFileSizeToCacheInBytes: 20000000,
runtimeCaching: [
{
urlPattern: /https:\/\/fonts\.googleapis\.com\/icon[\w\-_\/\.\:\?\=\&\+]*/,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts',
expiration: {
maxEntries: 10,
maxAgeSeconds: 30 * 24 * 60 * 60, // 1 month
},
},
},
{
urlPattern: /[\w\-_\/\.:]*\.(jpeg|png|jpg|ico|svg)\??.*/,
handler: 'CacheFirst',
options: {
cacheName: 'cache-img',
expiration: {
maxEntries: 15,
maxAgeSeconds: 2 * 24 * 60 * 60, // 2 days
},
},
},
{
urlPattern: /^((?!monetate).)*\.(js)$/,
handler: 'StaleWhileRevalidate',
},
{
urlPattern: /\/(browse.*|catalogsearch.*)$/,
handler: 'StaleWhileRevalidate',
},
],
},
So, my questions are the following:
do you think that this configuration is risky? Would you change something? I mean, I had several problems in the past with Service Workers caching JS files where I had to set a version for every file to make it work. However, now it seems that workbox fixed this issue.
Should I set a maxAge for the Stale while revalidation strategy? I want to revalidate the data every time the user reload the page. However here it says that it will use the cache without revalidate until the maxAge time is complete. What happens if I don't set in the workbox settings a maxAge?
I am testing this on a Vercel deploy (in a testing environment) and it seems it is working fine and I am thinking to move it to production.
Thanks,
You can use next-offline(i haven't used it much), or you can go ahead with using workbox-webpack-plugin. There is take cares of what file to refetch after caching(uses revision & hash(on url)).
Read this section : https://developers.google.com/web/tools/workbox/modules/workbox-precaching#how_workbox-precaching_works

Looking for Modernizr references

I'm trying to use the grunt-modernizr plugin in my project but I'm receiving the following output when I run tasks:
Running "modernizr:dist" (modernizr) task
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
I'm not receiving any type of error the terminal just goes back to the directory that I'm in, as if it's just giving up.
Here is my grunt file:
module.exports = function(grunt) {
grunt.initConfig ({
// Do grunt-related things in here
pkg: grunt.file.readJSON('package.json'),
modernizr: {
dist: {
"dest": "javascripts/modernizr-custom.js",
"parseFiles": true,
"customTests": [],
"devFile": "javascripts/modernizr-custom.js",
"outputFile": "javascripts/min/modernizr-custom.min.js",
"tests": [
"pointerevents",
"css/pointerevents"
],
"extensibility": [
"setClasses"
],
"uglify": false
}
},
cssmin: {
target: {
files: {
'css/min/bootstrap.min.css': ['css/bootstrap.css']
}
}
},
});
grunt.loadNpmTasks("grunt-modernizr");
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default',['modernizr', 'cssmin']);
};
Output from running grunt --verbose:
Initializing
Command-line options: --verbose
Reading "gruntfile.js" Gruntfile...OK
Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK
Registering "grunt-modernizr" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Loading "modernizr.js" tasks...OK
+ modernizr
Registering "grunt-contrib-cssmin" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Loading "cssmin.js" tasks...OK
+ cssmin
Loading "gruntfile.js" tasks...OK
+ default
No tasks specified, running default tasks.
Running tasks: default
Running "default" task
Running "modernizr" task
Running "modernizr:dist" (modernizr) task
Verifying property modernizr.dist exists in config...OK
Files: -> javascripts/modernizr-custom.js
Verifying property modernizr exists in config...OK
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
This is something I just came across too and seems to be grunt-modernizr stopping after customizr doesn't find any files to crawl (it crawls by default).
If you add "crawl": false to your modernizr:dist task that should fix the problem.
Also, I think "extensibility": [ "setClasses" ], should be "options": [ "setClasses" ],.
To use the grunt-modernizr task to crawl your code for Modernizr references you'll have to look at the config properties for the customizr task as this is part of grunt-modernizr 's node_modules:
modernizr: {
dist: {
dest: 'bower_components/modernizr/build/modernizr.custom.js',
uglify: false,
options: [
'setClasses',
'addTest'
],
files: {
src: ['js/app/**/*.js', 'js/app/*.js']
}
}
}
devFile: doesn't seem to matter where you point at
dest: instead of outputFile, note I'm just outputting to a build directory that's not part of the package
uglify: false if you have other minifying options like bundleconfig.json
options: to bypass the default options { "setClasses", "addTest", "html5printshiv", "testProp", "fnBind" }
files: to enlist your crawlable director(y|ies), make sure you take care of the root files and/or subdirectories as well
Load the required tasks, in my case:
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-modernizr');
grunt.loadNpmTasks('grunt-contrib-copy');
Refer to the 'modernizr:dist' task => grunt.registerTask('default', ['clean', 'modernizr:dist', 'copy']);
Which results in an unminified 34kb file:
Running "clean:files" (clean) task
19 paths cleaned.
Running "modernizr:dist" (modernizr) task
Looking for Modernizr references
1 match in js/app/classes/yambo.options.js
bgpositionxy
1 match in js/app/modules/yambo.audio.js
audio
Ready to build using these settings:
setClasses, addTest
Building your customized Modernizr...OK
Success! Saved file to bower_components/modernizr/build/modernizr.custom.js
Process terminated with code 0.
Running "copy:main" (copy) task
Copied 11 files
Done, without errors.
This way there's no need to even go to the online build to add a feature test. Simply reference Modernizr throughout your js code:
window.Yambo = (function($, modernizr, ns){
ns.Audio = {
extension: (function () {
return modernizr && modernizr.audio.mp3
? 'mp3'
: modernizr.audio.ogg
? 'ogg'
: 'wav';
}())
};
return ns;
}(window.jQuery, window.Modernizr, window.Yambo || {}));
Make sure to use the correct property name for a feature detection, so customizr can pick it up and provide a test to your custom build.
This should be also possible for css but haven't been testing that for the moment.
It looks like you missed source files.
http://gruntjs.com/configuring-tasks#files-object-format
Try to include
"dist": {
"files": {
"src": ['!<%= appDir %>assets/js/bower/modernizr/**']
}
}

Grunt Browserify max call stack size exceeded

I am using grunt-browserify to compile my react/flux application. I've also enabled Watchify under browserify options so speed up the compile process. It compiles fine when first run, but once I change a file and it compiles again, a Maximum Call Stack Size Exceeded error appears in the browser's console and breaks the application.
It seems that Watchify is adding react/flux/other dependencies again on a recompile which causes the error. Just a theory.
Any ideas?
Grunt Task
browserify: {
dist: {
files: {
'public/dist/bundle.js': ['public/js/**/*.jsx', 'public/js/**/*.js']
},
options: {
debug: true,
bare: true,
alias: [
'./node_modules/react/dist/react-with-addons.js:react',
'./node_modules/flux/index.js:flux',
'./public/lib/react-router/react-router.js:react-router',
'./node_modules/lodash/index.js:lodash'
],
transform: [react.browserify],
watch: true,
keepAlive: true
}
}
}
Register
grunt.registerTask('compile', ['browserify']);
Did you try ignore 'public/dist/bundle.js' for watching ?

Prevent `grunt-watch` from looping when there is a syntax error in less files?

I'm using grunt-watch to re-build my less style sheets:
watch: {
less: {
files: ['media/less/**/*.less'],
tasks: ['less'],
options: {
atBegin: true,
spawn: false
}
}
}
But if there is a syntax error in any of the .less files, the task just loops, trying to re-build the .less files every second… which makes debugging fairly difficult, because the error messages scroll past very quickly.
Is there any way fix that, so grunt-watch will only re-run the task once the .less files have been changed again?
This is using:
grunt#0.4.2
grunt-contrib-less#0.8.3
grunt-contrib-watch#0.5.3
I think the issue you're describing is this one, which was fixed in master but hasn't yet been released (as of 2013/12/17).
Well, for debugging purposes you could do a simple envelope of the less task with a custom task:
grunt.registerTask('myless', 'my less task', function() {
// do whatever debugging you want and stop the loop if needed.
grunt.task.run(['less']);
});
Then use your myless task in the watch.
UPDATE:
the idea is that since any repeated call to less now goes through your code - you can do whatever needed to either provide a more concrete output or preven repeated calls if failing is "desired" outcome and should fail, but not loop.
UPDATE 2:
Something like this:
watch: {
`less`: {
files: ['**/*.less'], // or whatever the extension is
tasks: ['myless'] // your envelope task
}
}
var flag;
grunt.registerTask('myless', 'My LESS task', function() {
if(flag === true) {
// if you are here - it means watch just invoked you repeatedly
// do whatever you need to analyze the issue (includig running an additional task)
flag = false;
return; // you exit task without altering any less files again -
// that should NOT trigger watch again
} else {
flag = true;
grunt.task.run(['less']);
}
});

How do I get Yeoman to continuously run tests

When I run grunt server, my file edits are picked up and the browser refreshed through livereload.
When I run grunt test, it runs once and shuts down.
This behavior can be simulated by running
yo angular --minsafe mytest
grunt test
When I change karma.unit.singlerun = false in the Gruntfile, grunt test now says that a watcher is running, but no file changes seem to trigger running the tests again.
How do I get the reload capability with the tests similar to the way linemanjs works?
You were almost there! There's an additional option you can set in the Gruntfile called autoWatch, which monitors the files specified in your karma.conf.js for changes. A complete entry in your Gruntfile could look like this:
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true,
autoWatch: false
},
server: {
configFile: 'karma.conf.js',
singleRun: false,
autoWatch: true
}
}
I set up as following
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: false,
autoWatch: true
}
}
It stands but can't rerun unit test when I change files, grunt karma:unit output
PhantomJS 1.9.7 (Linux) Controller: MainCtrl should attach a list of awesomeThings to the scope FAILED
Expected 3 to be 100.
PhantomJS 1.9.7 (Linux): Executed 1 of 1 (1 FAILED) ERROR (0.04 secs / 0.014 secs)
Found it: I use shared folder in Virtual and changing it outside virtual machine so that autoWatch can't recognize these changes.

Resources