Taking a variable value at runtime in Grunt-Concat task - gruntjs

I have implemented below Grunt configuration for concating two css files into a single css file(common_tfn_bsa.min.css ) in my jsp file.
<!-- build:css ./assets/css/common_tfn_bsa.min.css -->
<link href="./${theme}/css/style.css" rel="stylesheet">
<link href="./${theme}/css/component.css" rel="stylesheet">
<!-- endbuild -->
But while running Grunt task above code is generated as :
concat:
{ generated:
{ files:
[ { dest: '.tmp\\concat\\assets\\css\\common_bom.min.css',
src:
[ '.\\app\\${theme}\\css\\style.css',
'.\\app\\${theme}\\css\\component.css' ] }
]
}
}
What I need is ,the value of ${theme} in generated file so that it can pick the css files from correct location for concat.

Try this:
<!-- build:css(./<%= theme %>) ./assets/css/common_tfn_bsa.min.css -->
<link href="/css/style.css" rel="stylesheet">
<link href="/css/component.css" rel="stylesheet">
<!-- endbuild -->

Related

grunt-injector: Inject bootstrap bower component to index.html

I have done my research with grunt-injector. However, I have not found anything explains simply enough the process of injecting some file to another by grunt-injector.
My index.html header:
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>SmartHome</title>
<meta name="description" content=""/>
<meta name="author" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- build:css(client) styles/global.css -->
<!-- bower:css -->
<link rel="stylesheet" href="/bower_components/normalize.css/normalize.css" />
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="/bower_components/nouislider/distribute/nouislider.min.css" />
<!-- endbower -->
<!-- endbuild -->
Everytime I run grunt serve, it would delete the
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
I have no idea why. My bower.json has included bootstrap ~3.3.4 as a dependency. I've tried numerous methods with bower install --dev etc... But no luck to get this link back.
So I think my last resort would be to use the grunt-injector function. Can anyone gives me a hint with the syntax needed ? My files structure:
/client/
---bower_components/
(somemore folders)
---bootstrap.css
index.html
For this task you can use: https://github.com/taptapship/wiredep
Example:
wiredep: {
task: {
// Point to the files that should be updated when
// you run `grunt wiredep`
src: [
'src/main/resources/view.html'
],
options: {
// See wiredep's configuration documentation for the options
// you may pass:
// https://github.com/taptapship/wiredep#configuration
}
}
}
injector: {
options: {
// Task-specific options go here.
},
bower_dependencies: {
files: {
'index.html': ['bower.json'],
}
}
}

How to concat certain js files

I have the need to just concat certain 'vendor' JS files. My users won't always have access to the internet and I need to concat already minified JS files.
I have this index.html:
<!-- build:js vendor.min.js -->
<script type="text/javascript" src="bower_components/jquery/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/underscore/underscore.min.js"></script>
...
<!-- endbuild -->
<!-- build:js app.min.js -->
<script type="text/javascript" src="app/app.js"></script>
...
<!-- endbuild -->
I just want to concat the first group of files. Reason being is that some are already minified and some are not. The vendor files that are not minified cannot be minified.
Is there a way to run usemin to just concat the first group into a vendor.js file and concat and uglify the second group into an app.min.js file?
You should use flow option to define your custom workflow.
For example, if you need to only concat a group of files, add this to the useminPrepare:
useminPrepare: {
html: 'index.html',
options: {
flow: {
html: {
steps: {
onlyconcat: ['concat']
},
post: {}
}
}
}
}
In your index.html, change this:
<!-- build:onlyconcat vendor.min.js -->
<script type="text/javascript" src="bower_components/jquery/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/underscore/underscore.min.js"></script>
...
<!-- endbuild -->

Combine and minify all bower libraries with gruntjs

