How to handle javascript library version changes with grunt-bower-task? - gruntjs

I'm using grunt + bower + grunt-bower-task plugin to manage javascript library dependencies.
Say I have installed jquery with bower:
bower install jquery --save
and with grunt-bower-task:
bower: {
install: {
options: {
targetDir: './public/lib',
layout: 'byComponent',
install: true,
verbose: true,
cleanTargetDir: true,
cleanBowerDir: false,
bowerOptions: {}
}
}
}
After running grunt bower, jquery will be copied to:
/public/lib/jquery/jquery.js
So the client will fetch jquery with url:
http://somedomain.com/public/lib/jquery/jquery.js
But I have question, what if I changed the jquery version?
Say I used another query version with bower, but it will still be copied to the same location and user will fetch it with the same url. If I have add cache-headers for it, user won't fetch new jquery.js code from server before expired.
How to fix this problem?
I think if we can add the version to the file name when running grunt bower, that will fix it, e.g.
http://somedomain.com/public/lib/jquery/jquery-1.8.js
But I can't find such functions in grunt-bower-task.

I would handle library versioning in the bower.json file. Yours should have the versions to be installed whenever you call the bower install command.. something like this
"dependencies": {
"angular": "~1.2.21",
"jquery": ">=2.1.1"
},
"resolutions": {
"jquery": ">=2.1.1"
}
But now they're all jquery.js regardless of the version. So now what you'd want to do is add some type of cache busting strategy which will force the browser to download the newest version of your scripts. There's tons of resource on cache busting javascript online, so I won't reiterate those here, but there are grunt tasks that can help you like this one
One slightly off topic suggestion I would make is to concat and minify your externals scripts into one js file and maybe another for your application scripts. As one or more of your external library change, the cache busting technique will force the browser to grab the latest version of your dependent scripts.

Related

How to load specific moment locales with browserify

I have an angular application built in Visual Studio 2017. I'm using npm, gulp, and browserify to help me manage dependencies, bundling, and minification. Everything had been going along well until I tried to pull in moment, moment-timezone, and angular-moment, when I started having trouble getting these libraries to play nice.
I'm assuming that the issue is related to the way these libraries are being included in my application due to some mistake or bug with the way I'm using npm, gulp, browserify, or the require('...') statements. So, it seems like it'd be helpful for me to explain how I'm doing that.
First, in VS, I added a node configuration file to the project (package.json) and it contains a list of all of my dependencies that will be installed through npm. So, for example, my package.json looks something like this:
{
"property": value,
"otherProperty": otherValue,
"dependencies": {
"angular": "1.5.8",
"angular-ui-router": "1.0.3",
"jquery": "3.1.0",
"moment": "2.18.1",
"moment-timezone": "0.5.13",
"angular-moment": "1.0.1"
}
}
Now, that makes npm go ahead and download everything and stick it in my node_modules folder, but it doesn't actually include anything in my application. So there's a gulp task similar to the following:
var dependencies = Object.keys(packageJson && packageJson.dependencies || {});
browserify({cache: {}, packageCache: {} }})
.require(dependencies)
.bundle()
.pipe(source(js/siteLibs.js))
.pipe(buffer())
.pipe(gulp.dest("."));
Ok, so if that gulp task works correctly, I'll have a file called siteLibs.js that contains all of the js from my npm dependencies, and then I can just make a single script tag to reference siteLibs.js.
The next part, I'm a little hazy on, but do I still have to have an actual require('...') statement in my app for moment, angular-moment, and moment-timezone? If it is required, why? What is it doing?
Now, once at this point, I should be able to go ahead and let my angular app take a dependency on moment, moment-timezone, or angular-moment, and, indeed I can. The issue is that when I call moment.locales(), which is supposed to return a list of all loaded locales, it has naught but 'en-US'. Ok, that's expected because I never loaded any locales. So if I go in my app and say:
require('moment/locales/en-gb');
require('moment/locales/en-au');
require('moment/locales/fr-ca');
It makes no difference. The only loaded locale is en-US. What is the right way to go about getting those additional locales loaded given that I'm using npm, gulp, and browserify?
Refer to this in moment's documentation
https://momentjs.com/docs/#/use-it/browserify/

Is it possible to update bower dependencies using grunt?

