Including fontawesome in Angular with grunt - angularjs

I read a lot about this issue but still did not find the solution.
I have an Angular application set up with Yeoman's generator whitout Sass. I tried to include fontawesome, so I used bower install components-font-awesome --save.
The problem is that when I grunt buildmy app, I have an error because fonts are not found in my dist folder :
GET http://myapp.com/bower_components/components-font-awesome/fonts/fontawesome-webfont.svg?v=4.0.3 404 (Not Found)
So I tried to add this to Grunt copy task in order to copy the fonts to the right directory:
{
expand: true,
cwd: '<%= yeoman.app %>/bower_components/components-font-awesome/fonts/',
src: ['**'],
dest: '<%= yeoman.dist %>/bower_components/components-font-awesome/fonts/'
}
But I am still getting the same error...
EDIT
Fonts seem to be available at http://myapp.com/dist/bower_components/components-font-awesome/fonts/fontawesome-webfont.svg?v=4.0.3
But not at the URI throwing the error (without /dist) ...

The only way I found to include icons in my Angular's application was to include glyphicons instead of fontawesome. The same problem is happening when grunt building my app with glyphicon, but the following copy task worked for me:
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'bower_components/**/*',
'images/{,*/}*.{webp}',
'fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},

Related

Bower component are not created on mvn command

