grunt build crashing on cssmin with failed scss import - gruntjs

I have a project that uses the grunt yeoman angular generator and sass.
In my scss file, I have the following lines:
// bower:scss
#import "bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
// endbower
Which were automatically generated by my yeoman generator.
In the course of putting the project together, something happened and grunt build is failing on cssmin with:
Running "cssmin:generated" (cssmin) task Warning: Broken #import
declaration of
"\bootstrap-sass-official/assets/stylesheets/_bootstrap.scss\" Use
--force to continue.
Aborted due to warnings.
Below are some relevant sections from my Gruntfile:
// Automatically inject Bower components into the app
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: /\.\.\//
},
test: {
devDependencies: true,
src: '<%= karma.unit.configFile %>',
ignorePath: /\.\.\//,
fileTypes:{
js: {
block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
detect: {
js: /'(.*\.js)'/gi
},
replace: {
js: '\'{{filePath}}\','
}
}
}
},
sass: {
src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
ignorePath: /(\.\.\/){1,2}bower_components\//
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: './bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
sourcemap: true
}
}
},
and from my index.html
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css({.tmp,app}) styles/styles.css -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/clean-blog.css">
<!-- endbuild -->
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<!-- endbuild -->
Not quite sure what I need to do to get grunt to find the _bootstrap.scss file and to minify it properly.

I'm assuming that the #import statement you pasted was from your index.html?
// bower:scss
#import "bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
// endbower
For some odd reason, you're getting scss statements injected directly into your index.html which should not be happening. What you want to make sure you're doing is compiling all of your scss files into css, and then injecting those files into the index.html. The sass target you set up inside of wiredep is probably causing the sass to get injected. Wiredep is only meant to inject the link and script tags for bower_components, it is not meant to inject sass directly into your index.html. The goal is to compile sass, and then inject the compiled css files into your index.html. You should probably remove these lines inside of wiredep:
sass: {
src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
ignorePath: /(\.\.\/){1,2}bower_components\//
}
I ran into a similar issue but found that one of the css files that got injected into the index.html actually contained the #import statement inside:
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/somePackage/somePackage.css" />
<!-- endbower --><!-- build:css({.tmp,app}) styles/styles.css -->
My problem was that the somePackage.css file still contained scss statements and there is no reasonable method for running sass directly in a browser even if you run it as javascript. You could use something like sass.js or less.js but its really not recommended: Is there a SASS.js? Something like LESS.js?. Also, the 'cssmin' task will not minify files that still contain sass statements. The key here is to make sure all sass files are compiled down to css first.
After that is done, make sure that any .css files that are injected into your index.html don't actually contain scss statements. That is the main reason my the cssmin task failed for me, and ultimately caused 'grunt build' and 'grunt serve:dist' to break before it finishes the minification/uglification processes.

Related

How to get rid of grunt-processhtml "<link rel=....>" tags

I'm trying to dynamically load some css files from a Javascript.
Snippet:
if (theme === 'testtheme' || theme === 'testtheme/') {
css =
<!-- build:css({.tmp,app}) styles/main_testtheme.css -->
'<link rel="stylesheet" href="styles/css/main_testtheme.css" type="text/css" />'
<!-- endbuild -->
;
} else {
css =
<!-- build:css({.tmp,app}) styles/main.css -->
'<link rel="stylesheet" href="styles/css/main.css" type="text/css" />'
<!-- endbuild -->
;
}
However, the grunt-build task replaces all the text between the build comments with something like:
<link rel="stylesheet" href="styles/e59b065a.main.css">
thus removing the string quotes and rendering the code invalid.
How I would like to to run:
<!-- build:css({.tmp,app}) styles/main.css -->
css = 'styles/css/main.css';
<!-- endbuild -->
should result in:
css = 'styles/e59b065a.main.css';
That would allow testing both the unminified (unbuilt) and the minified versions. Grunt build takes around 5 minutes for me so I'm trying to avoid that while developing.
Edit:
I can probably override the default blockReplacement for css (see https://github.com/yeoman/grunt-usemin#blockreplacements ) but it will make it a pain for anyone coming afterwards to try and figure out why their stylesheet is not embedded properly.
I still was not able to find an acceptable solution for this, but here's one that works, for now:
Gruntfile.js snippet:
useminPrepare: {
html: ['<%= yeoman.app %>/index.html', '<%= yeoman.app %>/includes.html'],
options: {
dest: '<%= yeoman.dist %>',
flow: {
// i'm using this config for all targets, not only 'html'
steps: {
// Here you define your flow for your custom block
cssQuoted: ['concat', 'cssmin'],
// use the option below where you have minified files that you just want to concatenate
concatjs: ['concat'],
// Note that you NEED to redefine flow for default blocks...
// These below is default flow.
js: ['concat', 'uglifyjs'],
css: ['concat', 'cssmin']
},
// also you MUST define 'post' field to something not null
post: {}
}
}
},
usemin: {
//css_name: ['<%= yeoman.dist %>/{,*/}*.html'],
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
//patterns: {
// html: [
// [ /cssHrefString\s+=\s+['"]([^"']+)["']/gm, 'Update the HTML to reference our revved/min CSS and add quotes' ]
// ]
//},
blockReplacements: {
cssQuoted: function(block){
return '\'<link rel="stylesheet" href="' + block.dest + '">\'';
},
concatjs: function (block) {
return '<script src="' + block.dest + '"></script>';
}
}
}
},
script.js snippet:
var theme = getUrlParameter('theme');
var cssHrefString;
// we need fully qualified css tags below otherwise grunt build will not be able to pick them up
if (theme === 'testtheme' || theme === 'testtheme/') {
cssHrefString =
<!-- build:cssQuoted({.tmp,app}) styles/main_testtheme.css -->
'<link rel="stylesheet" href="styles/css/main_testtheme.css">'
<!-- endbuild -->
;
} else {
cssHrefString =
<!-- build:cssQuoted({.tmp,app}) styles/main.css -->
'<link rel="stylesheet" href="styles/css/main.css">'
<!-- endbuild -->
;
}
$('head').append(cssHrefString);
The grunt config file adds a definition for concatjs - a tasks which only concatenates minified files, does not run the uglifier on them. cssQuoted which takes the string between the blocks and replaces it with a quoted "link rel=..." tag.
Make sure your grunt-usemin plugin version is up-to-date - I lost several hours trying out options with an old version (~0.1.3). The code above works with 3.0.0.

