I'm using the uncss task with grunt.js in order reduce the size of my CSS by removing unused rules.
Here's the url for uncss: https://github.com/addyosmani/grunt-uncss
This is my Gruntfile.js setup:
module.exports = function(grunt) {
grunt.initConfig({
uncss: {
dist: {
files: {
'docs/tidy.css': ['docs/index.html']
}
},
options: {
compress:true
}
},
processhtml: {
dist: {
files: {
'docs/tidy.css': ['docs/index.html']
}
}
}
});
grunt.loadNpmTasks('grunt-uncss');
grunt.loadNpmTasks('grunt-processhtml');
grunt.registerTask('default', ['uncss','processhtml']);
};
And this is my package.json:
{
"name": "ProjectName",
"version": "0.0.1",
"private": true,
"devDependencies": {
"grunt": "~0.4.2",
"grunt-uncss": "~0.1.5",
"grunt-processhtml": "~0.2.7"
}
}
All the dependencies were installed fine, without any errors...
But when I run grunt or grunt uncss, I get the following error:
Running "uncss:dist: (uncss) task
[SyntaxError: Unmatched selector:(http]
>> Uncssing source "docs/index.html" failed.
Warning: Uncss failed. Use --force to continue.
Aborted due to warnings.
Does anybody have any idea what this error means and how to correct it? I searched and searched and I was unable to find any documentation that covers this.
Maybe you're using an unsupported selector, like in this issue : https://github.com/addyosmani/grunt-uncss/issues/14
It looks like you could have a syntax error in your css. Either that or you have a bug in your css. You could run using --force like the error hints at, which I'm assuming will ignore that single rule.
You could look for a selector that looks like this in your css file: (http
Related
I am currently going to the Learn how to Program with Steve Foote. I am using ubuntu as the operating system.I have installed Node.js, installed the grunt command-line, and installed the npm install to the correct folder.
I noticed a problem that when I ran node on the specified folder it wouldn't run the js files I have. I even went to the folder with the js files and it didn't work. I then tried node values.js but nothing came up.
This is my code for the package.json file:
{
"name": "kittenbook",
"version": "0.0.1",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-jshint": "~0.6.3"
}
}
And this is the Gruntfile.js
module.exports = function(grunt) {
//Project Configuiration
grunt.initConfig({
/*
* We will configuire our tasks here
*/
concat: {
release: {
src:['js/values.js', 'js/prompt.js'],
dest: 'release/main.js'
}
},
copy: {
release{
src: 'manifest.json',
dest: 'release/manifest.json'
}
},
jshint: {
files: ['js/values.js', 'js/prompt.js']
}
});
//We will load our plugins here
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-jshint');
//We will register our tasks here
grunt.registerTask('default', ['jshint', 'concat', 'copy']);
};
Sorry if the formatting is bad here it genuinely is all lined up on the text file.
When I type grunt jshint a warning comes up saying:
Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: Unexpected token {
Warning: Task "jshint" not found. Use --force to continue.
Aborted due to warnings.
You are missing a colon (:) in your grunt.initConfig object.
copy: {
release{ /*<--Missing colon in between "release" and the opening bracket {*/
src: 'manifest.json',
dest: 'release/manifest.json'
}
},
I'm trying to create a separate task called stylelint because for reasons I do not want it to be part of the postcss task.
In the gruntfile I'm writing:
stylelint: {
options: {},
src: './assets/css/precss/**'
}
When I run grunt stylelint it lints my code but when it finds an issue then I get Warning: Task "stylelint:src" failed. Use --force to continue.
Am I omitting something?
You should use grunt-stylelint rather than PostCSS as it supports the native stylelint format reporters. Your Gruntfile config should then look something like this:
stylelint: {
css: {
options: {
configFile: '.stylelintrc',
format: 'css'
},
src: [ 'assets/*.css' ]
},
},
I just realised that this is not possible. You have to run grunt with --force
I have just started looking at browserify and am wondering what is the recommended way to require the min versions of dependencies when building for production and the debug ones when building for development?
For example, I have followed the tutorial here - http://www.sitepoint.com/getting-started-browserify/ and ended up with the following files:
js\main.js
var names = require('./names.js'),
findSuperman = require('./findsuperman.js');
if (findSuperman(names())) {
document.write('We found Superman');
} else {
document.write('No Superman...');
}
js\names.js
module.exports = function () {
return ['Barry Allen', 'Hal Jordan', 'Kara Kent', 'Diana Prince', 'Ray Palmer', 'Oliver Queen', 'Bruce Wayne', 'Wally West', 'John Jones', 'Kyle Rayner', 'Arthur Curry', 'Clark Kent'];
}
js\findsuperman.js
var _ = require('underscore');
module.exports = function (values) {
var foundSuperman = false;
_.find(values, function (name) {
if (name === 'Clark Kent') {
console.log('It\'s Superman!');
foundSuperman = true;
} else {
console.log('... No superman!');
}
});
return foundSuperman;
}
index.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Find Superman</title>
</head>
<body>
<script src="js/findem.js"></script>
</body>
</html>
package.json
{
"name": "FindSuperman",
"version": "0.0.1",
"author": "Patrick Catanzariti",
"description": "Code designed to find the elusive red blue blur",
"dependencies": {
"underscore": "*"
},
"devDependencies": {
"browserify": "*",
"grunt": "*",
"grunt-browserify": "*",
"grunt-contrib-watch": "*"
},
"scripts": {
"grunt": "grunt"
}
}
gruntFile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.registerTask('default', ['browserify', 'watch']);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
main: {
options: {
browserifyOptions: {
debug: true
}
},
src: 'js/main.js',
dest: 'js/findem.js'
}
},
watch: {
files: 'js/*',
tasks: ['default']
}
});
}
Running npm run grunt creates js/findem.js, which includes the debug version of the underscore package (and also starts the watcher).
But I would also like to have js/findem-min.js - the min version intended for production and which should include the min version of the underscore package.
And here there are a few things I need to understand. Indeed:
require('underscore') maps to the debug version. There does not seem to be require('underscore-min'). Seems like one has to resort to require('underscore/underscore-min.js'). Am I correct?
How to require different things conditionally depending on the production or development build, but only when browserifying? The final js file (js\findem.js or js\findem-min.js) should require the right thing unconditionally, of course.
Should I also have index-min.html? Does not seem right. So, I should have one index.html which loads either js\findem.js or js\findem-min.js? Since I cannot have both at the same time I need to serve index.html as a dynamic content rather than a static file. Something like a jade template with the name of the js file being either js\findem.js or js\findem-min.js depending on the startup parameters (NODE_ENV=development comes to mind). Am I correct?
I would like to know whether I understand correctly the items 1 and 3, but I do not have an answer for item 2. What is the recommended way (the best practice, if you please) to do it? I might have gotten items 1 and 3 wrong as well, so please, correct me if I am wrong there.
I haven't used browserify in years. Most people use Webpack now. That said, the parameters passed to Browserify from grunt will control the output. A "run" command typically maps to debug. There will be a separate command to build production files.
For #1, you'll only ever want to write require('underscore'). It's up to the module bundler (browserify/webpack/etc) to rewrite/handle that. Include .js in your requires if you're referencing a specific file. Do not include it if you're referencing a module from outside of your project, such as underscore.
For #2, Browserify has pretty bad documentation. Since Webpack works in mostly the same way here, reading their resolve documentation might help you figure this out. https://webpack.github.io/docs/resolving.html
For #3, that's correct. The HTML needs to reference different .js files depending on if you're in prod/debug. You can hardcode it with two files if you want static output. But in most cases, yes, you typically pick an env variable. Other cases might be serving legacy .js files for old browsers, etc.
Good luck (and switch to webpack :)
As the title says I'm new to Grunt. I am following a tutorial located at: http://24ways.org/2013/grunt-is-not-weird-and-hard/. It is an older tutorial but most seems to work the same. I have installed "grunt-contrib-concat" and "grunt-contrib-uglify" and can run both individually. But when I run grunt, I get the following error: Warning: Task "concat, uglify" not found. Use --force to continue. Aborted due to errors. I've been looking around and can't seem to figure it out. My files are as follows:
Gruntfile.js:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
'js/controls.js', // This specific file
],
dest: 'dist/built.js',
}
},
uglify: {
build: {
src: 'js/build/production.js',
dest: 'js/build/production.min.js',
}
},
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
// 4. Where we tell Grunt what to do when we type 'grunt' into the terminal.
grunt.registerTask('default', ['concat, uglify']);
};
package.json:
{
"name": "grunt_libsass_example-project",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-uglify": "^0.9.1"
}
}
Your passing in only one string for the registerTask task list. It should be a array with a list of strings like:
grunt.registerTask('default', ['concat', 'uglify']);
You're getting that error because it's looking for a task named 'concat, uglify'.
I had to run:
npm install grunt-contrib-uglify --save-dev
I set up grunt to run node.js jasmine tests. For some reason, with this config, the results always show double the tests.
Here is my config:
I'm using jasmine-node which plugs into grunt.
/spec/some-spec.js:
var myModule = require('../src/myModule.js');
describe('test', function(){
it('works', function(done){
setTimeout(function(){
expect(1).toBe(1);
done();
}, 100);
});
});
Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
This results in two tests running rather than one.
> grunt
Running "jasmine_node:all" (jasmine_node) task
..
Finished in 0.216 seconds
2 tests, 2 assertions, 0 failures, 0 skipped
I was able to reproduce the behavior. This is what seems to be happening:
The task looks in the specified folder (spec in your case) for files with spec in the name.
Then it looks again in every folder in the whole project for files with spec in the name.
What it ends up with is 2 overlapping sets of test files to run.
My first attempt at trying to coerce it into more logical behavior was to set specNameMatcher: null (default is 'spec'), and leave the folder set to 'spec/'. This results in no tests being run, since apparently both conditions (name and folder) must be met for files in the specified folder. You get the same problem if specNameMatcher is left at the default value, but the files in the folder don't have 'spec' in the name.
What does work is to set the folder (or 'test set' or whatever you want to call it) to []:
jasmine_node: {
options: {
forceExit: true
},
all: []
}
The catch is that if you have any other files somewhere else in the project with 'spec' in the name, they'll be mistaken for tests by jasmine.
I would consider this behavior a bug, and it should probably be reported via the project's github issues page.
This grunt plugin ( https://github.com/jasmine-contrib/grunt-jasmine-node ) seems to be dead ( https://github.com/jasmine-contrib/grunt-jasmine-node/issues/60 ).
Maybe it is a better to switch to https://github.com/onury/grunt-jasmine-nodejs ?
The jasmine-node project is pretty old. The latest commit is from July of 2014. The grunt-jasmine-node plugin appears to be active, but running against something that is going stale seems a little pointless IMHO.
To test CommonJS modules using Jasmine I'd recommend using Karma along with the
karma-jasmine and karma-commonjs plugins. I got your example working with the following files:
package.json
{
"private": "true",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-jasmine-node": "^0.3.1",
"grunt-karma": "^0.10.1",
"jasmine-core": "^2.3.4",
"karma": "^0.12.31",
"karma-commonjs": "0.0.13",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4"
}
}
karma.conf.js
module.exports = function(config) {
config.set({
basePath: '.',
frameworks: ['jasmine', 'commonjs'],
files: [{
pattern: 'src/**/*.js'
}, {
pattern: 'spec/**/*.js'
}],
preprocessors: {
'src/**/*.js': ['commonjs'],
'spec/**/*.js': ['commonjs']
},
reporters: ['progress'],
browsers: ['PhantomJS']
});
};
Gruntfile.js (optional if you still want to use grunt)
module.exports = function(grunt) {
grunt.initConfig({
karma: {
unit: {
configFile: 'karma.conf.js',
options: {
singleRun: true
}
}
}
});
grunt.loadNpmTasks('grunt-karma');
grunt.registerTask('default', ['karma:unit']);
};
You should also install the karma command line runner globally, just like you probably did with grunt. npm install -g karma-cli
From your command line you can start karma by typing karma start. It will run the tests and then watch your files and re-run them on every save. (VERY NICE)
Alternatively you can run karma start --single-run to have it just run your tests once and exit. If you also updated your Gruntfile you can also just run grunt to run the tests once.
The current up voted answer isn't the solution. You simply modify the expression that's going to match your tests. The answer is as follows:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/*spec.js']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
Here you can see that 'all' is set to *'spec/spec.js'. This will search for all tests.
Secondly, just because a project hasn't had a recently commit, doesn't mean it's "old". jasmine-node is simply stable.
I have the same issue using grunt-jasmine-node, and as aeryaguzov points out, that project is no longer maintained. Switching to grunt-jasmine-node-new solves the issue for me.
grunt-jasmine-node-new is a fork of grunt-jasmine-node that is actively maintained, and can be found here: https://www.npmjs.com/package/grunt-jasmine-node-new