Trying to use grunt uncss to remove some css - javascript

I have a website that I inherited with a couple of gigantic css files that analysing with DUst-Me Selector in Firefox return me with almost 2000 unused styles.
To remove them I'm trying to use grunt uncss, the problem is that I get the following error:
grunt uncss
Running "uncss:dist" (uncss) task
Fatal error: uncss/node_modules/css: missing '}' near line 2429:5
-> .mobile-hidden {
Those are my configuration files
package.json
{
"name": "tappr-registration",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "^0.6.0",
"grunt-processhtml": "^0.3.3",
"grunt-uncss": "^0.3.7"
}
}
Gruntfile.js
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uncss: {
dist: {
options: {
media: ['min-width'],
timeout: 1000,
htmlroot: 'public_html',
report: 'max'
},
files: {
'dist/clean.css': ['public_html/index.php', 'public_html/page_2.html', 'public_html/page_3.html']
}
}
}
});
// Load the plugin that provides the "uncss" task.
grunt.loadNpmTasks('grunt-uncss');
grunt.loadNpmTasks('grunt-processhtml');
grunt.registerTask('default', ['uncss','processhtml']);
};
Now, my best guess is that I get this error because I specifying in the wrong way the media queries to include but I haven't found some decent documentation on how uncss wants that option.
I already tried to take off the options.
Do somebody has some good suggestion?

Believe it or not the problem was caused by the comments:
<!-- ----- Responsive 34.2857142857em ------>
After that I remove them everything worked fine and I can say the it was very much needed.
Running "uncss:dist" (uncss) task
File cleancss/tidy.css created: 229.48 kB → 25.98 kB
:)

Related

Less task not found error

I recently started using grunt and can't seem to get it working: I installed grunt-cli using npm and also installed a few grunt modules using npm with no issues. I'm trying to compile all the bootstrap framework's less files into one css file but keep getting an error saying the less task was not found. i'm sure everything is where it's supposed to be and I loaded the grunt-contrib-less plugin in the gruntfile. Any idea where I might be going wrong?
My package.json's contents:
{
"name": "dConference",
"version": "0.1.0",
"devDependencies": {
"grunt": "latest",
"grunt-contrib-jshint": "latest",
"jshint-stylish": "latest",
"grunt-contrib-uglify": "latest",
"grunt-contrib-less": "latest",
"grunt-contrib-cssmin": "latest",
"grunt-contrib-watch": "latest"
}
}
And my gruntfile.js's contents:
//gruntfile specifying all tasks to be performed
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//all configuration goes here
less: {
build: {
files: [{
expand: true,
cwd: "components/less",
src: ["*.less"]
dest: "css/main.css"
} ]
}
}
});
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
};
I made Gruntfile.js as following.
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
build: {
files: {
'css/main.css': 'components/less/bootstrap.less'
}
}
}
});
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
};
And running "grunt less" on project root folder was successful.
After successful running of "grunt less" command, main.css was generated under css folder.
Project structure is:
grunt-test-project
components/less
mixins folder
all other bootstrap less files
css
Gruntfile.js
package.json
Please try it on your side and let me know the result.

Grunt imagemin error: Cannot read property 'contents' of undefined