Nested Partials in Assemble

Revisiting Assemble after a few months away from it. I'm building out my Gruntfile.js with the Assemble options.
Setup
Gruntfile.js
assemble: {
options: {
flatten: true,
production: false, // set to true before delivery
assets: 'assets',
postprocess: require('pretty'),
// Metadata
pkg: '<%= pkg %>',
site: '<%= site %>',
// Templates
partials: '<%= site.includes %>',
layoutdir: '<%= site.layouts %>',
layout: '<%= site.layout %>',
},
site: {
files: {'<%= site.dest %>/': ['<%= site.templates %>/pages/*.hbs']}
}
}
_config.yml
# Assemble Templates
templates: <%= site.src %>/templates
includes: <%= site.src %>/templates/includes/**/*.hbs
layouts: <%= site.src %>/templates/layouts
layout: default.hbs
Question(s)
Within my .hbs files for the layouts, how would I go about referencing nested partials, ie temples/includes/global/head.hbs
This is how you'd call it if was at the root level:
<head>
{{> head }}
</head>
What's the markup for a nested partial? Check the docs and it didnt come to me as an answer there; sorry.
You access the partial the same way {{> head }}. We're only using the basename of the file to name the partial. There's no built in way to modify that in assemble 0.4.x.
If you have different partials with the same filename in different folders, then the last one wins.

Usemin not replacing reference blocks in HTML

