I'm currently using bower inside a Sails.js project, I found the grunt-bower library very complete and useful. However, you still need sometimes to pick or exclude files manually.
So I'm wondering if it exist another more conventional way to manage frontend dependencies inside a Sails.js project ?
Thanks
EDIT:
For those who are wondering, here is my grunt task:
module.exports = function(grunt) {
grunt.config.set('bower', {
dev: {
dest: '.tmp/public',
js_dest: '.tmp/public/js/dependencies',
css_dest: '.tmp/public/styles',
fonts_dest: '.tmp/public/fonts',
less_dest: '.tmp/dontpublish',
scss_dest: '.tmp/dontpublish',
options: {
keepExpandedHierarchy: false,
stripGlobBase: false,
packageSpecific: {
'bootstrap': {
files: [
'fonts/glyphicons-halflings-regular.eot',
'fonts/glyphicons-halflings-regular.svg',
'fonts/glyphicons-halflings-regular.ttf',
'fonts/glyphicons-halflings-regular.woff',
'fonts/glyphicons-halflings-regular.woff2',
'dist/js/bootstrap.js'
]
}
}
}
}
});
grunt.loadNpmTasks('grunt-bower');
};
As you see, I had to include some files manually for bootstrap and I placed less and scss files in a "not published" folder to exclude them. It's no big deal, but I was just wondering if something better exist, or if I have a bad config.
Related
I'm having serious problems getting gulp-angular-templatecache to work nicely within my app. I'm using the HotTowel yeomen generator and I modified it a little bit, but I can't seem to get my template cache to use a different module name. Here's the relevant gulpfile code:
gulp.task('templatecache', ['clean-code'], function() {
log('Creating an AngularJS $templateCache');
return gulp
.src(config.htmltemplates)
.pipe($.if(args.verbose, $.bytediff.start()))
.pipe($.minifyHtml({empty: true}))
.pipe($.if(args.verbose, $.bytediff.stop(bytediffFormatter)))
.pipe($.angularTemplatecache(
'templates.js',
{
module: 'app.templates',
standalone: true,
root: 'app/',
moduleSystem: 'IIFE'
}
))
.pipe(gulp.dest(config.temp));
});
The original HotTowel gulpfile had {module: 'app.core', standalone: false, root: 'app/'} as the options. Every time I run the build process, my stupid templates.js file looks like this:
angular.module("app.core").run(["$templateCache"....
I've tried so many things to change it, but it never goes to app.templates. Any ideas?
I have a couple of products that started off with the yeoman angular generator, and it has been a pretty good dev setup. One thing I haven't been able to find a good solution for is setting a development/production mode flag.
Naturally we use a few tools that we only want on in production so having prod/dev variable that we can use both inline JavaScript and/or HTML files would be quite useful. I searched for solutions online before but haven't found anything useful.
Ultimately, I'm looking for a good solution to use in an AngularJS setting, ideally set via grunt serve and/or build run. What are other teams doing here?
I'm using ng-constant. It creates a .js file which contains some angular constants of your choice.
grunt.initConfig({
...
ngconstant: {
options: {
name: 'config',
dest: '<%= yeoman.app %>/scripts/config.js'
},
development: {
constants: {
myVariable: 'it is development'
}
},
production: {
constants: {
myVariable: 'it is production'
}
}
}
});
And then just add it to your tasks:
grunt.registerTask('serve', [
...
'ngconstant:development',
...
]);
And don't forget to include this /scripts/config.js file in your html and inject 'config' into your app.
var app = angular.module('myApp', [
'config',
...
]);
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.
I am currently using Grunt, and as I was trying Gulp, the same problem I encountered first with Grunt occurred to me.
I am trying to process some js files (concat, uglify and minify them), but I don't want all of them to compile into one big file, I want multiple output files, each from the processing of some input files :
scripts =
firstOutput:
outputFilename: 'first.min.js',
inputFiles: ['one.js', 'two.js']
secondOutput:
outputFilename: 'second.min.js',
inputFiles: ['three.js']
thirdOutput:
outputFilename: 'third.min.js',
inputFiles: ['four.js', 'five.js']
The only way I found (for now) to achieve that with Grunt is with multiple watches and multiple uglify tasks (or one uglify task and a listener on watch change to dynamically modify the uglify task src and dest) :
module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-contrib-watch'
grunt.loadNpmTasks 'grunt-contrib-uglify'
grunt.initConfig
watch:
firstOutput:
files: scripts.firstOutput.inputFiles
tasks: ['uglify:firstOutput']
options :
spawn : false
secondOutput:
files: scripts.secondOutput.inputFiles
tasks: ['uglify:secondOutput']
options :
spawn : false
thirdOutput:
files: scripts.thirdOutput.inputFiles
tasks: ['uglify:thirdOutput']
options :
spawn : false
uglify:
firstOutput:
files: scripts.firstOutput.inputFiles
dest: scripts.firstOutput.outputFilename
secondOutput:
files: scripts.secondOutput.inputFiles
dest: scripts.secondOutput.outputFilename
thirdOutput:
files: scripts.thirdOutput.inputFiles
dest: scripts.thirdOutput.outputFilename
grunt.registerTask 'default', 'watch'
And, as you can imagine, this is just an example, in my case of a big web application, there's a lot more than just three output js files, and I also process a few less files into some css files
My Gruntfile is really huge, and I find it has a lot of duplicate code, is there any way to have this code refactored to have one watch and one uglify task, with an automatically guessed src and dest with some kind of dependency (to know that if the four.js file is modified, it has to process the third output) ?
If you have some way to do it with Gulp I'll take it with great pleasure, as I would like to test it in my usual workflow.
Here's how you can do this with gulp + vanilla javascript:
var _ = require("underscore")
, gulp = require("gulp")
, uglify = require("gulp-uglify")
var scripts = [
{
output: 'first.min.js',
input: ['one.js', 'two.js']
}
, {
output: 'second.min.js',
input: ['three.js']
}
, {
output: 'third.min.js',
input: ['four.js', 'five.js']
}
];
function build(files, dest) {
return gulp.src(files)
.pipe(uglify())
.pipe(gulp.dest(dest));
}
gulp.task("watch", function () {
_.each(scripts, function (script, i) {
gulp.watch(script.input, function () {
build(script.input, script.output);
});
});
});
Even better if you can use globs to match sets of files so you don't have to write out the path for every single input set. Something like input: ["one/**/*.js, "other/**/*.js"]
"I am trying to process some js files (concat, uglify and minify
them), but I don't want all of them to compile into one big file"
Can I ask why? The benefit of one larger file is that you save on HTTP requests, every resource you load will cause some slowdown of your website. May I suggest using proper dependency management with RequireJS? That way the optimiser can walk your dependency graph and output optimised files for you.
http://requirejs.org/
There's a grunt task for this too:
https://github.com/gruntjs/grunt-contrib-requirejs
I use grunt to convert all my less files into css files,using this:
less: {
development: {
files: {
"css/*.css": "less/*.less"
}
}
}
This worked on version 0.3.0, but now that I have upgraded to v0.4.0 it doesn't work anymore.
The following code (not using * in the destination) works on both versions, so the problem is with the star on the destination file.
less: {
development: {
files: {
"css/test.css": "less/*.less"
}
}
}
Any idea ?
This isn't a bug. Grunt no longer supports globbing in dest using that configuration. However, you can use the "files array" format, like this:
files: [
{
expand: true,
cwd: 'src',
src: ['*.less'],
dest: 'assets/css/',
ext: '.css'
}
]
Also, if you use a library like Bootstrap and you want to build each LESS file (component) into a separate, individual CSS file, it's not very easy to accomplish "out of the box". The reason is that each LESS file would need to have its own #import statements for variables.less and mixins.less (and a couple of others like forms.less and navbar.less, since they are referenced in other files).
To make this really easy, try the Grunt plugin, assemble-less (disclaimer: I'm one of the maintainers of the project, and I'm also on the core team for less.js). assemble-less is a fork of grunt-contrib-less by Tyler Kellen, but it adds some experimental features that will accomplish what you need (if you want stability, please stick with grunt-contrib-less). For example:
// Project configuration.
grunt.initConfig({
less: {
// Compile all targeted LESS files individually
components: {
options: {
imports: {
// Use the new "reference" directive, e.g.
// #import (reference) "variables.less";
reference: [
"bootstrap/mixins.less",
"bootstrap/variables.less"
]
}
},
files: [
{
expand: true,
cwd: 'bootstrap/less',
// Compile each LESS component excluding "bootstrap.less",
// "mixins.less" and "variables.less"
src: ['*.less', '!{boot,var,mix}*.less'],
dest: 'assets/css/',
ext: '.css'
}
]
}
}
...
}
The imports feature essentially prepends the specified #import statements onto the source files. The reference option allows you to "reference" other less files while only outputting styles that are specifically referenced via mixins or :extend. You might need to reference a few more files than shown here, since Bootstrap cross-references styles from other components, like forms.less, buttons.less, etc. (See the Gruntfile in assemble-less for examples.)
So after running the assemble-less task with the configuration in the example above, the assets/css folder would have:
alerts.css
badges.css
breadcrumbs.css
button-groups.css
buttons.css
carousel.css
close.css
code.css
component-animations.css
dropdowns.css
forms.css
glyphicons.css
grid.css
input-groups.css
jumbotron.css
labels.css
list-group.css
media.css
modals.css
navbar.css
navs.css
normalize.css
pager.css
pagination.css
panels.css
popovers.css
print.css
progress-bars.css
responsive-utilities.css
scaffolding.css
tables.css
theme.css
thumbnails.css
tooltip.css
type.css
utilities.css
wells.css
There are other features that should help you with this, but the imports feature is super powerful since it allows you to add directives directly to the Gruntfile.