My bower_component are not created. I have one dev profile inside my pom.xml file and when I execute the command mvn clean install -P dev I get error Warning: Unable to read "C:\test-widgets\xcomponent-widgets\target/bower_components/angular-animate/angular-animate.js" file (Error code: ENOENT). Use --force to continue.
My dev profile looks like this
<profile>
<id>dev</id>
<properties>
<grunt.build.file>gruntfile-dev.js</grunt.build.file>
<bower.components.dir>webapp/bower_components</bower.components.dir>
</properties>
<build>
<plugins>
<!-- For development, launch the grunt serve after compile phase -->
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<workingDirectory>${basedir}/target</workingDirectory>
</configuration>
<executions>
<execution>
<id>grunt-fix-ngdocs</id>
<phase>none</phase>
</execution>
<execution>
<id>grunt-build</id>
<phase>compile</phase>
<goals>
<goal>grunt</goal>
</goals>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
<execution>
<id>grunt-dist</id>
<phase>none</phase>
</execution>
<execution>
<id>grunt-serve</id>
<phase>test</phase>
<goals>
<goal>grunt</goal>
</goals>
<configuration>
<arguments>serve</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6.1</version>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>${project.build.directory}</directory>
<excludes>
<exclude>**/node/**</exclude>
<exclude>**/node_modules/**</exclude>
</excludes>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</profile>
and my grunt file dev.js looks like this
'use strict';
// Grunt file for de only
// Removed tasks for dist
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Project settings
yeoman: {
// configurable paths
app: require('${project.build.directory}/bower.json').appPath || 'components',
sources: '${basedir}/src/main/webapp/components',
modules: '${basedir}/src/main/webapp/modules',
sourcesSass: '${basedir}/src/main/webapp/components',
testSources: '${basedir}/src/test',
resourcesDocs: '${basedir}/src/main/resources/docs',
base: '${basedir}',
// Target folder where all generated files are placed
target: '${project.build.directory}',
// Distribution folder is defined on target\dist
dist: '${project.build.directory}/dist',
// Minimal distribution folder is defined on target\binDist
binDist: '${project.build.directory}/binDist',
// Distribution folder for vendor assets
vendor: '${project.build.directory}/dist/vendor',
// Documentation folder is defined on target\docs
docs: '${project.build.directory}/docs',
tmp: '${project.build.directory}/.tmp',
bower: '${project.build.directory}/bower_components'
},
watch: {
docJS: {
files: ['<%= yeoman.sources %>/**/*.*'],
tasks: ['jsdocs'],
options: {
livereload: true,
}
},
docSCSS: {
files: ['<%= yeoman.sources %>/**/*.scss'],
tasks: ['compass', 'jsdocs'],
options: {
livereload: true,
}
}
},
// Empties folders to start fresh
clean: {
options: {
force: true
},
// Clean target index html
targetIndexHtml: {
files: [
{
src: '<%= yeoman.target %>/index.html'
}
]
},
// Clean target template cache
targetTemplateCache: {
files: [
{
src: '<%= yeoman.target %>/<%= pkg.name %>-template-cache.js'
}
]
},
// Clean build folder .tmp
targetTemp: {
files: [
{
dot: true,
src: '<%= yeoman.target %>/.tmp'
}
]
},
// Clean build folder components
targetComponents: {
files: [
{
dot: true,
src: '<%= yeoman.target %>/components'
}
]
},
// Clean build folder css
targetCSS: {
files: [
{
dot: true,
src: '<%= yeoman.target %>/css'
}
]
},
// Clean distribution folder
dist: {
files: [
{
dot: true,
src: '<%= yeoman.dist %>'
}
]
},
// Clean minimal distribution folder
binDist: {
files: [
{
dot: true,
src: '<%= yeoman.binDist %>'
}
]
},
// Clean documentation folder
docs: {
files: [
{
dot: true,
src: '<%= yeoman.docs %>'
},
{
dot: true,
src: '<%= yeoman.tmp %>/doc'
}
]
}
},
// Copies files to places other tasks can use
copy: {
// Copy sources javascript to build directory
targetJS: {
files: [
{
expand: true,
dot: true,
cwd: '<%= yeoman.sources %>',
dest: '<%= yeoman.target %>/components',
src: [
'**/*.js',
'*/*'
]
}
]
},
// Copy index html page to build directory
targetIndexHtml: {
files: [
{
src: '${basedir}/src/main/webapp/index.html',
dest: '<%= yeoman.target %>/index.html'
}
]
},
docsFont: {
files: [
{
expand: true,
cwd: '<%= yeoman.bower %>/font-awesome/fonts/',
dest: '<%= yeoman.docs %>/fonts/',
src: ['**/*.*']
},
{
expand: true,
cwd: '<%= yeoman.sources %>/vendor/black-tie/fonts/',
dest: '<%= yeoman.docs %>/fonts/',
src: ['**/*.*']
},
{
expand: true,
cwd: '<%= yeoman.bower %>/bootstrap/fonts/',
dest: '<%= yeoman.docs %>/fonts/',
src: ['**/*.*']
}
]
},
docsBootstrap: {
files: [
{
expand: true,
cwd: 'bower_components/bootstrap/dist/css/',
dest: '<%= yeoman.docs %>/css/',
src: ['*.map']
}
]
},
docsResource: {
files: [
{
expand: true,
dot: true,
cwd: '<%= yeoman.resourcesDocs %>',
dest: '<%= yeoman.docs %>/doc_resource/',
src: ['**/*.pdf', '**/*.json']
}
]
},
docsTimeline: {
files: [
{
expand: true,
cwd: '<%= yeoman.sources %>/vendor/TimelineJS/build',
dest: '<%= yeoman.docs %>',
src: ['css/**/*.*']
}
]
},
docsPdf: {
files: [
{
expand: true,
dot: true,
cwd: '<%= yeoman.target %>/xcomponent-customization/pdfViewer',
dest: '<%= yeoman.docs %>/pdfViewer/',
src: ['**']
}
]
},
ngDocsPatch: {
// T2i fix for ng-docs issue that routing does not work in AngularjS 1.6
files: [
{
expand: true,
dot: true,
cwd: '<%= yeoman.resourcesDocs %>',
dest: '${project.build.directory}/node_modules/grunt-ngdocs/src/templates/js',
src: ['docs.js']
}
]
}
},
// Generate javascript template cache file
ngtemplates: {
options: {
url: function (url) {
return url.split("/").pop();
},
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true, // Only if you don't use comment directives!
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
},
'xcomponent-widgets': {
cwd: '<%= yeoman.sources %>',
src: ['**/*-template.html', '**/*-tpl.html', '**/template/*.html', '**/templates/*.html'],
dest: '<%= yeoman.target %>/<%= pkg.name %>-template-cache.js'
},
// module enhancement
't2i-common': {
cwd: '<%= yeoman.sources %>',
src: ['**/dialog-box.html', '**/t2i-spinner.html', '**/search-field.html', '**/version-display.html', '**/t2i-badge.html'],
dest: '<%= yeoman.target %>/templates/t2i-common-template-cache.js'
},
'pdf-viewer': {
cwd: '<%= yeoman.sources %>/pdf-viewer',
src: ['**/*.html'],
dest: '<%= yeoman.target %>/templates/pdf-viewer-template-cache.js'
},
'vertical-menu': {
cwd: '<%= yeoman.sources %>/vertical-menu',
src: ['**/*.html'],
dest: '<%= yeoman.target %>/templates/vertical-menu-template-cache.js'
},
'object-display-list': {
cwd: '<%= yeoman.sources %>',
src: ['**/*object-display-list/*.html'],
dest: '<%= yeoman.target %>/templates/object-display-list-template-cache.js'
},
'multiple-fields-group': {
cwd: '<%= yeoman.sources %>',
src: ['**/*multiple-fields-group/*.html'],
dest: '<%= yeoman.target %>/templates/multiple-fields-group-template-cache.js'
},
'multiple-search-and-select': {
cwd: '<%= yeoman.sources %>',
src: ['**/*multiple-search-and-select/*.html'],
dest: '<%= yeoman.target %>/templates/multiple-search-and-select-template-cache.js'
},
'lookup-text-field': {
cwd: '<%= yeoman.sources %>',
src: ['**/*lookup-text-field/*.html'],
dest: '<%= yeoman.target %>/templates/lookup-text-field-template-cache.js'
},
'attach-document': {
cwd: '<%= yeoman.sources %>',
src: ['**/*attach-document/*.html'],
dest: '<%= yeoman.target %>/templates/attach-document-template-cache.js'
},
'bread-crumb': {
cwd: '<%= yeoman.sources %>',
src: ['**/bread-crumb/*.html'],
dest: '<%= yeoman.target %>/templates/bread-crumb-template-cache.js'
},
'calendar-navigation': {
cwd: '<%= yeoman.sources %>',
src: ['**/calendar-navigation/*.html'],
dest: '<%= yeoman.target %>/templates/calendar-navigation-template-cache.js'
},
'date-histogram-filter': {
cwd: '<%= yeoman.sources %>',
src: ['**/date-histogram-filter/*.html'],
dest: '<%= yeoman.target %>/templates/date-histogram-filter-template-cache.js'
},
'date-histogram-select-box-filter': {
cwd: '<%= yeoman.sources %>',
src: ['**/date-histogram-select-box-filter/*.html'],
dest: '<%= yeoman.target %>/templates/date-histogram-select-box-filter-template-cache.js'
},
'object-display-paginated-tile': {
cwd: '<%= yeoman.sources %>',
src: ['**/object-display-paginated-tile/*.html'],
dest: '<%= yeoman.target %>/templates/object-display-paginated-tile-template-cache.js'
},
'event-category-display-list': {
cwd: '<%= yeoman.sources %>',
src: ['**/event-category-display-list/**/*.html'],
dest: '<%= yeoman.target %>/templates/event-category-display-list-template-cache.js'
},
'event-tile': {
cwd: '<%= yeoman.sources %>',
src: ['**/event-tile/**/*.html'],
dest: '<%= yeoman.target %>/templates/event-tile-template-cache.js'
},
'file-manager-tile': {
cwd: '<%= yeoman.sources %>',
src: ['**/file-manager-tile/*.html'],
dest: '<%= yeoman.target %>/templates/file-manager-tile-template-cache.js'
},
'filter-sidebar': {
cwd: '<%= yeoman.sources %>',
src: ['**/filter-sidebar/*.html'],
dest: '<%= yeoman.target %>/templates/filter-sidebar-template-cache.js'
},
'flexicard-calendar': {
cwd: '<%= yeoman.sources %>',
src: ['**/flexicard-calendar/*.html'],
dest: '<%= yeoman.target %>/templates/flexicard-calendar-template-cache.js'
},
'vertical-floating-toolbar': {
cwd: '<%= yeoman.sources %>',
src: ['**/vertical-floating-toolbar/*.html','**/floating-circle-button/*.html'],
dest: '<%= yeoman.target %>/templates/vertical-floating-toolbar-template-cache.js'
},
'form-paging': {
cwd: '<%= yeoman.sources %>',
src: ['**/form-paging/*.html'],
dest: '<%= yeoman.target %>/templates/form-paging-template-cache.js'
},
'theme-dropdown-button': {
cwd: '<%= yeoman.sources %>',
src: ['**/theme-dropdown-button/*.html'],
dest: '<%= yeoman.target %>/templates/theme-dropdown-button-template-cache.js'
},
'toolbar': {
cwd: '<%= yeoman.sources %>',
src: ['**/toolbar/*.html'],
dest: '<%= yeoman.target %>/templates/toolbar-template-cache.js'
},
'workflow-display': {
cwd: '<%= yeoman.sources %>',
src: ['**/workflow-display/*.html'],
dest: '<%= yeoman.target %>/templates/workflow-display-template-cache.js'
},
'year-navigator-with-legend': {
cwd: '<%= yeoman.sources %>',
src: ['**/year-navigator-with-legend/*.html'],
dest: '<%= yeoman.target %>/templates/year-navigator-with-legend-template-cache.js'
},
'variable-list-edit': {
cwd: '<%= yeoman.sources %>',
src: ['**/variable-list-edit/*.html'],
dest: '<%= yeoman.target %>/templates/variable-list-edit-template-cache.js'
},
},
// Create javaScript docs
ngdocs: {
options: {
dest: '<%= yeoman.docs %>',
editExample: false,
scripts: [
'https://code.jquery.com/jquery-1.11.2.min.js',
'https://code.jquery.com/jquery-migrate-1.2.1.min.js',
'<%= yeoman.target %>/.tmp/concat/vendor/<%= pkg.name %>-vendor.js',
'<%= yeoman.target %>/bower_components/angular-animate/angular-animate.js',
'<%= yeoman.target %>/bower_components/iscroll/build/iscroll-probe.js',
'<%= yeoman.target %>/bower_components/ng-file-upload/ng-file-upload.js',
'<%= yeoman.target %>/<%= pkg.name %>.js',
'<%= yeoman.sources %>/vendor/TimelineJS/build/js/storyjs-embed.js',
'<%= yeoman.resourcesDocs %>/documentation_override.js',
'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false'
],
styles: [
'<%= yeoman.target %>/.tmp/concat/vendor/<%= pkg.name %>-vendor.css',
'<%= yeoman.target %>/<%= pkg.name %>.css',
'<%= yeoman.sources %>/vendor/TimelineJS/build/css/timeline.css',
'<%= yeoman.resourcesDocs %>/documentation_override.css'
],
html5Mode: false,
startPage: '/api',
title: "xcomponent-widget-js",
bestMatch: true
},
api: {
src: ['<%= yeoman.sources %>/**/*.js', '<%= yeoman.resourcesDocs %>/api/*.ngdoc'],
title: 'API Documentation'
}
},
ngAnnotate: {
dist: {
files: [
{
expand: true,
src: [
'<%= yeoman.target %>/xcomponent-widgets-js-template-cache.js',
'<%= yeoman.target %>/components/**/*.js',
'<%= yeoman.target %>/scripts/**/*.js'
]
}
]
}
},
useminPrepare: {
html: ['<%= yeoman.target %>/index.html'],
options: {
dest: '<%= yeoman.target %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['concat', 'cssmin'],
copy: ['concat']
},
post: {}
}
}
}
},
usemin: {
html: ['<%= yeoman.target %>/{,*/}*.html'],
css: ['<%= yeoman.target %>/styles/{,*/}*.css'],
options: {
dirs: ['<%= yeoman.target %>'],
assetsDirs: [
'<%= yeoman.target %>',
'<%= yeoman.target %>/images',
'<%= yeoman.target %>/styles']
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
dist: {
options: {
sassDir: '<%= yeoman.sources %>/',
cssDir: '<%= yeoman.target %>/css',
relativeAssets: true,
assetCacheBuster: false,
generatedImagesDir: '<%= yeoman.target %>/images',
httpPath: ".",
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images',
httpFontsPath: '/fonts',
raw: 'Sass::Script::Number.precision = 10\n'
}
}
},
// Minify css files
cssmin: {
// Concat and minify all css on the distribution folder
dist: {
files: {
'<%= yeoman.target %>/<%= pkg.name %>.min.css': [
'<%= yeoman.target %>/css/**/*.css'
]
}
}
},
// Minify js files
uglify: {
options: {
mangle: false
},
dist: {
files: {
'<%= yeoman.target %>/<%= pkg.name %>.min.js': [
'<%= yeoman.target %>/<%= pkg.name %>.js'
]
}
},
distTemplate: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-template.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-template.js'
]
}
},
distCore: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-core.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-core.js'
]
}
},
distOrganigram: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-organigram.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-organigram.js'
]
}
},
distParameterValue: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-parameter-value.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-parameter-value.js'
]
}
},
distTimeline: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-timeline.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-timeline.js'
]
}
},
distFile: {
files: {
'<%= yeoman.target %>/dist/scripts/<%= pkg.name %>-file.min.js': [
'<%= yeoman.target %>/.tmp/concat/scripts/<%= pkg.name %>-file.js'
]
}
},
},
concat: {
// Concat all sources
jsTargetAll: {
src: [
// begin t2i modules in xcomponent-widgets
'<%= yeoman.modules %>/*.js',
// end t2i modules in xcomponent-widgets
'<%= yeoman.sources %>/**/*.js',
'<%= yeoman.target %>/xcomponent-customization/angular-strap/angular-strap.js',
'<%= yeoman.target %>/xcomponent-customization/angular-strap/angular-strap.tpl.js',
'!<%= yeoman.sources %>/vendor/TimelineJS/build/js/storyjs-embed.js',
'<%= yeoman.target %>/<%= pkg.name %>-template-cache.js',
// begin t2i modules in xcomponent-widgets
'<%= yeoman.target %>/templates/*.js',
// end t2i modules in xcomponent-widgets
],
dest: '<%= yeoman.target %>/<%= pkg.name %>.js'
},
jsTargetNoTemplateCache: {
src: [
'<%= yeoman.sources %>/xcomponent-widgets.js',
'<%= yeoman.sources %>/**/*.js',
'!<%= yeoman.sources %>/xcomponent-widgets-tpl-cache.js'
],
dest: '<%= yeoman.target %>/<%= pkg.name %>-without-template-cache.js'
},
// Concat all css
cssDist: {
src: ['<%= yeoman.target %>/css/**/*.css'],
dest: '<%= yeoman.target %>/<%= pkg.name %>.css'
}
},
connect: {
doc: {
options: {
port: 9010,
base: '<%= yeoman.docs %>',
open: "http://localhost:9010/#/api",
hostname: '0.0.0.0',
livereload: true
}
}
}
});
grunt.registerTask('jsdocs', [
"clean:docs",
'newer:copy:targetIndexHtml',
'newer:copy:targetJS',
'ngtemplates', // Generate template cache
'newer:compass', // Compile scss to css
'useminPrepare', // Prepare usemin tasks for minification
'concat', // Concat sources for distribution
'ngAnnotate',
'usemin',
'copyDocs', // Copy resources for documentation,
'ngdocs' // Build documentation
]);
grunt.registerTask('copyDocs', [
'copy:docsResource',
'copy:docsTimeline',
'copy:docsPdf',
'copy:docsFont',
'copy:docsBootstrap',
]);
// 1. Run grunt build by frontend-maven-plugin
grunt.registerTask('build', [
'clean', // Clean folders
'copy:targetIndexHtml',
'copy:targetJS',
'ngtemplates', // Generate template cache
'compass', // Compile scss to css
'useminPrepare', // Prepare usemin tasks for minification
'concat', // Concat sources for distribution
'ngAnnotate',
'usemin'
]);
// 2. Build pdf js (npm run build-pdf-js) in frontend-maven-plugin
// 3. Run grunt dist by frontend-maven-plugin
grunt.registerTask('serve', [
'copyDocs', // Copy resources for documentation,
'ngdocs', // Build documentation
'connect:doc',
'watch'
]);
grunt.registerTask('dist', [
]);
};
where is the mistake ? I can't find out why when i execute the command the bower_components folder with the dependencies is not created
I tried to change the <bower.components.dir> from webapp/bower_components to bower_components to search
on the root but after that I get error
Warning: Unable to create directory "C:\test-widgets\xcomponent-widgets\target\components\bread-crumb"

