I am building a small angular app with browserify and ui-router. As I don't want to use a server, I want to store all my templates using angular's $templateCache like this:
exports.templateCache = ["$templateCache", function($templateCache) {
'use strict';
$templateCache.put('partials/someState.html',
"myHtmlCode"
);
}];
To populate the cache, I use grunt to look into my partials folder, grab all the html and load it into the cache with grunt-angular-templates:
ngtemplates: {
myApp: {
cwd: 'dist/',
src: 'partials/**.html',
dest: 'src/js/templates/templates.js',
options: {
bootstrap: function(module, script) {
return 'exports.templateCache = ["$templateCache", function($templateCache) {\n' +
script +
'}];'
}
}
}
},
I then use browersify to combine all my js together:
browserify: {
dist: {
files: {
'dist/js/app.js': [
'src/js/templates/**',
'src/app.js'
],
}
}
},
This is working so far but this workflow looks very unwieldy to me: I have an intermediary step where I create the templates.js file in my src directory and I have hard-coded code in my grunt file.
Is there any way to do this more elegantly? Does browserify come with built in solutions to tackle this problem?
browserify-ng-html2js has been designed to resolve this problem.
Simply add in package.json :
"browserify": {
"transform": ["browserify-ng-html2js"]
}
And you'll see if it walks the talks :)
Try transform for browserify that give you possibility to require html file (eg. Stringify). Then you can require('yourPartial.html') as string:
$templateCache.put('yourPartialId', require('./partials/yourPartial.html'));
// html file
<div ng-include=" 'yourPartialId' "></div>
Related
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.
I have a .js file in my project with code like that:
var API_ENDPOINT = 'http://example.com:8000';
var api = new RemoteApi(API_ENDPOINT);
where API_ENDPOINT changes among dev/prod environments
It's not a js application, mostly a classic server-side app (Django) with some client-side enhacements.
I started using Grunt for managing client-side dependencies and thought, it'd be a good idea to specify API_ENDPOINT in Grunt config and somehow "embed" it into .js file.
But I can't find a way to mangle files with Grunt.
The resulting .js file will be run in browser envorenment, so I need my API_ENDPOINT variable embedded in source.js file or creating a separate .js file like
var API_ENDPOINT = '...';
which I will include before script.js
(Also, I'd like to "embed" this variable into my django's settings.py)
for the clientside js i would extract all configs into a config.json file, and use grunt-replace for injection to your code.
the folder structure could look like this:
- Gruntfile
- config.json
- client/
- src/
- script.js
- dist/
config.json
{
"API_ENDPOINT": "http://example.com:8000"
}
src/script.js
var API_ENDPOINT = '##API_ENDPOINT'; // everything starting with ## will be replaced by grunt-replace by default
var api = new RemoteApi(API_ENDPOINT);
Gruntfile
grunt.initConfig({
replace: {
dist: {
options: {
patterns: [{
json: require('config.json')
}]
},
files: [
{expand: true, flatten: true, src: ['./client/src/*.js'], dest: './client/dist/'}
]
}
}
});
some details:
your final clientsidecode will reside in client/dist
requiring a json-file will automatically parse it
of course you can do it with yaml/cson (see grunt-replace section)
dont know on how to parse a json-config in python, but it shouldn't be to difficult...
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 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.