I can see css and js files correctly getting concatenated, revved and copied to the correct folder. The last step though, being usemin replacing the blocks and images in html file, is not working for some reason. The image references in the css file do get replaced.
Gruntfile.js:
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>'
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
html: ['<%= yeoman.dist %>/{,*/}*.html'],
options: {
assetsDirs: ['<%= yeoman.dist %>/images', '<%= yeoman.dist %>/styles', '<%= yeoman.dist %>/scripts']
}
},
in Html I have:
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="Styles/main.css">
<link rel="stylesheet" href="Shared/Styles/default.css">
<link rel="stylesheet" href="Shared/Styles/default.date.css">
<link rel="stylesheet" href="Shared/Styles/default.time.css">
<!-- endbuild -->
The output when building says:
[1mProcessing as HTML - dist/index.html[22m
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
The file structure in dist:
– dist
|– index.html
|– styles
|– 146eba12.main.css
|– scripts
|– ...
|– images
|– ...
This has been driving me crazy and I cannot figure out why. Any assistance will be highly appreciated.
UPDATE: In a further development, and I don't know why, the blocks in html now are replaced by one line pointing to the concatenated file but it does not prepend the hash added during revving. So it does:
<link rel="stylesheet" href="styles/main.css"/>
Rather than:
<link rel="stylesheet" href="styles/b64b6f59.main.css"/>
I had exactly the same problem and stumbled upon this question in my search. I tried everything (1000 config options) but nothing worked. (however concat, minifying, revving, kept working)
Then after searching and searching I found an easy solution: Change your line endings from Unix to Dos/Windows format.
That fixed this problem for me.
File revving is done by another task; "grunt-filerev". As an example from one of my projects I have the following in my gruntfile.js :
...
filerev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
rel: {
files: [
{
src: [
'<%= project.dist %>/assets/fonts/**/*.{eot*,otf,svg,ttf,woff}',
'<%= project.dist %>/assets/img/**/*.{jpg,jpeg,gif,png,webp,svg}',
'<%= project.dist %>/assets/css/*.css',
'<%= project.dist %>/assets/js/*.js'
]
}
]
}
},
...
grunt.registerTask( 'release', [
'clean:build',
'compass:build',
'jekyll:build',
'useminPrepare',
'concat',
'uglify',
'cssmin',
'filerev',
'usemin'
]);
I realize that this is an old question, but it still has not gotten an answer to the original question. A simple fix is to remove the options from both the useminPrepare and the usemin. In the documentation on grunt-usemin it says:
When the reference is relative, by default the referenced item is looked in the path relative to the current file location in the destination directory (e.g. ...if the file is build/bar/index.html, then transformed index.html will be in dist/bar, and usemin will look for dist/bar/../images/foo.32323.png).
This only works when the index.html is in the same directory as the revved file. However, it would appear that this is the case in the above question.
My implementation of this and the result:
app/index.html
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/default.css">
<link rel="stylesheet" href="styles/default.date.css">
<link rel="stylesheet" href="styles/default.time.css">
<!-- endbuild -->
Gruntfile.js
useminPrepare: {
html: '<%= yeoman.app %>/index.html'
},
filerev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
css: {
src: ['<%= yeoman.dist %>/styles/main.css']
}
},
usemin: {
css: ['<%= yeoman.dist %>/styles/*.css'],
html: ['<%= yeoman.dist %>/*.html']
}
...
grunt.registerTask('default', [
'useminPrepare',
'concat:generated',
'cssmin:generated',
'filerev',
'usemin'
]);
dist/index.html
<link rel="stylesheet" href="styles/main.b49d2ce4.css">

Yeoman / GruntJS / UseMin

I am trying to build my files using usemin. my setup is like this: index.html - /en/bunchofhtmlfiles.html - /de/bunchofhtmlfiles.html - /scripts/apps.js
index.html
-- /en/ -> html files
-- /scripts/ -> js files
How do i write the build:js blocks?
In index.html its clear:
<!-- build:js scripts/... -->
<script src="scripts/...></script>
<!-- endbuild -->
But what do i write in the subdirs?
<!-- build:js ../scripts/... -->
<script src="../scripts/...></script>
<!-- endbuild -->
Puts the scripts in a directory "before" root.
<!-- build:js scripts/... -->
<script src="scripts/...></script>
<!-- endbuild -->
This leaves the files with the wrong paths to the js files but the js files get placed correctly.
Here is the gruntfile.js part for usemin:
useminPrepare: {
html: ['<%= yeoman.app %>/{,*/}*.html', '<%= yeoman.app %>/en/*.html'],
options: {
dest: '<%= yeoman.dist %>'
}
},
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html', '<%= yeoman.dist %>/en/*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
},
There is no need to touch the Gruntfile.js
You need to go threw the whole index.html and change the paths inside the uncommented areas.
e.g.
root/scripts/main.js
and your index.html
root/en/index.html
you need to change the index.html from
<!-- build:js scripts/main.js -->
<script src="scripts/main.js"></script>
<!-- endbuild -->
Into
<!-- build:js ../scripts/main.js -->
<script src="scripts/main.js"></script>
<!-- endbuild -->
Same for your other paths

Grunt usemin with templates

Given the following directory structure:
– Gruntfile.js
– app
|– index.php
|– js
|– css
|– templates
|– template.php
– dist
How can I configure grunt usemin to update the references to styles and scripts in my template file relative to the index.php which uses the template?
currently the tasks look like this:
useminPrepare: {
html: '<%= yeoman.app %>/templates/template.php',
options: {
dest: '<%= yeoman.dist %>'
}
},
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.php'],
css: ['<%= yeoman.dist %>/css/*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
}
And the blocks inside of the template look like this:
<!-- build:js js/main.js -->
<script src="js/script1.js"></script>
<script src="js/script2.js"></script>
<!-- endbuild -->
Okay I found it out:
The solution is to use the alternate search path option:
<!-- build:<type>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
The build blocks now look like this:
<!-- build:js(app) js/main.js -->
<script src="js/script1.js"></script>
<script src="js/script2.js"></script>
<!-- endbuild -->
and the usemin task is configured as follows:
usemin: {
html: '<%= yeoman.dist %>/templates/template.php',
css: ['<%= yeoman.dist %>/css/*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
}

Resources