I have a grunt tasks to concat and minify all my javascript files into one single file and the javascript file is in dist folder. "dist/<%= pkg.name %>.min.js'"
"Gruntfile.js"
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/main/resources/app/js/**/*.js',
'src/main/resources/app/config/*.js',
'src/main/resources/app/app/js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'src/main/resources/app/dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask("default", ["concat", "uglify"]);
};
Now, how can I use this minified version of javscript? Moreover, my index.html entry point of my code points to the non-minified version.
"index.html"
<div ui-view/>
<script data-main="config/require-conf" src="vendor/requirejs/require.js"></script>
You could use usemin from https://www.npmjs.com/package/grunt-usemin. Usemin, with other tasks as
concat
uglify
cssmin
filerev
is able to minify all js and css in one single file. You only need to add a build:js as you can see in snippet below:
<!-- build:js SCLogic.min.js -->
<!-- Load app main script -->
<script src="app/app.js"></script>
<!-- Load services -->
<script src="app/services/authInterceptorService.js"></script>
<script src="app/services/authService.js"></script>
<script src="app/services/blablaService.js"></script>
<!-- Load controllers -->
<script src="app/controllers/indexController.js"></script>
<script src="app/controllers/homeController.js"></script>
<script src="app/controllers/loginController.js"></script>
<script src="app/controllers/blablaController.js"></script>
<script src="app/directives/validNumber.js"></script>
<script src="app/controllers/angular-locale_es-es.js"></script>
<!-- endbuild -->
You can just include the js file the normal way.
<script src="path to the minified file"></script>
in your index.html.
Minified file is just like a normal JS file. What it does is:
It will merge all the mentioned JS files into a single file.
It will then minify it i.e it will remove the white spaces and auto change the variable names.
Advantage of this is you will have a lower size file and a single http request made from your browser which will help you load the page at a faster speed.
Related
I have angular application from yeoman-angular generator.
I do have that code in index.html:
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
...
<script src="bower_components/moment/moment.js"></script>
...
<!-- endbower -->
<!-- endbuild -->
and then in Gruntfile:
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: /\.\.\//
}
}
The problem is that i need not just moment/moment.js in my project, but min/moment-with-locales.js. Of course, it dosn't help to change it manually in index.html.
Maybe there is some way to override which library file should be used for building?
The solution appeared to be not in Grunt tasks, but in bower.json.
I had to add:
"overrides": {
"moment": {
"main": "min/moment-with-locales.js"
}
},
And grunt added that to build, so problem was solved.
Is it possible to take code from an external JS file, then paste it inline into script tags (in index.html), once the application is built?
For example, both files below are intended to be identical but I'd like the JS to be implemented externally in the src/dir and inline within the build/dir:
src/index.html
<head>
<script src="long/minified/code.js"></script>
</head>
build/index.html
<head>
<script>
// long... minified code to be added inline here
</script>
</head>
long/minified/code.js
(function(){var this,isSomeLong='minifiedCode';})();
Gruntfile.js
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
dist: {
src: [
'long/minified/code.js',
],
dest: 'build/index.html',
}
});
It's possible I'm completely off and need something like grunt-include-source
You can use grunt-processhtml to easily inline your scrips:
HTML
<head>
<!-- build:js inline -->
<script src="long/minified/code.js"></script>
<!-- /build -->
</head>
Gruntfile task:
grunt.initConfig({
processhtml: {
dist: {
files: {
'build/index.html': ['src/index.html']
}
}
}
});
How can I configure grunt and/or the usemin step so that it doesnt touch an inline script inside the body?
Suppose the following:
<html>
<body>
<script id="an-example" type="text/x-jsrender">
<b>{{:data}}</b>
</script>
</body>
</html>
When I run grunt serve to run it locally, all is ok, but when i package it with grunt, I can't find the script inside the index.html.
This is part of my Gruntfile.js:
usemin: {
options: {
assetsDirs: [
'<%= config.dist %>',
'<%= config.dist %>/images',
'<%= config.dist %>/styles'
]
},
html: ['<%= config.dist %>/{,*/}*.html'],
css: ['<%= config.dist %>/styles/{,*/}*.css']
},
Actually, the script section was wrapped inside the following comments:
<!-- build:js({app,.tmp}) scripts/main.js -->
...
<!-- endbuild -->
that instructed Grunt to compress/minify/uglify the code inside the same main.js file.
Moving the sections outside any build comment solved the issue.
My index.html has split js files as follows:
<head>
....
<!-- build:js js/app1.min.js -->
<!-- js from lib -->
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<!-- js of this app -->
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<!-- external js -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<!-- endbuild -->
....
</head>
.....
<body>
...
<!-- build:js js/app2.min.js -->
<!-- js from lib -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<!-- angular-animate provides search functionality -->
<!-- js of this app -->
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
<!-- endbuild -->
....
</body>
As you can see, I tried to use two sets of js files. The reason to split is performance. How to use usemin in this case. I tried with following:
'useminPrepare': {
'html': 'app/index.html'
},
'usemin': {
'html': ['dist/index.html']
},
However, there is no folder/file created. But in index.html, those two sections are replaced appropriately by app1.min.js and app2.min.js
Moreover, I do not understand one thing that all examples are using concat and uglify in combination of usemin. The files in index.html which are already *.min.js eg. files included in bower_components folder, what happens to them?
Unless you're heavily invested in grunt already, give gulp a look.
Below is a snippet from gulpfile.js. The gulp.src() functions take a list of files, then pipe them through transformations, ending with a list of files, which get's written to disk with gulp.dest().
This let's the first two blocks of code src, transform (minify,concat,etc), and write the js and css.
The last block of code src()'s the index.html, injects the filenames from the first two blocks, and writes the index.html to a build folder. I do consulting on gulp builds.
Here's how you'd do it in gulp:
// Vendor files are pre-minified. Get right versions.
// JS. Concat, and add revision if necessary
var srcJs = config.minify ? config.dashboard.vendorJsMin : config.dashboard.vendorJs;
var destJs = 'vendor' + (config.minify?'.min':'') + '.js';
var vendorJs = gulp.src(srcJs)
.pipe(plugins.if(config.concat, plugins.concat(destJs)))
.pipe(plugins.if(config.hash, plugins.hash()))
.pipe(gulp.dest(config.dashboard.dest + '/js'))
// Vendor files are pre-minified. Get right versions.
// CSS. Concat, and add revision if necessary
var srcCss = config.minify ? config.dashboard.vendorCssMin : config.dashboard.vendorCss;
var destCss = 'vendor' + (config.minify?'.min':'') + '.css';
var vendorCss = gulp.src(srcCss)
.pipe(plugins.if(config.concat, plugins.concat(destCss)))
.pipe(plugins.if(config.hash, plugins.hash()))
.pipe(gulp.dest(config.dashboard.dest + '/css'))
// Inject all these files into index.html
return gulp.src(config.dashboard.index)
.pipe(plugins.plumber())
.pipe(plugins.inject(vendorJs, _.merge({name: 'vendor'}, config.dashboard.injectOptions)))
.pipe(plugins.inject(vendorCss, _.merge({name: 'vendor'}, config.dashboard.injectOptions)))
.pipe(plugins.inject(appJs, _.merge({name: 'app'}, config.dashboard.injectOptions)))
.pipe(plugins.inject(appCss, _.merge({name: 'app'}, config.dashboard.injectOptions)))
.pipe(plugins.inject(templates, _.merge({name: 'templates'}, config.dashboard.injectOptions)))
.pipe(plugins.replace('REPLACE_NODE_ENV', config.NODE_ENV))
.pipe(gulp.dest(config.dashboard.dest))
This is a much more 'dev' like build system than grunt. Grunt is much more 'ops' like. Whatever works best is the one to use!
I'm attempting to get a gruntfile working to concatenate / uglify javascript files in a Laravel application. All of my tasks work in isolation, but for whatever reason the paths to my input javascript files are not being set correctly.
Here's an example of one of my blade templates:
#section('scripts')
<!-- build:js /js/min/page.min.js -->
<script type="text/javascript" src="/js/scrollIt.min.js"></script>
<script type="text/javascript" src="/js/jquery.omniwindow.js"></script>
<script type="text/javascript" src="/js/isotope.min.js"></script>
<!-- endbuild -->
#stop
Here's my useminPrepare / usemin task definitions:
useminPrepare: {
html: 'app/views/**/*.blade.php',
options: {
dest: 'app/views/dist'
}
},
usemin: {
options: {
assetDirs: [ 'public/js' ]
},
html: [ 'app/views/dist/**/*.blade.php' ]
},
I have no defined uglify task, I'm just relying on the one that usemin will generate.
All templates are making it into the 'app/views/dist' directory correctly, with the correct replacement (in the example above, there's a single javascript file at public/js/min/page.min.js being included in the template). During processing, I noticed output:
$ grunt build
Running "useminPrepare:html" (useminPrepare) task
Going through {list of templates} to update the config
Looking for build script HTML comment blocks
Configuration is now:
concat:
{ generated:
{ files:
[ { dest: '.tmp/concat/js/min/page.min.js',
src:
[ 'app/views/course/js/scrollIt.min.js',
'app/views/course/js/jquery.omniwindow.js',
'app/views/course/js/isotope.min.js' ] },
] } }
uglify:
{ generated:
{ files:
[ { dest: 'app/views/dist/js/min/page.min.js',
src: [ '.tmp/concat/js/min/page.min.js' ] },
] } }
cssmin:
{}
As you can see above, it is looking for my javascript files in app/views/course/js directory, which is incorrect. Why is this? I thought specifying assetDirs: ['public/js'] in my usemin task would tell grunt where to find those files. I have tried changing the script references to look like this:
<script type="text/javascript" src="../../../public/js/scrollIt.min.js"></script>
And this causes a successful build, but breaks my local development so its definitely not a solution. Do I need to somehow override the uglify:generated task, and if so, how do I do it for multiple different templates with generated filenames?
If it's necessary, you can see the entirety of my Gruntfile.js here. You can see from there I had to also add a new copy task for copying Javascript files from app/views/dist/js/min back over to public/js/min. I'd also like to get rid of that, but if I can just get around this issue I'd be happy.
The answer here actually turned out to be relatively simple, and was able to be gathered directly from the usemin documentation (as soon as I started to look hard enough):
Blocks are expressed as:
<!-- build:<type>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
In my case for working with Laravel, I needed to specify an alternate search path of public/ and it wound up working just fine:
#section('scripts')
<!-- build:js(public/) /js/min/script.min.js -->
<script type="text/javascript" src="/js/script1.js"></script>
<script type="text/javascript" src="/js/script2.js"></script>
<script type="text/javascript" src="/js/script3.js"></script>
<script type="text/javascript" src="/js/script4.js"></script>
<!-- endbuid -->
#stop