Does grunt-usemin contain concat, uglify, cssmin? - angularjs

Below is my Gruntfile.js
grunt.initConfig({
useminPrepare: {
html: 'Menu.htm',
options: {
dest: 'build'
}
},
usemin: {
html: ['build/Menu.html']
},
copy: {
generated: {
src: 'Menu.htm',
dest: 'build/Menu.html'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-usemin');
grunt.registerTask('build', [
'copy:generated',
'useminPrepare',
'concat',
'cssmin',
'uglify',
'usemin'
]);
if I run the above code I get error saying no "concat" tasks found. Either I have to remove it from registerTask or I have to add task in config. But as per tutorials I browsed if they add usemin then concat uglify cssmin will be automatically added when I run grunt. Why am I not getting it automatically? Why do I have to add all these task again separately?

According to readme, you need to install it first.
To install these plugins, run:
$ npm install grunt-contrib-concat grunt-contrib-uglify grunt-contrib-cssmin grunt-filerev --save-dev
I encourage you to check the repo and also issue number 313

Related

Coursera - AngularJS week 2 Issue js & css file isn't created after i type grunt command

I'm new in using Grunt tool, I was doing the steps like the video said, but i faced some errors and started from the whole beginning again, but now i'm facing this issue, when i type the command "grunt" in the CMD in the directory of the project folder i get everything good, but there is no JavaScript file created in the distribution folder directory "dist/scripts", and even the Uglify is not generated.
In the video after the instructor typed the command grunt a JS file created in dist/scripts directory with name "main.6c5adb2140e008f7bb85.js", and css file created in dist/styles directory with name "main.d1901e133950f2e3aeae.css", and also in his terminal it was written replaced 1 reference to assets and Uglify generated like in the picture:
Instead i get replaced 0 references to assets and the uglify is not generated:
I did all the installation command that in the video by order, and i created all the files (package.json, Gruntfile.js, app.js, .jshintrc)
after that i added the usemin to the require jit-grunt
and added it to the registerTask. Here's the Gruntfile.js source code:
'use strict';
module.exports = function (grunt) {
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Automatically load required Grunt tasks
require('jit-grunt')(grunt, {
useminPrepare: 'grunt-usemin'
});
// Define the configuration for all the tasks
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'app/scripts/{,*/}*.js'
]
}
},
useminPrepare: {
html: 'app/menu.html',
options: {
dest: 'dist'
}
},
// Concat
concat: {
options: {
separator: ';'
},
// dist configuration is provided by useminPrepare
dist: {}
},
// Uglify
uglify: {
// dist configuration is provided by useminPrepare
dist: {}
},
cssmin: {
dist: {}
},
// Filerev
filerev:{
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 20
},
release: {
// filerev: release hashes(md5) all assets (images, js and css)
// in dist directory
files: [{
src: [
'dist/scripts/*.js',
'dist/styles/*.css',
]
}]
}
},
// Usemin
// Replace all assets with their revved version in html and css files.
// options.assetDirs contains the directories for finding the assets
// according to their relative paths
usemin: {
html: ['dist/*.html'],
css: ['dist/styles/*.css'],
options: {
assetsDirs: ['dist', 'dist/styles']
}
},
copy: {
dist: {
cwd: 'app',
src: [ '**','!styles/**/*.css','!scripts/**/*.js' ],
dest: 'dist',
expand: true
},
fonts: {
files: [
{
//for bootstrap fonts
expand: true,
dot: true,
cwd: 'bower_components/bootstrap/dist',
src: ['fonts/*.*'],
dest: 'dist'
}, {
//for font-awesome
expand: true,
dot: true,
cwd: 'bower_components/font-awesome',
src: ['fonts/*.*'],
dest: 'dist'
}
]
}
},
clean: {
build: {
src: [ 'dist/']
}
}
});
grunt.registerTask('build', [
'clean',
'jshint',
'useminPrepare',
'concat',
'cssmin',
'uglify',
'copy',
'filerev',
'usemin'
]);
grunt.registerTask('default',['build']);
};
Need help please !!
it's look like there is no mistake in the commands that 've wrote but the mistake here is the name of the html in my project folder is not the same name which is "menu.html" and i wrote it in Gruntfile "meun.html" that's why it doesn't create the js & css file !!

Task "serve" not found

