Well met!
For the past hours I have been trying to get the mainFiles option to work, but it seems to ignore every file that I include in there. I have tried multiple plugins in the list- but none of them get through. I am rather new with Grunt, admittedly, but I have been going through the grunt-bower-concat documentation but, nothing there. And have been adding a number of console logs inside the actual plugin code, shows no files are being passed (reverted the file after, of course).
This is the GruntFile I'm working with:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
bower_concat: {
main: {
dest: 'Assets/Build/Scripts/plugins.js',
cssDest: 'Assets/Build/Styles/plugins.css',
dependencies: {
'amplify': 'jquery'
},
mainFiles: {
bootstrap: ['bower_components/bootstrap/dist/css/bootstrap.css']
},
exclude: [
'leaflet-illustrate'
]
}
}
});
grunt.loadNpmTasks('grunt-bower-concat');
grunt.registerTask('buildbower', ['bower_concat']);
};
Leaflet-Illustrate has been excluded (for now) because it wreaks havoc on the actual task, and without the mainFiles option, I can't include it correctly.
Is there anyone who can direct me in the right way, or correct me?
Thanks in advance!
As it turns out, I entered a full path which was not needed. Meaning, this part works:
main: {
mainFiles: {
'bootstrap': ['dist/css/bootstrap.css']
}
Related
I am very new to task-runners in JS and this is my first attempt with GruntJS. In my Gruntfile.js I have kept several tasks like jshint, cssmin etc. I am able to run them all from command line, but when I run `grunt uglify' there is no response, the cursor goes to another line and remains so for hours. No error message is shown as well.
Below is my relevant code, I have tried various uglify configuration as I saw different users providing a different set of properties
//uglify:{
// options: {
// mangle : {
// except : ['jQuery', 'angular']
// },
// compress: {
// drop_console : true
// },
// banner: '*****Minified file for Pricing Plan*****',
// footer: '*********File ends**********',
// preserveComments: false
// },
// my_target:{
// options: {
// beautify: true,
// files: {
// 'scripts/pp.min.js': ['scripts/pp.js']
// }
// }
// }
//},
uglify: {
options: {
banner: '*****Minified file for Pricing Plan*****'
},
dist: {
src: 'scripts/pp.js',
dest: 'scripts/pp.min.js'
}
},
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('uglify', ['uglify']);
On command line I am running grunt uglify
Can someone suggest whats wrong here and the way to rectify it.
Just if required: Its an Angular1.x.x project
EDIT: I tried installing uglifyJs and ran the uglifyjs command. It successfully uglifies and minifies my code. So is there any thing that needs to be done apart from what I have above.
but when I run `grunt uglify' there is no response, the cursor goes to another line and remains so for hours.
The Issue:
I think the issue is related to how you are registering your uglify task. This following line of code:
grunt.registerTask('uglify', ['uglify']); //<-- Issue is here.
How to fix it:
When creating an Alias Task using grunt.registerTask() avoid naming the taskName the same as any of the items/tasks defined in the taskList array.
grunt.registerTask('minify', ['uglify']); //<-- Correct.
NOTE: Although in the example code above I have changed the taskName to minify it can be any valid name you prefer. Just ensure whatever taskName you choose does not also exist as one of the items in the taskList array.
You now run the revised registered uglify task via CLI as follows:
$ grunt minify
Gruntfile.js
Here is the revised Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
uglify: {
options: {
banner: '/*****Minified file for Pricing Plan*****/'
// ... <-- Your other options
},
dist: {
src: 'scripts/pp.js',
dest: 'scripts/pp.min.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('minify', ['uglify']);
};
(Note: Also added forward slashes to your banner string to produce a valid JavaScript comment in the resultant file)
I’m trying to get grunt to concat some .css files from 2 different directories into a single css file
I got it working ok and am trying to write a similar piece of code to concat html files in the order I specify in a simple external .json file rather than editing the Grunfile.js directly each time but it keeps throwing errors
The file locations and permissions are all ok, I can do it with php or concat the css files ok, I’m not great on js syntax os using functions. I only learned to use Grunt in the last few days so am pretty sure have not called the file with the correct code??
Any advice kindly appreciated!
This is my Gruntfile.js exactly
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
// 2. Configuration for concatinating files goes here
file.readJSON(‘html-files.json’);
},
watch: {
files: ['../../pages/**/*.html’],
tasks: ['concat'],
options : { nospawn : true }
}
});
// 3. Where we tell Grunt we plan to use this plug-in
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat']);
};
This is the html-files.json file contents exactly
html: {
src: [
'../../pages/**/this-block.html',
'../../pages/**/that-block.html',
],
dest: '../../somepage/content.html',
}
I am using Grunt to build a set of static pages that operate together as a site/application. In the interest of sticking to DRY practices, I am using a package called grunt-processhtml to do "includes".
However, my "included" navigation does not have the appropriate classes to indicate the current page in the navigation. I can pull it off with JavaScript if I need to (set the active class after the menu is created, based on either a variable or the URL). However, I also stumbled across this:
grunt-autonav
Which post-processes my assembled static files and adds the appropriate class. However, I can't for the life of me figure out how to configure it for "process all of the .html files and add the appropriate classes to each of them."
My last failed attempt looks like this:
autonav: {
options: {
parent: '.nav'
},
dev: {
src: '<%= dirs.purgatory %>/html/**/*.html',
dest: '<%= dirs.dev %>'
}
}
However, the plugin doesn't seem to want to use this kind of input for the source:
Warning: Unable to read
"purgatory/html/download.html,purgatory/html/upload.html" file (error
code: ENOENT). Use --force to continue.
It sees my two HTML files but doesn't know how to take it from there. I can't tell if I have a configuration error or if the plugin just doesn't work this way. The sample given in their documentation seems to require specifying every single page that needs its nav customized. But it might be a reading comprehension issue.
Does anybody know how to accomplish my goal in Grunt (not in JS) using the above or any other tools? I don't mind adding a new tool, but I've come up short.
To use dynamic file lists in grunt and all its plugins, you need to wrap your src/dest in a files object and set expand to true:
autonav: {
options: {
parent: '.nav'
},
dev: {
files: {
expand: true,
src: '<%= dirs.purgatory %>/html/**/*.html',
dest: '<%= dirs.dev %>'
}
}
}
Xavier Priour set me on the right path, but I had to scratch my head a bit before I arrived at the final solution:
autonav: {
options: {
parent: '.nav'
},
dev: {
files: [
{
expand: true,
cwd: '<%= dirs.purgatory %>/html',
src: '**/*.html',
dest: '<%= dirs.dev %>'
}
]
}
}
First, I had to look into expand, which provided samples that used the files property Xavier mentioned. However, the examples show that files is an array of objects. Not sure if it "has" to be, but I followed that pattern and wrapped it up as an array.
Next was realizing it wasn't the input string that was wrong, it was that I was configuring the copy incorrectly. When expanded, the destination is a recreation of the source path. To get around this, you issue a CWD. This means that your input path is essentially "null"-ish and it doesn't create a "purgatory" directory in the destination.
The final task now works as expected!
I apologize for the very awkward question title, if anyone can think of a better way to phrase this question I'll change it immediately.
I'm building an app with Angular and RequireJS and to try to optimize performance, dependencies and lazy-loading I'm looking to build a file structure like this:
/app
----/regisitration
--------_registration.module.js
--------registration.ctrl.js
--------registration.svc.js
--------registration.directive.js
----/courses
--------_courses.module.js
--------courses.directive.js
--------courses.controller.js
--------courses.service.js
--------/course
------------course.controller.js
----/admin
--------_admin.module.js
--------admin.controller.js
Where I set up my routing, I want to be able to have a user who goes to any /registration/ view load the entirety of _registration.module.js which would be the concatenation of all the other .js files within the /registraion directory (and any sub directories) so that my team isn't bogged down by needing to include several and possibly duplicate dependencies as well as serve the entirety of the site "section" to the user in one shot. Hopefully the sample above shows why I wouldn't want to just front-load all the files, because most users will never hit the admin section of the site. I'm trying to figure out the most efficient way to achieve this with grunt, but so far I'm working very manually with code like this:
grunt.initConfig({
concat: {
app: {
files: [
{
src: ['..app/registration/*.js', '!..app/registraion/*.module.js'],
dest: '..app/registration/_registration.module.js'
},
{
src: ['..app/courses/*.js', '!..app/courses/*.module.js'],
dest: '..app/courses/_courses.module.js'
},
{
src: ['..app/admin/*.js', '!..app/admin/*.module.js'],
dest: '..app/admin/_admin.module.js'
}
],
}
},
});
I think there must be a more efficient and less manual way to do what I'm trying to achieve. Does anyone have any suggestions?
Remember that you can still execute JavaScript within your Gruntfile.
grunt.initConfig({
concat: {
app: {
files: grunt.file.expand({ cwd: 'app', filter: 'isDirectory' }, '*')
.map(function(ngModule) {
return {
src: ['app/' + ngModule + '/*.js', '!app/' + ngModule + '/*.module.js'],
dest: 'app/' + ngModule + '/_' + ngModule + '.module.js'
};
})
}
},
});
With this, you should be able to create new modules without needing to remember to update a config entry for them.
So here is my hypothetical config object for a hypothetical fooTask that does something (not relevant to question) to a bunch of JS files
grunt.initConfig({
fooTask: {
app1: 'app1/*.js',
app2: 'app2/*.js',
app3: 'app3/*.js'
}
});
As you can see, with this approach, I have to run fooTask 3 times with each app specified as a target:
grunt fooTask:app1
grunt fooTask:app2
grunt fooTask:app3
Needless to say this does not scale as either the number of apps increase or the number of such foo tasks increase as one has to C&P the same code over and over for each app.
So ideally what I would like to define is just one target with the name of the app passed in as a config variable
grunt.initConfig({
fooTask: {
dist: '<%=appName%>/*.js'
}
});
I would then like to call fooTask 3 times, one for each app, with the right app set as appName
var apps = ['app1', 'app2', 'app3'];
apps.forEach(function(app) {
var currAppName = app;
// Run fooTask but how do I specify the new currAppName config?
grunt.task.run('fooTask');
});
As from code above, I know I can run my fooTask using grunt.task.run but how do I set the appName config for my task?
Note that this question is similar to this other one that also does not have the right answer yet - Pass Grunt config options from task.run
Thanks a lot.
EDIT 2:
So nevermind the garbage below the first edit, leaving as example of what doesn't work. In my case it was really important to be able to set the value within a task at run-time so I settled on the file system. Perhaps it suits your needs.
grunt.initConfig({
someTask: {
someKey: fs.readFileSync('file.txt', { encoding: 'utf8' })
}
});
of course you can do the readFile outside of the task if you need a bunch of different app names.
EDIT:
Hmmm. I swear I had this working when I wrote this...but now it is not. Grunt just sees the extra arguments as additional unfound tasks.
I was trying to figure this out myself, finally a "duh" just moment happened - why not parse process.argv before grunt.initConfig?
module.exports = function(grunt) {
var sourcefile = process.argv[2] || 'default.js'; // <- this
grunt.initConfig({
uglify: {
main: {
src: sourcefile, // <- voila :)
dest: sourcefile.substring(0, sourcefile.length-3) + '.min.js'
}
}
});
grunt.loadNpmTasks('uglify');
grunt.registerTask('default', ['uglify']);
};
and use from command line:
grunt mykillerscript.js
I didn't even try to use grunt.option for the same reason that all the examples only showed directing which task is run, but I wouldn't be surprised if there is a more "grunt" way to do this.