Is there a way to combine and minify all bower installed libraries into 1 file automatically?
First I tried the most basic approach: combine all .js files from all subdirectories:
uglify: {
options: {compress: true},
my_target: { files: {
'vendor.js': ['bower_components/**/*.js'],
} } }
But this is obviously a bad approach. It also doesn't work because of too many errors.
I manually deleted all the files and kept only 1 (main) file that each library has, and it worked.
Is there a way to do this all automatically?
Also, is it advisable to do it? (i.e. combine all vendor libraries into 1 file)
I recommend the combination of 2 nice grunt libraries, Wiredep and Usemin:
Wiredep: Load all dependencies of bower identified in bower.json inside your html automatically
Usemin: Detect all src inside two comments tags and all that source are minified and concatenated in dist folder, below are a little example of a grunt files using this packages, is based on the generator of angular to yeoman this is only a brief of that grunt
Grunt
wiredep: {
options: {
cwd: 'appFolder'
},
app: {
src: ['htmlCollections'],
ignorePath: /\.\.\//
}
},
useminPrepare: {
html: 'htmlCollections',
options: {
dest: 'distributionFolder',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
usemin: {
html: ['distributionFolder+HtmlFiles'],
css: ['distributionFolder+cssFiles'],
js: ['distributionFolder+javascriptFiles']
}
HTML
<!doctype html>
<html lang="en" ng-app="MobileDev" id="ng-app">
<head>
<!-- build:css(app) styles/vendor.css -->
<!-- bower:css -->
//This gonna be generated for the grunt by dependencies in bower
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/main.css -->
//All the script inside this gonna be concatened and minified in
//the dist folder by the name of main.css
<link type="text/css" rel="stylesheet" href="styles/app.css"/>
<!-- endbuild -->
</head>
<body>
<!-- build:js(app) scripts/vendor.js -->
<!-- bower:js -->
//This gonna be generated for the grunt by dependencies in bower
//And in distribution all bower components added gonna be minified by usemin in
//vendor.js
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/scripts.js -->
//All the script inside this gonna be concatened and minified in the dist
//folder by the name of scripts.js
<script type="text/javascript" src="scripts/numero1"></script>
<script type="text/javascript" src="scripts/numero2"></script>
<!-- endbuild -->
</body>
Just needed wiredep
uglify: {
options: { compress: true },
my_target: {
files: { 'public/vendor.js': require('wiredep')().js
} } },
cssmin: {
minify: {
files: { 'public/vendor.css': require('wiredep')().css
} } },

grunt: cdnify doesn't do anything

I have created an AngularJS application using Yeoman. It also uses the cdnify task that shoud transform bower_components/angular/angular.js into //ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js. The generated index.html contains the following code:
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js"></script>
<!-- endbower -->
<!-- endbuild -->
There is also a task that combines, minifies and uglifies all the scripts, so these scripts are combined into a single vendor.js file. To avoid jquery.js and angular.js to be included in this process, I changed it into:
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js"></script>
<!-- endbower -->
<!-- endbuild -->
When I run grunt serve:dist the cdnify task is ran and generates the following output:
Running "cdnify:dist" (cdnify) task
Going through dist/404.html, dist/index.html to update script refs
My bower.json looks like this:
{
"name": "myAmazingAngularApp",
"version": "0.0.0",
"dependencies": {
"jquery": "~1.11.0",
"angular": "1.2.x",
"bootstrap": "~3.1.1",
"angular-bootstrap": "~0.10.0"
}
}
Does anyone know what I am doing wrong? I would think it should work out-of-the-box, so I suspect it's a bug...
There is also a .bowerrc file that has the following content:
{
"directory": "app/bower_components"
}
I tried changing this setting to "directory: bower_components" when running grunt cdnify, but it doesn't help.

how to handle absolute url to css with grunt-usemin

I am using grunt-usemin to build an app project
css are linked with absolute paths:
<!-- build:css(.) /app/css/libs.css -->
<link rel="stylesheet" href="/app-dev/lib/css/style.css"/>
<link rel="stylesheet" href="/app-dev/lib/css/another.css">
<!-- endbuild -->
javascript files are linked with relative paths:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<!-- endbuild -->
the grunt config:
useminPrepare: {
html: 'app-dev/index.html',
options: {
dest: 'app'
}
},
usemin: {
html: ['app/{,*/}*.html'],
css: ['app/css/{,*/}*.css'],
options: {
assetsDirs: ['app']
}
}
The problem is there is one spare subfolder level in the css output:
app
- app
- - css
- - - libs.css
- js
- - app.js
- etc
while the reference in the outputed html file is correct
<link rel="stylesheet" href="/app/css/libs.css">
How to output the css to the correct folder hierarchy?
Try removing the / in front of your build path
<!-- build:css app/css/libs.css -->
<link rel="stylesheet" href="/app-dev/lib/css/style.css"/>
<link rel="stylesheet" href="/app-dev/lib/css/another.css">
<!-- endbuild -->
The HTML file should be under "app" folder as well, so you can remove "/app-dev".

Resources