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

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.

Related

Does grunt-usemin contain concat, uglify, cssmin?

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

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 build not working in Yo Angular

I build a Angular App with Yo angular-genertor,
I was building the app with Grunt Build fine, then I added Bootstrap 3 and also npm install grunt-bower-install
I added these lines to the Grunt file
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
//ADDED THIS LINE
grunt.loadNpmTasks('grunt-bower-install');
grunt.initConfig({
yeoman: {
// configurable paths
app: require('./bower.json').appPath || 'app',
dist: 'dist'
},
//ADDED THESE LINES
'bower-install': {
target: {
src: [
'app/index.html'
],
}
},
I have removed these line however!
Now Grunt Build is throwing this error
Running "bowerInstall:app" (bowerInstall) task
Warning: Cannot read property 'main' of undefined Use --force to continue.
Aborted due to warnings.
I do know what to do or even where to start?
In my yeoman generated project this task looks like:
'bower-install': {
app: {
html: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
}
},
In newer version instead of html uses src:
'bowerInstall': {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: '<%= yeoman.app %>/'
}
},
Maybe you adapt it to your case. Though i think it should work without changes.
But you have almost the same, so maybe the problem in another place.
I found the answer,
I simply needed to run Bower Install,

Glyphicons not appearing after running grunt in angular generator

When you run grunt to build the app, the vendor.css file created in the dist folder 'mis-links' the glyphicons as /app/bower_componenets/.../glyphicons-... instead of ../fonts/glyphicons-...
In Gruntfile.js comment out the following line to fix this issue:
cssmin: {
options: {
//root: '<%= yeoman.app %>'
}
}
Source: https://github.com/yeoman/generator-angular/issues/645

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