I’m using grunt to develop a website, and was wondering if it’s possible to update bower dependencies in my project within my 'build' grunt task—so that when I build a production version of my project, everything is up–to–date?
Obviously, I know I could just execute bower update before grunt build:prod, but it would be one less step every time.
Just curious!
Grunt has this task called grunt-bower-task which can help you manage bower dependencies. Use the official grunt documentation to go through the details.
Found one possible solution:
I guess I could use grunt-shell to automate running the bower update command in a shell…
Just wondering if this is the most logical/sophisticated way of doing it. Any other suggestions?
Found a good solution—I’ll post it in case it’s of use to someone…
The grunt-bower-install-simple plugin allows you to update bower dependencies from a grunt task by setting the command option to update like so:
"bower-install-simple": {
options: {
color: true,
directory: "src/bower_components"
}
"prod": {
options: {
command: update,
production: true
}
}

How can I properly config the uncss in grunt?

I've tried to configure uncss using grunt
I've installed
npm install grunt-uncss --save-dev
npm install grunt-processhtml --save-dev
Configuration
uncss: {
dist: {
files: { 'dist/css/clean.css': ['index.php'] }
}
}
at the end I load them in and register a default task like this :
grunt.loadNpmTasks('grunt-uncss');
grunt.loadNpmTasks('grunt-processhtml');
grunt.registerTask('default', ['uncss', 'processhtml']);
Result
When I run grunt
at the end I keep seeing :
Running "uncss:dist" (uncss) task
Fatal error: PhantomJS: Cannot open about:blank
Update
I added :
processhtml: {
dist: {
files: {
'index.php': ['index.php']
}
}
}
Still get the same error after running grunt
If this is all of your code, you are not referencing any stylesheets to remove code from. All you are doing is telling grunt where the cleaner file should go, and to remove any unused css from index.php. However, it doesn't know where the styles for index.php live, so it has nothing to do... You need to actually configure your processhtml and tell uncss which stylesheets you would like to clean up.
Read the directions friend:
grunt-uncss github readme.md
I have that problem with my project and the solution is here:
You need update the uncss module, remember grunt-uncss is only a way to use uncss node package. In my case my version of that was in 0.12.1 and updating that package the problem was fixed. Let me know if this help you.

How can I install custom fonts using Bower? (not Font Awesome)

I'm using Bower, and already installed Font Awesome with it, but now I'm wondering if I can install a custom font (to be more specific: Raleway and Montserrat) using Bower. Can I do that?
I did some research but I didn't find any solution! If it is possible, please tell me how.
The best solution I found with Bower was the Google Fonts Bower Proxy (source on Github). You will have to first get the query string by going to Google fonts.
<link href='http://fonts.googleapis.com/css**?family=fontname:size**' rel='stylesheet' type='text/css'>
Then using Bower:
bower install --save https://google-fonts.azurewebsites.net/googleFonts/yourPackageName?family=fontname:size
Depending on the requirement, it may be actually easier to simply import the font to your CSS or SASS instead of going for the bower based solution.
There is also a google fonts bower package which includes all fonts.
Raleway is included in the bower package TypoPRO.
Install it with
bower install --save typopro
As you are new to bower, here some further tips:
As the bower_components directory is usually excluded from version control, you can copy the files you need to another directory with a grunt task.
Add a exportsOverride section to bower.json:
{
(…)
"dependencies": {
"typopro": …
},
"exportsOverride": {
"typopro": {
"fonts": "web/TypoPRO-Raleway/*"
}
}
(…)
}
Install grunt
$ npm install -g grunt-cli
$ npm install --save-dev grunt
$ npm install --save-dev grunt-bower-task
and create Gruntfile.js:
module.exports = function(grunt) {
var path = require('path');
grunt.initConfig({
bower: {
install: {
options: {
targetDir: 'vendor',
cleanTargetDir: true,
layout: function(type, component, source) {
return type;
}
}
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-bower-task');
// Default task.
grunt.registerTask('default', ['bower:install']);
};
The grunt task bower:install will run bower install and copy all files from web/TypoPRO-Raleway to vendor/fonts (vendor from targetDir in Gruntfile.js and fonts from exportsOverride in bower.json). You can execute the task with
$ grunt bower:install
As bower:install is registered as a default task, you can also use the short cut:
$ grunt
What you could do, instead of managing it with bower, is add in google code directly into your CSS or SCSS #import url(http://fonts.googleapis.com/css?family=Raleway) or manually add the font by first downloading the font then adding the relative path into your css.
You can download raleway here http://www.google.com/fonts#UsePlace:use/Collection:Raleway, clicking on the down arrow on the top right of the page, unzipping and add the fonts to your site.
Another solution would be to use grunt instead of bower to manage your fonts. I found two grunt plugins which download fonts from Google for you.
grunt-local-googlefont and grunt-goog-webfont-dl. You can install them via npm.
There are lots of different plugins to download fonts from other sources. Just search for font at grunt's plugin search.

How to update and include Twitter Bootstrap 3 on webapp or yo angular?

I used yo webapp or yo angular to create new a project, and I received Bootstrap include is version 2.3.2, but I want use the latest version of Bootstrap.
How can I update the Bootstrap package with command prompt and later update when create new webapp or yo angular, choose include Twitter Bootstrap is last version?
Yeoman's webapp & angular generators grab Sass for Bootstrap, which is based on the 2.3.2 build of Twitter Bootstrap.
After you run yo webapp or yo angular, you can add Bootstrap 3.0 by running the following command.
$ bower install --save bootstrap
This will download Bootstrap 3.0 for you.
#micjamking answer is a really good hint, but since with Yeoman things should be easier, I'll save you some googling:
yo angular - Say 'No' to Bootstrap here - otherwise it'll download 2.x version
bower install --save bootstrap
npm install --save-dev grunt-bower-install
edit Gruntfile.js - insert marked lines:
// ...
} catch (e) {}
grunt.loadNpmTasks('grunt-bower-install'); // INSERT
grunt.initConfig({
yeoman: yeomanConfig,
'bower-install': { // INSERT BEGIN
target: { // .
html: '<%= yeoman.app %>/index.html', // .
ignorePath: '<%= yeoman.app %>/' // .
} // .
}, // INSERT END
watch: {
coffee: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
tasks: ['coffee:dist']
// ...
edit app/index.html - insert :
<!-- bower:css -->
<!-- endbower -->
and:
<!-- bower:js -->
<!-- endbower -->
where appropriate - those will inject references to bower-managed resources (bootstrap's stylesheet and JS in our case).
update 10/5/2013: Consider placing bower:xxx inside build:xxx.
In our case, bower:css inside build:css and bower:js inside build:js.
This is needed for minification to work when assembling dist. However I consider this approach not so perfect - see Remarks below. I'm excused a little bit, since this is the very same way the bootstrap version obtained by Yeoman by default gets included in our app :-P
Note: To get css minification working you might need changing build:css(.tmp) to build:css({.tmp,app}).
grunt bower-install
Ready. Now run server (grunt server) and Bootstrap 3 will be available.
Remarks - Update 10/5/2013 - inspired by #Luke's enquiry in a comment:
Based on this I added one sub-step to make dist minification work.
Bower's injecting works, so does minifying, however I'm not so happy with this approach.
Reasons:
[minor] We're not using already minified resources obtained by bower.
Minifying ALL kinds of CSS/JS into a SINGLE file is a pretty lame idea. A better way to include external dependencies in your application would be to have a switch between CDN-fetch (dist) and local copies obtained with bower (dev). Sth like maven profiles.
Depending on the application size, downloading all-in-one resources, particularly JavaScripts, will slow down first encounter with our application.
Later on the rest of the application will be loaded faster, true, but the first time user enters our page, those bulky single-filers will have to be downloaded preemptively.
#yao tony also hadn't found this approach cool - see the referenced question.
Update Nov 2013: You can use grunt's cdnify task. It's cool
Software versions I was using:
user#machine:~/somewhere $ yo -v; grunt --version; bower -v
1.0.4
grunt-cli v0.1.9
grunt v0.4.1
1.2.6
For sass Bootstrap update:
This Works for me:
bower install angular-bootstrap
bower install sass-bootstrap
and select the new versions of both...
maybe should add a --save
Note: sass-bootstrap is bean deprecated, is now a official bower for sass version of bootstrap https://github.com/twbs/bootstrap-sass but i dont tried it.

Resources