Having sub directories under views using yo angular generator

So I have started yo angular for a new project and it's great, the only issue is that I like to structure my views and have partials etc, for example a great structure for me is something like the following:
app/views/_partials/modals
app/views/_partials/menus
app/views/_partials/buttons
app/views/index.html
app/views/about.html
However, it appears that the angular generator doesn't look in sub directories when building into the dist folder and I get all sorts of missing includes and errors.
Can I change Grunt to look into these sub directories and process the views accordingly so that they appear within my app after building?
I located an interesting block that I think could be responsible in my Grunt file:
ngtemplates: {
dist: {
options: {
module: 'myApp',
htmlmin: '<%= htmlmin.dist.options %>',
usemin: 'scripts/scripts.js'
},
cwd: '<%= yeoman.app %>',
src: 'views/{,*/}*.html',
dest: '.tmp/templateCache.js'
}
},
Or is it something in the usemin block? I'm confused (relatively new to Angular):
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
js: ['<%= yeoman.dist %>/scripts/{,*/}*.js'],
options: {
assetsDirs: [
'<%= yeoman.dist %>',
'<%= yeoman.dist %>/images',
'<%= yeoman.dist %>/styles'
],
patterns: {
js: [[/(images\/[^''""]*\.(png|jpg|jpeg|gif|webp|svg))/g, 'Replacing references to images']]
}
}
},
Ok, so I figured this one out, the issue was in the ngtemplates block and my code now looks like this:
ngtemplates: {
dist: {
options: {
module: 'myApp',
htmlmin: '<%= htmlmin.dist.options %>',
usemin: 'scripts/scripts.js'
},
cwd: '<%= yeoman.app %>',
src: 'views/**/**/*.html',
dest: '.tmp/templateCache.js'
}
},
Notice the src attribute has changed from:
src: 'views/{,*/}*.html',
to:
src: 'views/**/**/*.html',
This seems to capture all my templates within the _partials directories