Grunt imagemin throws the following error when I try to run it:
Running "imagemin:dynamic" (imagemin) task
Fatal error: Cannot read property 'contents' of undefined
Here's my package.json file:
{
"name": "project1",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-imagemin": "^1.0.0",
"grunt-contrib-uglify": "^0.11.0",
"imagemin" : "4.0.0"
}
}
And here's my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: 'views/js/src/main.js',
dest: 'views/js/build/main.js'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'views/images/src/',
src: ['**/*.{png,jpg,gif}'],
dest: 'views/images/build/'
}]
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-imagemin');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['uglify', 'imagemin']);
};
The issue was flagged and evidently resolved in a prior version of imagemin. But the agreed upon solution was to update grunt-contrib-imagemin to version 1.0.0 and imagemin to 4.0.0, which I've done and it still isn't working.
Just update the gurnt-contrib-imagemin to 1.0.0 or latest, you may be having older version probably 0.9.x
The GitHub solution (https://github.com/gruntjs/grunt-contrib-imagemin/issues/344), instead of downgrading grunt-contrib-imagemin, is adding "vinyl-fs": "2.2.1" in your package.json.
vinyl-fs seems to be anywhere in the dependency tree. But there was a breaking version change of vinyl-fs from 2.2.1 to 2.3.0, which will brake the build process. So the version should be "forced" to 2.2.1.
I resolved the issue by changing my grunt-contrib-imagemin in my package.json to grunt-contrib-imagemin": "0.9.1"
For me worked updating grunt-contrib-imagemin to version ^1.0.0 and adding dependencies imagemin version ^4.0.0 and vinyl-fs version ^2.1.1

How do you use Istanbul Code Coverage with transpiled Typescript?

I've been reading articles on this all morning trying to get my environment setup correctly. But for some reason I'm not getting it. My setup-
/app
... source (mixed js and ts)
/scripts
... copied source (js)
typescripts.js // transpiled typescript with inline mapping
Tests run fine, and with the mapping debugging in the chrome debugger is mapped correctly. But Istanbul sees the typescripts.js file as one file instead of the concatenation of dozens of other files.
To generate the typescript source I'm using gulp-typescript. The source (excluding tests) are transpiled to the aforementioned typescripts.js, and the tests are transpiled individually and copied to /scripts.
var ts = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
module.exports = function (gulp, config) {
'use strict';
// Runs dot ts files found in `www` through the typescript compiler and copies them as js
// files to the scripts directory
gulp.task('typescript', ['typescript:tests'], function () {
return gulp.src(config.paths.typescript) // [ './www/app/**/*.ts', '!./www/app/**/*.test.ts', '!./www/app/**/*.mock.ts' ]
.pipe(sourcemaps.init())
.pipe(ts(ts.createProject(config.paths.tsConfig))) // './tsconfig.json'
.js
.pipe(concat(config.sourcemaps.dest)) // typescripts.js
.pipe(sourcemaps.write(config.sourcemaps)) // { includeContent: false, sourceRoot: '/app' } - i've also tried absolute local path
.pipe(gulp.dest(config.paths.tmpScripts)); // ./www/scripts
});
gulp.task('typescript:tests', [], function() {
return gulp.src(config.paths.typescriptTests) // [ './www/app/**/*.test.ts', './www/app/**/*.mock.ts' ]
.pipe(ts(ts.createProject(config.paths.tsConfig))) // './tsconfig.json'
.pipe(gulp.dest(config.paths.tmpScripts)); // ./www/scripts
});
};
The resulting typescripts.js has the inline sourcemap. With the sourcemap, the dozen or so ts files results in 106kb.
So from here tests and debugging works fine.
Now in an attempt to get Istanbul code coverage working properly i've installed karma-sourcemap-loader and added it to the preprocessors.
preprocessors: {
'www/scripts/typescripts.js': ['sourcemap'],
'www/scripts/**/*.js': ['coverage']
},
I'd think this is what I'd need to do. But it does not show code coverage on the source files. I tried the absolute path from C:/ but that didn't work either. I also tried the different options in gulp-sourcemaps like adding source (which pushed the file to 160kb) but no like either.
Has anyone gotten this to work? Any ideas what I could be doing wrong?
TL;DR: There is a tool: https://github.com/SitePen/remap-istanbul described as A tool for remapping Istanbul coverage via Source Maps
The article on Sitepan describes it in more detail:
Intern as well as other JavaScript testing frameworks utilise Istanbul
for their code coverage analysis. As we started to adopt more and more
TypeScript for our own projects, we continued to struggle with getting
a clear picture of our code coverage as all the reports only included
the coverage of our emitted code. We had to try to use the compilers
in our minds to try to figure out where we were missing test coverage.
We also like to set metrics around our coverage to let us track if we
are headed the right direction.
A couple of us started exploring how we might be able to accomplish
mapping the coverage report back to its origins and after a bit of
work, we created remap-istanbul, a package that allows Istanbul
coverage information to be mapped back to its source when there are
Source Maps available. While we have been focused on TypeScript, it
can be used wherever the coverage is being produced on emitted code,
including the tools mentioned above!
How to use the tool with gulp: https://github.com/SitePen/remap-istanbul#gulp-plugin
If you want source map support with Istanbul, you can use the 1.0 alpha release as the current release does not support source maps. I have it set up using ts-node in http://github.com/typings/typings (see https://github.com/typings/typings/blob/bff1abad91dabec1cd8a744e0dd3f54b613830b5/package.json#L19) and source code is being mapped. It looks great and is nice to have my tests and code coverage all running in-process with zero transpilation. Of course, you can use Istanbul 1.0 with the transpiled JavaScript.
For the browser implementation you're using, I'd have to see more of code of what you're doing to see this'll just work for you, but try the 1.0.0-alpha.2 and see what happens.
As blakeembrey mentioned. Istanbul 1.x handles it well.
Below an example of pure npm script that does it with Jasmine.
See https://github.com/Izhaki/Typescript-Jasmine-Istanbul-Boilerplate.
package.json (the relevant stuff)
{
"scripts": {
"postinstall": "typings install dt~jasmine --save --global",
"test": "ts-node node_modules/.bin/jasmine JASMINE_CONFIG_PATH=jasmine.json",
"test:coverage": "ts-node node_modules/istanbul/lib/cli.js cover -e .ts -x \"*.d.ts\" -x \"*.spec.ts\" node_modules/jasmine/bin/jasmine.js -- JASMINE_CONFIG_PATH=jasmine.json"
},
"devDependencies": {
"istanbul": "^1.1.0-alpha.1",
"jasmine": "^2.4.1",
"ts-node": "^0.9.3",
"typescript": "^1.8.10",
"typings": "^1.3.1"
},
}
Output
This is repo works. I ran the repo and can see the tests running. Html view is also generated.
https://github.com/Izhaki/Typescript-Jasmine-Istanbul-Boilerplate
None of the examples provided worked for my Node.JS project (written in TypeScript). I wanted to run unit tests in Jasmine, and covered by Istanbul.
I ended up getting it working with the following.
package.json:
{
"scripts": {
"lint": "tslint 'src/**/*.ts'",
"remap": "./node_modules/.bin/remap-istanbul -i ./coverage/coverage-final.json -t html -o ./coverage && rimraf ./coverage/dist",
"test": "npm run lint && rimraf dist coverage && tsc --project tsconfig-test.json && ./node_modules/.bin/istanbul cover ./node_modules/.bin/jasmine JASMINE_CONFIG_PATH=jasmine.json && npm run remap"
},
"devDependencies": {
"#types/jasmine": "2.8.6",
"#types/node": "9.6.6",
"istanbul": "0.4.5",
"jasmine": "3.1.0",
"remap-istanbul": "0.11.1",
"rimraf": "2.6.2",
"tslint": "5.9.1",
"typescript": "2.8.1"
}
}
jasmine.json
{
"spec_dir": "dist",
"spec_files": [
"**/*.spec.js"
],
"stopSpecOnExpectationFailure": false,
"random": false
}
.istanbul.yml
instrumentation:
root: ./dist
excludes: ['**/*.spec.js', '**/fixtures/*.js']
include-all-sources: true
reporting:
reports:
- html
- json
- text-summary
dir: ./coverage
tsconfig-test.json
{
"compilerOptions": {
"declaration": true,
"lib": [
"dom",
"es6"
],
"module": "commonjs",
"noImplicitAny": true,
"outDir": "dist",
"sourceMap": true,
"target": "es5"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

React and Grunt - Envify NODE_ENV='production' and UglifyJS

I am using Grunt to build a React project and I want to have 'dev' and 'prod' flavours. As react docs says:
To use React in production mode, set the environment variable NODE_ENV to production.
A minifier that performs dead-code elimination such as UglifyJS is
recommended to completely remove the extra code present in development mode.
I am very new using grunt, browserify and stuff but let's see. First problem I have is with envify, I use it as a transform:
browserify: {
options: {
transform: ['reactify'],
extensions: ['.jsx']
},
dev:{
options: {
watch: true //Uses watchify (faster)
},
src: ['js/app.js'],
dest: 'js/bundle.js'
},
/**
* To use React in production mode, set the environment variable NODE_ENV to production.
* A minifier that performs dead-code elimination such as UglifyJS is
* recommended to completely remove the extra code present in development mode.
**/
prod: {
options: {
transform: ['envify'] //How to set up NOD_ENV='production' ?
},
src: ['js/app.js'],
dest: 'js/bundle.js'
}
},
Ok, doing grunt:dev works just fine. So when running grunt:prod... How can I set NODE_ENV: 'production'? I mean, I know I am passing 'envify' as a transform but... No idea how to use that.
After this, I also have an uglify task:
uglify: {
prod: {
files: {
'js/bundle.min.js': ['js/bundle.js']
}
}
}
So after calling grunt:prod, what it creates is two files (bundle.js and bundle-min.js). In production I will like to only have bundle.min.js. I know I can do:
js/bundle.js': ['js/bundle.js']
But mmm I don't know if there is a way to just rename it to bundle.min.js, I guess so... the problem is that in the html I have:
<script src="js/bundle.js"></script>
Is there here also a trick to make it accepts either bundle.js or bundle.min.js?
Thanks in advance.
Transforms are local, and well made packages put their transforms in their package.json file. Unless you're using envify in your own code, you don't need to do anything with it.
What you do need is grunt-env, or another way to set environmental variables.
Here's an alternative by using package.json:
{
"scripts": {
"build": "NODE_ENV=development grunt build-dev",
"dist": "NODE_ENV=production grunt dist"
}
},
"devDependencies": {
"grunt": "...",
"grunt-cli": "..."
}
The benefit here is that the person using your package doesn't even need to install grunt globally. npm run build will run ./node_modules/.bin/grunt build-dev with the correct environmental variable set.
Both John Reilly's and FakeRainBrigand 's answers did not work for me. What worked for me was the following:
Step 1 - Run this command where your package.json is
npm i grunt-env --save-dev
Step 2 - Add the code in "evn:" to your Gruntfile.js within grunt.initConfig like so:
grunt.initConfig({
...
env: {
prod: {
NODE_ENV: 'production'
}
},
...
});
Step 3 - Add the grunt task to your Gruntfile.js
grunt.loadNpmTasks('grunt-env');
Step 4 - Call it before browserify like so:
grunt.registerTask("default", ["env", "browserify"]);
Just an addition to the great answer by FakeRainBrigand, if you're running on Windows (like me) then you need a subtly different syntax in your scripts section:
{
"scripts": {
"build": "SET NODE_ENV=development&&grunt build-dev",
"dist": "SET NODE_ENV=production&&grunt dist"
}
},
"devDependencies": {
"grunt": "...",
"grunt-cli": "..."
}

Setting jshint and travis-ci for javascript project

I'm trying to setup Travis CI on one JavaScript project hosted on GitHub but I'm getting error like
Loading "jshint.js" tasks...ERROR
>> Error: Cannot find module 'jshint/src/cli/cli'
Those are my files:
Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
myFiles: ['cyrlatconverter-v0.5.4.js']
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
};
.travis.yml
language: node_js
node_js:
- 0.10
package.json
{
"name": "node-travis",
"version": "0.1.0",
"devDependencies": {
"grunt": "0.4.1",
"grunt-cli": "0.1.9",
"grunt-contrib-jshint": "0.6.0"
},
"scripts": {
"test": "grunt --verbose"
}
}
Upgrading versions as discussed in github.com/gruntjs/grunt-contrib-jshint/issues/92 solved the problem.
Also as #Dexa pointed out, for him - removal of scripts part of the package.json worked and adding following to the Gruntfile.js :
grunt.registerTask('default', ['jshint']);
For clarification, ^ above registers default grunt task to run jshint when grunt is wrote to command line.

Categories