Let's continue our grunting.
As we did in the second part of the NPM scripts exercise,
in this second part of that grunt exercise,
we're going to configure exactly the same tasks.
We're going to do cleaning up the distribution folder,
copying the fonts to the distribution folder,
then we will also do the minification of our images using imagemin,
and then finally use the usemin task to build and prepare our distribution folder.
Continuing with our exercise,
I will install a couple of grunt modules.
So, let's install NPM, install-grunt-contrib-copy.
This is used for copying the files and then grunt-contrib-clean,
and minus minus save-dev.
And once these two are installed,
then we'll go ahead and config the corresponding tasks.
Going to your grunt file,
we'll add in the configuration for both the copy and the clean tasks.
So, starting with the comma,
always remember not to forget the comma.
It'll come back to bite you at the wrong moments if you do that.
So let's set up the copy task.
For the copy, usemin expects us to also keep
our HTML files copied to the distribution folder
so that it can do the manipulation on that.
So, in this case,
we're going to first copy
the HTML files from our project folder to the distribution folder.
So, to do the copying,
I'm going to set up the HTML part of it.
So, this is where we will use some of
the grunt syntax for specifying the files that need to be copied.
So, I say files and also specify the right,
left and right braces there so within this,
I need to specify now certain configuration.
So, I would say, expand true and dot true, then CWD,
the current working directory is dot slash,
and then after that,
we'll configure the next one which is SRC, the source files,
and then the source files are star.html,
all the HTML files,
and then we are going to copy them to the dist folder.
So that's why the destination is set to the distribution folder here.
So, with this set up,
my copy task will copy all the HTML files to the distribution folder.
Now along with that, we also need to copy the fonts.
So, I will set up the second one for the fonts.
So, I specify fonts and then in here also I need to specify
the files that need to be copied and so we say files,
and then these are
some configuration parameters that you need to set up for the copy task.
Now, if you need to understand,
then by reading the documentation for the corresponding grunt plugin,
you'll be able to figure this out and so or you can
just simply follow the example that I am giving here.
So, dot true, and then CWD,
the current working directory is node modules and font awesome.
So that is where I'm going to copy the files from,
and then the source of the files is the fontsstar.star,
those are the files that I need to copy,
and the destination is the distribution folder.
So with this, I have set up my copy task to copy
both the HTML files and the fonts files into my distribution folder.
Now, the next task that I'm going to set up is the clean task.
So, let me configure the clean task.
For the clean task, I will configure the build,
and then I will say the source is the distribution folder.
So, essentially specifying that the distribution folder should be cleaned up.
So, now we have set up the copy and the clean tasks so let's save the changes.
The next task that I'm going to set up is the imagemin task.
This is what we will use to compress and copy the images into the distribution folder.
To get started with the imagemin task, the first step,
install the corresponding grunt plugin.
So, grunt-contrib-imagemin, minus minus save.dev.
And once that is installed,
then we'll go ahead and configure the corresponding imagemin task.
Going to our grunt file after the configuration for the clean task,
I'm going to configure the imagemin task.
So, I will say imagemin,
and then right in there,
I will specify dynamic,
and inside there I will specify the files so you can
see that the file specification would be similar.
I'd say, expand true,
then CWD is the current directory.
Then the source of the files is imagestar.
and then within brackets, within braces,
I specify PNG, GIF, and JPG.
So essentially, you can see the file global pattern here.
So it says any PNG, GIF,
or JPG files that matches this pattern and then
start dot meaning all the files of that pattern,
and source, and the destination,
I set as the distribution folder.
So with this, we have configured our copy,
clean and imagemin task.
Let's configure a task here called build.
So, I would say, register task,
grunt register task and then I will name the task as build,
and then inside this,
we will specify the set up steps to be done by the build task.
So, right there, semicolon and then in there,
I will specify the three tasks in the sequence that they should be performed.
First, I will say, clean.
So, we will clean up the distribution folder
and then start rebuilding the distribution folder.
Clean, then the next task would be
copy and then after that I would do, imagemin.
So these three tasks to be configured here.
So with this, let me save the changes.
Let's see how this thing works.
Now, going to the prompt if I type,
grunt and build, you will see that it will first do the clean,
then to do the copy and do the imagemin task.
So, it does all these three and then you would immediately see that
the distribution folder is built up in my project folder here.
And inside the distribution folder you can see that the fonts have been copied,
the images have been copied and
the three HTML files have been copied to the distribution folder.
You're only halfway there.
Now, we need to be able to process these files using the usemin plugin.
So, let's go to that next.
Now, I'm going to install a few NPM modules
that are useful for building the distribution folder.
So, to do that, I would say NPM install.
I can specify a set of modules here so,
I would say, grunt-contrib-concat.
So, this a used for concatenating files, then grunt-contrib-cssmin,
grunt-contrib-htmlmin, then say, grunt-contrib-uglify.
Then grunt-filerev.
You'll see the reason for using filerev in a short while,
and then grunt-usemin, and save def and then,
install all this grunt modules.
Once all of them have been installed,
the next step is to go and configure,
usemin task which also uses
the cssmin Uglify Concat tasks to accomplish the building of the distribution folder.
Now, lets proceed ahead configuring the usemin task.
So going back to the grunt file after imagemin,
I'm going to add in the next task for usemin to work with the grunt.
The first task that I need to configure is called useminPrepare.
This useminPrepare task will prepare the files and then also configure
the ConCache CSS min and Uglify and file ref plugins,
so that they can do their work correctly.
So, that's the reason for the useminPrepare.
So, this is how the grant usemin plugin has been designed.
Somewhat different from the way the usemin that we used with the end game scripts wooks.
So, in the useminPrepare,
just some random name that I'm going to use and then say destination is dist.
And then I would specify the source as all the html files here.
So I would say contactus.html,
aboutus.html, and index.html.
So, all these three files need to be processed.
The next part of this usemin configuration,
useminPrepare configuration is where I specify the options.
This is something I have figured out by trial and error.
Just follow along the steps.
So I need to configure
a few things here inside where I need to configure something called Flow.
And then inside there I need to configure another part called Steps,
and then here I specify the steps here and then say cssmin,
and then after that I will say js is uglify.
So, this is something that I need to specify here and then after this I say post,
and here I can allow this to supply
some options for their specific tasks that I have configured.
So, I am supplying some additional options for css.
So, that is supplied inside of the post here.
Now again, this is how the configuration has to be done.
So, we just learned it by looking at the documentation there.
So, in here inside the post css,
I would specify a name as cssmin.
So far this here is cssmin task.
I would say createConfig:
function context block, and then inside those function
I have to supply certain parameters.
So, I would say var
generated context options generator.
So this is some JavaScript variable that I need to
specify there, JavaScript object essentially.
So, this object contains this property called options,
where I can specify some options which are passed
into the CSS min tasked by the usemin prepare task.
So, in there, keep
special comments and then,
rebase is false.
Apparently I need to supply this in order for my cssmin task to currently handle
the font awesome modification and inclusion in the concatenated file.
If I don't do this,
it seems to break the font awesome and this is something that I figured out,
by doing a little bit of
research on stack overflow and some of these places and figured out
that their problem that is being caused with font awesome can be
fixed by including this into my grunt configuration.
So, again I have just looked up
the suggestions from some people that have tried and to fix the problem.
So, if you run into problems like this,
this is one way of solving issues that might arise when you're
working with these various tools.
Let me add in the next task for Concat.
I will specify some things here and options.
I specify this semicolon,
so this is something that I need to specify for the Concat,
and then also after
options I specify dist as empty.
Now this Concat options will be configured by the useminPrepare that runs earlier.
So we can leave most of it blank there,
and then that would be reconfigured by the useminPrepare.
The next one is uglify.
Inside uglify also I just need to specify this dist as empty.
If I don't specify these,
then the usemin task doesn't work correctly.
So, that's why I need to specify all of these things explicitly.
So for cssmin also I would say dist empty.
And then, the next task that I'm going to configure is called filerev.
So, you saw me installing the filerev plugin for Grunt.
What does this filerev do?
What the filerev does is when usemin prepares the main.css and main.js file,
what filerev does is it adds an additional extension to that main name,
so that when you prepare a new version of your website and upload it to the web page,
in case somebody has seen your Website earlier,
then their browser might have cashed the main.css and main.js files.
If you don't attach this filerev what happens is that,
the browser beneath downloads the new version of your web page.
It may not download the main.js and main.css file
because it finds them already in it's local cache.
So, your web page may not be rendered correctly.
So, to deal with the problem,
what we do is every time we prepare a new distribution folder,
we will add a file revision.
That's what the filerev stands for,
the file revision number,
as a additional extension to the name of those css and js file.
The main.ss and main.js files the pre-prepared.
So that's what the filerev does.
Now how does this filerev can compute this value?
It takes the contents of these files and then does some processing and then generates
an md5 compressed 20 characters number which will be attached to the main file.
So, I'm going to configure that part here.
So, in the options,
I specify here saying how it is supposed to compute this number there.
So, I say encoding utf8,
and then I say algorithm that it used to compute this hash,
what we call as the hash is md5.
Now, it'll become more clearer when we actually run
the usemin task and then see what it does, length 20.
So, I will come back and explain what this thing
does when we actually run the usemin task.
So, let me finish the options here and then I would say release.
So, I need to set up a few more things here and then release,
and then I need to specify the files for which my filerev should act.
So, I would say filerev files.
So, inside here file.
So, you're beginning to see a pattern in the way things are specified here.
So, when you specify the files here,
you will say the source,
and then in there you will specify dist CSS
and then star dot CSS,
and then the next one dist js*.js.
So, with this, you have configured the filerev.
So, the filerev part is configured.
And finally, we need to configure the usemin task.
So, to configure the usemin task,
I go down here and say usemin,
and in here let me specify some options for the usemin task.
So, here I specify html.
So, here I am specifying to it which files it needs to change,
it needs to update.
So, the files that have been copied to the distribution folder.
And the last one is "dist/index.html."
So these are the three files that it is supposed to process,
and then some options for this here.
So, the options I will specify "assetsDirs."
So, this is where all the assets that I'm using exist.
So, the CSS and the JavaScript files exist.
So, I'll specify "dist/css" and "dist/js."
With this, you have completed configuring the "usemin" task.
Next, we configure the "htmlmin" task.
For the "htmlmin" task,
we specified the target which is "dist", the distribution folder,
and the "htmlmin" to be performed on
all the HTML files that are in that distribution folder.
The options that we specify for this state that, we'll say,
"collapsedWhitespace: True" meaning that
all the white space in the HTML files would all be collapsed,
such that the [inaudible] contain only the minimum HTML code there.
The modification essentially removes
all the extraneous characters from the "htmlmin" files.
Now, we also specify that dictionary of files,
those files that need to be configured.
This is specified as destination, colon, source.
So, we specify "dist/index.html" : "dist/index.html",
meaning that the "index.html" in the distribution folder
will be [inaudible] and then put back into the "index.html" file,
also in the distribution folder.
Similarly, the "contactus.html" specified there and then the
"aboutus.html" also specified as shown in that list of files.
The reason why we perform "htmlmin" after we finish "usemin"
is because "usemin" will replace all the scripts
with the main ".js" file and also all that CSS
code concatenated and combined and replaced with the main ".css" file.
So the "htmlmin" will be performed on
the resulting HTML files after "usemin" has completed its work.
This is how this works in Grunt.
So the Grunt "htmlmin" has to be applied after the "usemin" has completed its work.
So once all these are configured,
then one little step that I need to do is to go back up here,
and then where we specify for the "jit-grunt",
we need to specify that this "jit-grunt",
you recall that we introduced something called the
"useminPrepare" [inaudible] so you need to inform the "jit-grunt"
saying that the "useminPrepare" configuration that we introduced is going to be
handled by that "grunt-usemin" plugin itself.
So I need to explicitly specify,
otherwise "jit-grunt" is going to look around for a "useminPrepare" Grunt plugin.
So to specify to that,
I would say "useminPrepare" and say "grunt-usemin",
essentially informing "jit-grunt" saying the "useminPrepare" is going to be
handled by the "grunt-usemin" plugin there.
Finally, let's reconfigure the "build" task at the bottom.
Going down to that "build" task after "imagemin."
So we did "clean", "copy", "imagemin",
then the next task that I should execute is "useminPrepare" and then after
"useminPrepare" execute "contact," then I execute "cssmin",
then I execute "uglify."
So you see that we have to do them in a certain set of steps.
Once the "cssmin" and "uglify" run,
then the main ".css" and the main ".js" files would be created.
So at this point, I'm going to run the
"filerev" and then finally I run the "usemin" task.
So you see the secrets: "clean", "copy",
"imagemin", "useminPrepare", "concat", "cssmin", "uglify."
At this point, the ".css" and ".js" files,
the main ".css" and main ".js" files are ready.
I can do the "filerev" on them and then finally run the "usemin."
But this, let's save the changes and then go and
see how the "build" task actually prepares the distribution.
[inaudible] Going to our terminal,
at the prompt I type "grunt build" and then wait for all the tasks to be executed.
So you would see that it'll run through all the set of tasks,
and then finally when it is done,
it's going to simply specify that all the tasks are done.
So if you want to go back and look at the sequence of the tasks that have been completed,
you can just scroll back and see what it does.
It first cleans up,
then it copies the HTML files,
then it copies the font files,
then it does the "imagemin" task,
then it does the "useminPrepare",
then it does the "concat",
then it does the "cssmin",
both the distribution and generated,
and then it does the "uglify",
then "uglify" task, then it runs the "filerev" and then finally the "usemin" task.
And then our distribution folder should now be ready.
Going to our editor,
you now see that the distribution folder has been prepared.
Let's specifically look at the main ".css" and main ".js" files.
Note the names of these files.
Notice that after main,
there is a dot and then there is
a 20-character hash that has been added by "filerev" here.
So what happens is if I prepare a new distribution folder,
every time I prepare the new distribution folder, this hash changes,
which means that every single time I deploy a new version of my website,
if any browsers have previously viewed my web site then their cache entries,
where they might have cached the main ".css" and main ".js" has become
invalidated because we have a new version of the main ".css" and main ".js".
So the browser will re-download these things.
I didn't show the "filerev" with the NPM scripts,
but I just added it in here just to show you how it is done with the Grunt.
So with this, we complete this exercise.
Let's take a quick look at the site in our browser.
Going to your browser,
you can see that I am now loading in "dist/index.html".
So this is from the distribution folder,
so I'm checking out and it looks just fine.
The "aboutus.html" also looks just fine, just like before.
And the contact page also looks well prepared for deployment.
So with this, we complete this exercise.
After all the grunting,
I'm sure you need to catch your breath.
Before you do that, make sure to do a good comment with the message "Grunt Part two."