No views present in dist when building with grunt

I have an angular app that I have scaffolded using yeoman.
When I am trying to build with grunt, no views directory is generated in dist/
This is how my GruntFile looks
htmlmin: {
dist: {
options: {
collapseWhitespace: false,
conservativeCollapse: false,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
ngtemplates: {
dist: {
options: {
module: 'tweetSearchApp',
htmlmin: '<%= htmlmin.dist.options %>',
usemin: 'scripts/scripts.js'
},
cwd: '<%= yeoman.app %>',
src: 'views/{,*/}*.html',
dest: '.tmp/templateCache.js'
}
},
And this is how my grunt logs look like
Running "ngtemplates:dist" (ngtemplates) task
File .tmp/templateCache.js created.
>> Usemin has not created uglify.generated yet!
And
Running "usemin:html" (usemin) task
Replaced 2 references to assets
Running "usemin:css" (usemin) task
Replaced 2 references to assets
Running "usemin:js" (usemin) task
Replaced 2 references to assets
Running "htmlmin:dist" (htmlmin) task
Minified 2 files
But I still cannot see any views folder generated in my dist/ folder
Please help me with the configuration
Please have a look to this link
https://www.npmjs.com/package/grunt-angular-templates
Grunt is caching your HTML templates with $templateCache. That means all your Html files were included in the script*.js file which was generated in dist/scripts/script*.js.
That is why the views directory is not being generated in dist/
Make change in your gruntfile.js
htmlmin. files.src: ['.html', '{,/}*.html']and
copy.dist.files.src:[
'.{ico,png,txt}',
'.htaccess',
'.html',
'{,/}.html',
'images/{,/}.{webp}',
'styles/fonts/{,/}.*'
]
In this way it is working for me.

How to correctly manage fonts with bower / grunt

On my project I added to my bower.json some projects that use fonts:
fontawesome
bootstrap
roboto-fontface
Grunt file was mainly generated by "yo angular" with some custom edits. Fonts work just fine in "grunt serve" development mode but don't work when I do my dist build with "grunt".
The problem is that fonts aren't copied to my dist folder. To fix that I manually changed my Gruntfile to copy:dist all my fonts. Like this:
{
expand: true,
cwd: "<%= yeoman.app %>/bower_components/bootstrap/dist/fonts",
dest: "<%= yeoman.dist %>/fonts",
src: ["*.*"]
}
My problem now is that all my libraries CSS expect the fonts to be on a specific folder ( roboto-fontface and bootstrap for example expect the font to be in different folders).
So I'll have to change my gruntfile to replace the fonts reference on the *.css files to target the right paths. I don't know yet how to do this but my main itch is that this seems very "hacky"
Bower works very well with my css files: they are automatically added to index.html and their href is correctly replaced when doing my dist build. For example I can upgrade my ng-grid project without problems, remove and add new projects. I believe that works because of the bower.json file on the ng-grid project that contains
"main": ["./ng-grid.css", "./build/ng-grid.js"]
Grunt is correctly configured to understand that and add it to my index.html.
But for fonts it seems the only solution is to to modify my gruntfile to add copy:dist and then some kind of regex replacement on my *css files. But, for example, the roboto-fontface project bower.json file also seems to have a good "main" where all the fonts are listed besides the css file.
For me it seems logical that I should be able to configure my Gruntfile so that it understands that the "main" parameter has fonts and automatically copies them to my dist/ and replaces my css files with the correct path.
When I add a new font to my project I'll have to edit my Gruntfile, also when I remove/update fonts.
So, the question is simple: how can I best manage my project fonts? What are the best practices? How are the 'cool kids' doing it?
I ran into this issue a few weeks ago, I also used yeoman-angular-generator and had to tweak the copy:dist as well.
In my project I was using 3 separate fonts, font-awesome, lato and open-sans. I added font-awesome via bower but the other 2 I manually downloaded them and placed them under app/fonts
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'images/{,*/}*.{png, jpg, jpeg, gif,webp}',
//any new font you drop under app/fonts will be copied to dist
'fonts/**'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}, {
expand: true,
cwd: '.',
src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*',
dest: '<%= yeoman.dist %>'
}, {
expand: true,
dot: true,
cwd: 'bower_components/font-awesome',
src: ['fonts/*.*'],
dest: '<%= yeoman.dist %>'
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
//rest of Gruntfile...
Hope this helps!

grunt build gives Error code: EISDIR when trying to package fonts in AngularJS app

When I grunt build my AngularJS app grunt-rev has a problem dealing with the fonts. It will create the font folders just fine but does not place any fonts in them. Here is what it shows me.
Running "rev:dist" (rev) task
dist/scripts/scripts.js >> a3e641ec.scripts.js
dist/styles/main.css >> 970b8797.main.css
Warning: Unable to read "dist/fonts/Aller" file (Error code: EISDIR). Use --force to continue.
grunt-rev in my Gruntfile.js
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
}
}
How to fix this?
I finally solved this problem by using the double asterisk ** method to match all the sub directories recursively. I don't know why that method was not used in my original Gruntfile.js. Instead it used the {,*/}* which did not behave recursively for some reason. So here is my new rev object in my Gruntfile.js
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/**/*.js',
'<%= yeoman.dist %>/styles/**/*.css',
'<%= yeoman.dist %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/fonts/**/*.ttf'
]
}
}
},
I was having the same problem. They have a bug about it in version 0.1.0.
A workaround is to specify a file extension.
Before:
rev: {
dist: {
files: [{
expand: true,
cwd: '<%= config.dist %>/',
src: [
'images/**/*'
]
}]
}
}
After:
rev: {
dist: {
files: [{
expand: true,
cwd: '<%= config.dist %>/',
src: [
'images/**/*.{gif,jpeg,jpg,png}'
]
}]
}
}

Resources