I'm a newbie in Angular and I've cloned a repo (angular-slider). My problem is that when I type in console grunt serve it says Warning: Task "serve" not found. Use --force to continue. I've been searching through Internet and I've tried everything. I don't know which is the origin of my problem. If I type node -v the console gives me this v0.10.33 and if I type npm -v I get this 2.11.2 I already have a Gruntfile.js and a package.json and bower.json at the same level folder that my root project directory. Any help would be appreciated.
Edited:
This is my Gruntfile.js
module.exports = function(grunt){
'use strict';
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
srcFiles: [
'src/rangeInputSupported.js',
'src/angular-slider.js'
],
concat: {
prod: {
src: ['<%= srcFiles %>'],
dest: 'build/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*\n <%= pkg.name %> v<%= pkg.version %> \n (c) 2013-2014 Venturocket, Inc. http://github.com/Venturocket \n License: MIT \n*/\n'
},
build: {
src: ['<%= srcFiles %>'],
dest: 'build/<%= pkg.name %>.min.js'
}
},
jshint: {
options: {
jshintrc: true,
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'karma.conf.js',
'src/**/*.js',
'test/**/*.js'
],
options: {
force: true
}
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
// Default task(s).
grunt.registerTask('default', ['jshint:all', 'uglify', 'concat:prod']);
grunt.loadNpmTasks('grunt-contrib-concat');
};
And my bower.json looks like this:
{
"name": "angular-slider",
"version": "0.3.2",
"main": "./build/angular-slider.js",
"ignore": [
"**/.*",
"node_modules",
"components",
"lib",
"src",
"test",
".g*",
".editorconfig",
".jshintrc",
".travis.yml",
"Gruntfile.js",
"karma.conf.js",
"*.html"
],
"dependencies": {
"angular": "~1.2",
"angular-touch": "~1.2"
},
"devDependencies": {
"angular-mocks": "*",
"angular-scenario": "*"
},
"resolutions": {
"angular": "v1.2.16"
}
}
This usually appears if you don't have grunt installed. Also you should install bower if you don't have it.
Try to install grunt like so : npm install -g grunt-cli . Also you should run in you're project file npm install && bower install to download all the dependencies that you need in you're project. I hope it helped.
Make sure that you have 'serve' registeredTask in your gruntFile.js .
If it is there then probably grunt is not installed on your system. Install grunt-cli from npm and also the bower on your system. So that you have node_modules in your folder structure.
Use the following commands :
npm install -g grunt-cli
npm install --save
bower install --save
This should do the trick.
Just do
grunt
...on its own. This runs the 'default' task
We can see toward the bottom of your GruntFile.js that you have a definition of the 'default' task
grunt.registerTask('default', ['jshint:all', 'uglify', 'concat:prod']);
...which I think will be the one to start up the server
I had thought that "serve" was a standard task name (also with alias "server") but I'm seeing gruntfiles where these are not defined, and where the "default" (just the grunt command on its own) starts the server. Maybe this is a standard thing with Angular(?)

Using Grunt to preprocess and replace environment variables

I have an angular app setup that's using grunt, but I'd like to be able to use grunt as a preprocessor to replace variables and I haven't been able to find anything that matches my needs.
For instance, if I change the name of my main app module to "someAppName" in a config file, I'd like to just use something like "ENV.APP_NAME" in various html and js files and have that replaced by an appropriate value for that environment.
Ideally I'd like to have a config file somewhere along these lines, either as a .json file or using module.exports to expose an object, which specifies values for different environments:
{
APP_NAME:{
dev: "someAppDev",
prod: "someApp"
},
API_BASE:{
dev: "localhost:8000/",
prod: "https://www.some-site.com/api/"
}
}
and then I could create a grunt task and pass it either "dev" or "prod" to have it run the preprocessor and replace each instance with the corresponding value. I've found this https://github.com/STAH/grunt-preprocessor but the examples are confusing and I don't think it's quite what I'm looking for.
Is there anything like this that allows you to create preprocessed environment variables and read them from an external config file, or am I forced to build my own grunt plugin? Has anyone achieved something similar with grunt?
EDIT: I've begun building a grunt plugin for this specific task, once it's done and tested I'll post it up on npm
Use grunt-ng-constant.
Npm install this plugin:
npm install grunt-ng-constant --save-dev
Then in grunt write to config file:
ngconstant: {
// Options for all targets
options: {
space: ' ',
wrap: '"use strict";\n\n {%= __ngModule %}',
name: 'config',
},
// Environment targets
development: {
options: {
dest: '<%= yeoman.app %>/scripts/config.js'
},
constants: {
ENV: {
myvar1: 'Hello from devel',
myname: 'John Doe'
}
}
},
production: {
options: {
dest: '<%= yeoman.dist %>/scripts/config.js'
},
constants: {
ENV: {
myvar1: 'Hello',
myname: 'John Doe'
}
}
}
},
Then add to grunt task:
grunt.task.run([
'clean:server',
'ngconstant:development',
'connect:livereload',
'watch'
]);
Running task would generate config.js with constants defined in gruntfile.
Then add config.js to your index.html:
<script src="/scripts/config.js" />
Inject it to your app:
var app = angular.module('myApp', [ 'config' ]);
And inject into controller:
.controller('MainCtrl', function ($scope, $http, ENV) {
console.log(ENV.myvar1);
});
You can set different variables for production and different for development, by setting it in gruntfile and setting ng:production or ng:development.
Refer this article explaining the procedure for more information.
You could do something making use of grunt-string-replace while loading some config values into Grunt from a JSON file. Suppose you had this in myconfig.json:
{
"appName": "MyGrowth",
"version": "1.1.2",
}
Then perhaps load the config into Gruntfile.js from JSON with something like:
grunt.initConfig({
myConfig: grunt.file.readJSON('myconfig.json'),
// ... the rest of the stuff in your initConfig goes sure
}
Then you would have some sort of task like this maybe:
'string-replace': {
version: {
options: {
replacements: [
{
pattern: /MY_VERSION/ig,
replacement: '<%= myConfig.version %>'
}
]
},
files: [{
expand: true,
cwd: 'src/',
src: '**/*.js',
dest: 'dist/'
}]
}
}
That would make actual changes to the files if you had 'src' and 'dest' in the same folder, otherwise it would put the processed files in the dest folder.
I've not actually used this recipe for preprocessing, but I use it for other types of things like replacing tags in a framework with the app name as configured in package.json.
Hope it helps.
Alright I ended up building a grunt plugin just for this task because it's something that I really needed. It allows you to place environment variable definitions in a .json file like I described in my original question and replaces all instances in a specified file or list of files.
https://github.com/ejfrancis/grunt-envpreprocess
So if you have something like this
HTML
<head>
<title>ENV.APP_NAME</title>
</head>
<script src="ENV.API_BASE/user/create">
JS
var version = "ENV.APP_VERSION";
alert(version);
The task will replace it with this
HTML
<head>
<title>AppDev</title>
</head>
<script src="http://localhost:8000/user/create">
JS
var version = "0.1.0";
alert(version);

Grunt + Yeoman - How to stop rewrite linked JS files in index.html?

I have a Angular project which is build with Yeoman and Grunt. Everytime if I run command:
sudo grunt serve
Is app normally launched but in index.html are deleted some linked libraries from bower_components directory.
FXP:
<script src="bower_components/spin.js/spin.js"></script>
So I must everytime revert changes in index.html file in git before I can continue in testing.
Is any possibility how can i solve this annoying problem?
Thanks for any help.
EDIT:
I tried following:
Installed:
npm install grunt-script-inject
GrunFile.js
// Automatically inject Bower components into the app
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: new RegExp('^<%= yeoman.app %>/|../')
},
scriptinject: {
dev: {
srcs: ['<%= yeoman.client %>/bower_components/path/to/src/plugin.js',
'<%= yeoman.client %>/bower_components/path/to/src/plugin2.js'] ,//order is important if this sciprt will be concated and minified
html: '<%= yeoman.client %>/index.html', //file that as the block comment to look for a place to insert the script tags
without: '<%= yeoman.client %>/' //this script will be used to remove this block of string of script tag file location
}
}
},
And
grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'wiredep',
'scripinject',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});
But now, after the grunt serve i see following error:
Running "serve" task
Warning: Task "scripinject" not found. Use --force to continue.
Aborted due to warnings.
What is wrong?
I resolved using the --s in bower install command
So:
bower install --save angular-translate
Works fine.
Here is documentation:
http://bower.io/docs/api/#install
I had a similar problem.
In index.html I added the following code:
<script src="bower_components/highcharts-release/highcharts.js"></script>
<script src="bower_components/highcharts-release/modules/heatmap.js"></script>
and every time I ran grunt serve or grunt build commands, grunt rewrote it to:
<script src="bower_components/highcharts-release/highcharts.js"></script>
<script src="bower_components/highcharts-release/highcharts-more.js"></script>
<script src="bower_components/highcharts-release/modules/exporting.js"></script>
So I looked into bower_components/highcharts-release/bower.json file and saw:
{
"name": "highcharts",
"version": "v4.1.4",
"main": [
"highcharts.js",
"highcharts-more.js",
"modules/exporting.js"
]
}
I changed it to:
{
"name": "highcharts",
"version": "v4.1.4",
"main": [
"highcharts.js",
"modules/heatmap.js"
]
}
and everything is fine now. Hope it will help someone, even this is a quite late answer.

Is there a way to automatically generate karma.conf.js with a grunt task?

I've been using a modified version of the gruntfile that comes with the Yeoman.io base angularjs generator, and the grunt-bower-install command is kind of handy for keeping my base index.html file up-to-date with bower dependencies.
However, when I do a bower install (package) --save and then grunt bower-install, my index.html updates, but my karma.conf.js does not update, meaning I need to manually add the new file to the list of files to load when karma runs the test suite (otherwise the injector fails trying to inject a nonexistent package).
Is there any easy-peasy way to add this to my grunt workflow? It's not the end of the world, but it is one of those easy-to-forget things.
I actually came up with a solution for just this problem. Check out https://github.com/stephenplusplus/grunt-bower-install/issues/35#issuecomment-32084805
'bower-install': {
app: {
src: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
},
test: {
src: 'karma.conf.js',
fileTypes: {
js: {
block: /(([\s\t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
detect: {
js: /'.*\.js'/gi
},
replace: {
js: '\'{{filePath}}\','
}
}
}
}
}

Resources