I am using grunt-usemin plugin. I wonder how to do below.
I have two blocks of usemin config in index.html.
<!-- build:js /scripts/scriptsmin.js -->
<script src="/scripts/jquery.min.js"></script>
...
...
<!-- endbuild -->
<!-- build:js /scripts/scripts.js -->
<script src="/scripts/app.js"></script>
....
...
<!-- endbuild -->
First block, scriptsmin.js, is minified files.
Second, scripts.js, contains all files which needs minification.
I like to.
run minifier (uglifyjs) on second block
concat first block with minified version of second (step 1)
Is it possible if these blocks are in the same file. I saw a section on flow. Couldn't follow whether I can name the block of configuration, and set seperate flow on each of it. It talks about flow based on file name (index.html). How should I write the grunt useminPrepare section.
I had the same problem. If you'll be satisfied with two files instead of one you can use a fork of usemin here. It enables few new flows, namely
libs
libs2min
void
remove
See full descriptions. So your html would be:
<!-- build:libs2min /scripts/scriptsmin.js -->
<script src="/scripts/jquery.js"></script>
...
...
<!-- endbuild -->
<!-- build:js /scripts/scripts.js -->
<script src="/scripts/app.js"></script>
....
...
<!-- endbuild -->
Nesting the blocks isn't probably a good idea right now unfortunately. But you could try it out.
To install the fork instead of the regular grunt-usemin change your package.json as so
"devDependencies": {
...
"grunt-usemin": "Rauno56/grunt-usemin",
...
},
and keep an eye on the main repo - maybe the feature isn't to far from getting there too.
Just wondering why you need two separate targets for your JavaScript files, especially if they are going to be minified & concatenated into one file. What I would do is just have the one script block at the end of your file, like this:
<!-- build:js /scripts/scripts.js -->
<script src="/scripts/jquery.min.js"></script>
<script src="/scripts/app.js"></script>
<!-- endbuild -->
It's easier to understand like that, if all your JS is at one block rather than two. The useminPrepare is a task that basically updates your Gruntfile configuration to include concat, cssmin and uglify targets for your scripts and styles. Just run it on the files that have your build comments in, like so.
useminPrepare: {
html: 'build/index.html'
}
usemin shouldn't look too different to useminPrepare, but what you may find you want to do is 'seed' useminPrepare with one file, if that contains the same build blocks as the rest of your HTML. So the actual usemin config could have a few more files in there:
usemin: {
html: ['build/index.html', 'build/about.html', 'build/contact.html']
}
After useminPrepare runs, then run your concat, uglify and cssmin tasks, then finally run usemin. So you have a custom task like this:
grunt.registerTask('build', ['useminPrepare', 'concat', 'uglify', 'cssmin', 'usemin']);
Hope this helps.
Related
I'm brand new to Gulp and I was able to create a site.min.js file, which as I understand is the minified versions of my JavaScript files.
How do I take advantage of that?
I'm not sure if I'm on the right track, but should my index.html also be getting modified to only load the new min.js file?
When you minify a file, the result is a completely different file. You need to link it in your page in order to use it.
<script src="site.min.js"></script>
The production version of your index.html file should only link to the minified version and any non-minified version should be removed.
There are gulp plugins which help with this.
gulp-useref is popular
gulp-html-replace is quite flexible
gulp-usemin
gulp-htmlbuild
They all offer a similar feature where you can specify blocks within HTML comments that will be replaced by the minified version.
<!-- build:js -->
<script src="website-module.js"></script>
<script src="core.js"></script>
<!-- endbuild -->
With the right options within your gulp task, it would become:
<script src="site.min.js"></script>
I'm using grunt-usemin in grunt for minify, concat all the js files and put them into minified file on my index.html header:
<!-- build:js js/indexBulk.js -->
<script src="js/common/mifirstfile.js"></script>
<script src="js/common/errors.js"></script>
<script src="js/common/anotherfile.js"></script>
<script src="lib/angular/angular.js"></script>
<!-- endbuild -->
This works perfect...but what if I have some others html static files with exactly the same js files on the header, how do I have to proceed in order to prevent the fact of copy each time this block?
Is there a way to put the minified file on the header of each one of my others html files without copying this block?
I have problems understanding the usemin(Prepare), described in here: usemin
What I understand is, that with the usemin, you can combine many files as only one file, which would be a good idea when building your JS application. I also understand the flow how you should use it, for example:
// simple build task
grunt.registerTask('build', [
'useminPrepare',
'concat:generated',
'cssmin:generated',
'uglify:generated',
'filerev',
'usemin'
]);
Then if you have this code:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->
The concat task would combine all those files into a one file, called app.js, and put it in a .tmp folder. Then the uglify task would take the file app.js from the .tmp folder, uglify all js in it, and put it to dist-folder.
Let's say that before useminPrepare, I have had another task, which translates the original html (index.html) also to dist folder. Now when the usemin task starts, I have set it to use the dist folder, and it should replace the old blocks with a reference to the generated app.js. So now, in the html inside the dist folder, the same part should look something like this:
<script src="js/app.js"></script>
Is this correct? So now there shouldn't be any comment tags left? Now I have a problem related to the usemin. The situation is this: In the beginning html, I have comment tags for bower_components (bower-install) inside usemin tags like this:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<!-- bower:js -->
<script src="bower_components/something/some_bower_component.js"></script>
<script src="bower_components/something/some_bower_component.js"></script>
<script src="bower_components/something/some_bower_component.js"></script>
<!-- endbower -->
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->
With this setting, everything seems to work good until the usemin task in the end. The usemin task is now unable to replace the code blocks. I have identified the reason why it can't. It is because I have those bower comment blocks there. So if I separately make the first tasks, then transfer the code to dist, then remove those bower comment tags, and make the rest of the tags in the build, then everything works fine. I want to solve this so that I can run all the tasks straight through. How could I solve this? Why does usemin fail if it sees comment blocks? Could I change usemin options to ignore comment blocks? Or should I write a grunt task, that will remove those particular comment blocks after bower components are injected and the html has been transfered to dist? The versions I have are:
"grunt-bower-install": "~0.7.0",
"grunt-concurrent": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-cssmin": "~0.7.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-uglify": "~0.2.0",
"grunt-usemin": "~2.0.0",
See this answer: grunt usemin doesnt affect the html file(index.html)
Just had this problem by myself and my solvation was to convert all line endings into unix style line endings (lf) and avoid windows line endings in any file converted by grunt usemin
I've got an angular project that I started up with default yeoman settings.
Looking through how the build process works, I can't imagine how any of my bower dependencies are automatically cdnifyed and what the point of the cdnify task are.
First of all, yeoman sets everything up with wiredep, which wires in my bower dependencies into a spot into index.html. It looks like:
<!-- build:js(app) 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/json3/lib/json3.js"></script>
<!-- endbower -->
<!-- endbuild -->
Looking at my Gruntfile from Yeoman, it appears that
Wiredep forces all bower dependencies into this block
The whole block is then compiled into a vendor.js
and finally
cdnify runs, identifying any free script tags and attempting to replace with cdn'd versions.
This seems rather silly to me. But before I go into hacking up my Gruntfile, I wanted to try to make sure that my understanding is correct.
I can't simply copy-paste easily cdnify'd dependencies outside of this block, because wiredep is just going to put them back in. If I did that index.html would include jquery twice, for example. Once in vendor.js and second from a cdn.
If I want to use cdnify, then I need to get away from wiredep, and manually decide which dependencies should be cdnify'd and which shouldn't.
It seems yeoman would be smarter than this, and I wanted to make sure I'm not the dumb one here. Is it true that this setup is somewhat contradictory/redundant? Am I missing something?
update it appears that placing scripts outside of this block causes wiredep not to place them in the bower block. I can't find anywhere that says this is documented behavior, however.
You can go to the bottom of the grunt file which has registered tasks and remove things like CDNify from a task like grunt build. Grunt will then skip that step next time.
I'm beginning to evaluate javascript module tools like RequireJS for javascript modularization. This seems useful, especially during development, so I don't need to recompile all of the js files into mylib-<version>.js whenever I change one of the dependent files.
My app is distributed with both html and javascript files, and in production, I would like to use the compiled version of the javascript file.
So in development, my html file might look something like
<html>
<head>
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
</html>
But in production, I would expect it to look more like
<html>
<head>
<script src="mylib-1.0.js"></script>
</head>
</html>
I wouldn't think it production that there should be any need to reference requirejs if I am distributing a compiled file.
Is there a way to do this without having to manually change my html files before I distribute the app?
RequireJs has an optimization tool, which can help you to minify and concatenate your modules. It has a lot of options, and can be difficult to use, but it gets easier with a build tool like GruntJs or (especially) Yeoman, which uses GruntJs to build.
In both you can use the rjs task (which optimizes modules), but again Yeoman is a bit easier since it has generators which will configure it already for you:
// usemin handler should point to the file containing
// the usemin blocks to be parsed
'usemin-handler': {
html: 'index.html'
},
// rjs configuration. You don't necessarily need to specify the typical
// `path` configuration, the rjs task will parse these values from your
// main module, using http://requirejs.org/docs/optimization.html#mainConfigFile
//
// name / out / mainConfig file should be used. You can let it blank if
// you're using usemin-handler to parse rjs config from markup (default
// setup)
rjs: {
// no minification, is done by the min task
optimize: 'none',
baseUrl: './scripts',
wrap: true,
name: 'main'
},
In the index.html you just use a comment line to specify which js files should be minified/concatenated to which output file:
<!-- build:js scripts/amd-app.js -->
<script data-main="scripts/main" src="scripts/vendor/require.js"></script>
<!-- endbuild -->
In the example above, the modules will be concatenated to ONE file, named amd-app.js.
Edit:
This will be done by executing grunt from the command line. This will start a lot of useful tasks, which will build the project in a dist folder, but again this is highly adaptable.
The resulting index.html file (in dist) has only (if you want) one javascript file:
<script src="scripts/15964141.amd-app.js"></script>
My advice: use Yeoman to make life easier (at least for handling minification/concatenation).
First you have to compile your depency tree into one file using the r compiler. After that you can a striped down AMD loader like almond. At least you have to find a way to change the url in your index html.
Take a look at gruntjs which can automatize the whole thing, there a bunch task to like usemin that helps you with the process.