How to exclude certain libraries on build vs dev - gruntjs

Using Grunt, I have a serve and a build task.
I would like to remove certain lines from my code when the build task is run
<!-- don't want from here -->
<script src="../components/jquery-mockjax/jquery.mockjax.js"></script>
<script src="scripts/mockjax-mocks.js"></script>
<!-- to here -->
But if there is some sort of library that's built around environment variables in Grunt that may solve this problem as well as others in the future...

I use grunt-preprocess to do that.
In your build task, you have to add this task to remove the html you want. The basic sintaxis is like that:
preprocess: {
options: {
inline: true,
context : {
DEBUG: false
}
},
html : {
src : [
'your_path/index.html',
]
}
}
In your index.html, add the conditional named DEBUG:
<!-- #if DEBUG -->
<script src="../components/jquery-mockjax/jquery.mockjax.js"></script>
<script src="scripts/mockjax-mocks.js"></script>
<!-- #endif -->

Related

styles dont connect when loading local server

my dir looks like that :
|-project
-gulpfile.js
|-build
-index.html
|-js
-app.min.js
-vendors.min.js
|-styles
-all.css
-vendors.min.css
i inject the css and js files with this gulp task:
gulp.task('index',function () {
return gulp.src('src/index.html')
.pipe(inject(gulp.src(['**/vendors.min.css','**/vendors.min.js','**/app.min.js','**/all.css'], {read: false})))
.pipe(gulp.dest('build'))
.pipe(livereload());
})
i set up a local server with node.js,when i do the request , the html file loads up,but the .js and .css files dont connect for some reason.Although when i check page's source code at output their paths are written in.
<!-- inject:css -->
<link rel="stylesheet" href="/build/styles/vendors.min.css">
<link rel="stylesheet" href="/build/styles/all.css">
<!-- endinject -->
when i hover on one of them it shows :
http://localhost:5000/build/styles/all.css
i use this task for setting the server :
gulp.task('connect', function() {
connect.server({
root: 'build',
livereload: true,
port: 5000
});
});
EDIT
any recommendation about how to make it on hovering look like
localhost:5000/styles/all.css
If the build folder is the root of the server, you shouldn't be including it in the path of the js and css files. This is failing because you are trying to reference a build folder inside the build folder.
Change your injection of css to the following:
<link rel="stylesheet" href="styles/vendors.min.css">
<link rel="stylesheet" href="styles/all.css">

Polymer, grunt-vulcanize: prototype.registerCallback is not a function

I am trying to create a very simple HTML page with Polymer, which includes an HTML file with all the components I need:
<link rel="import" href="bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="components/my-element.html">
my-element.html looks like this:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="my-element">
<template>
// Some HTML
</template>
<script>
Polymer({
is: 'my-element',
properties:{
// properties
}
});
</script>
</polymer-element>
When I run it as it is, everything works fine.
When I try to Vulcanize the components.html file, and then open the same page with the Vulcanized version, I get the following error in the console
"Uncaught TypeError: prototype.registerCallback is not a function"
I have noticed the Vulcanize process turns
Polymer({
is: 'my-element',
properties:{
// properties
}
});
Into
Polymer('my-element', {
is: 'my-element',
properties:{
// properties
}
});
Which seems to be what is causing the bug, as window.Polymer only expects an Object as a parameter.
I am using grunt-vulcanize to do the actual Vulcanizing, and my config looks like this:
vulcanize: {
default: {
options: {
excludes: {
imports: [
'polymer.html'
]
},
'strip-excludes': false,
inline: true,
strip: true
},
files: {
'build.html': 'components.html'
},
},
}
Is there a way of stopping this?
I am using Polymer 1.0, and grunt-vulcanize 0.6.4
Got it: I was using <polymer-element> instead of <dom-module>. <dom-module> is correct for Polymer 1.0.
This guide is useful, and has taken me days to find, if only so that you know what works with 0.5 and what works with 1.0:
https://www.polymer-project.org/1.0/docs/migration.html
grunt-vulcanize is not compatible with vulcanize 1.8.1, because last update on github was on Feb 9 with version 0.6.4. It's out of date plugin for Polymer 0.8+.
temporary adaptation for grunt-vulcanize which works with vulcanize ^1.8.1 and Polymer 1.0.
https://github.com/kgadzinowski/grunt-vulcanize/
just change in package.json:
"grunt-vulcanize": "kgadzinowski/grunt-vulcanize"
it'll work fine

How do I generate a list of files in html, using a grunt task?

I am using yeoman, grunt and angularjs and am new to grunt.
I have some content generation that produces something like this, already copied to the dist folder.
/dist/whatever/x/a.html
/dist/whatever/y/b.html
/dist/whatever/x/c.html
I would like to create another html file using a grunt task:
/dist/whatever/index.html
Which contains:
...
<a href="x/a.html">x</x>
<a href="y/b.html">x</x>
<a href="x/c.html">x</x>
...
This html file can exist in my /app folder as a template, and have grunt replace some tokens.
Is there an existing module that does anything like this (looking for files matching a pattern and writing them into existing content)?
solution based on Matt's comment to use grunt-include-source:
Gruntfile.js:
includeSource: {
options: {
basePath: 'dist/whatever',
baseUrl: '',
templates: {
html: {
link: '<li>{filePath}</li>'
}
}
},
whateverIndex: {
files: {
'dist/whatever/index.html': 'app/whatever/index.template.html'
}
}
},
app/whatever/index.template.html
<ul>
<!-- include: "type": "link", "files": "*/index.html" -->
</ul>
grunt-include-source can be used to build sections in HTML that reference css, js and HTML files in a directory or that match a glob.
The docs on github provide a good overview of how the task is configured and works.
Additionally, the answer to this other question provides a little more info.

cssmin not correctly handling #import

I am using cssmin on files containing #imports. cssmin is recursively importing local files correctly, but for imports that point to a URL the imports are left inline. This makes the resulting minified CSS invalid because # rules must be at the beginning of the file. Does anyone know a good solution or workaround to this problem?
I have exactly the same problem with cssmin and #import, and i found a solution with grunt concat:
Create a concat grunt task that:
Put #import url in the begining of mified css file and replaces references of #imports url for "".
Execute task concat:cssImport after cssmin task.
Grunt task Code: to execute (concat:cssImport)
grunt.initConfig({
concat: {
cssImport: {
options: {
process: function(src, filepath) {
return "#import url(http://fonts.googleapis.com/css?family=Roboto:400,300,900);"+src.replace('#import url(http://fonts.googleapis.com/css?family=Roboto:400,300,900);', '');
}
}
},
files: {
'your_location_file_origin/file.full.min.css': ['your_location_file_destination/file.full.min.css']
}
} )}
My inspiration comes from https://github.com/gruntjs/grunt-contrib-concat#custom-process-function.
I added the processImport: false option to grunt.
'cssmin': {
'options': {
'processImport': false
}
}
Use the following process:
Install node-less
import the files by compiling with less first
minify with cssmin
References
node-less
LESS compile error
I had something like this in the styles.scss:
#import url(custom-fonts.css);
My problem was the #import wasn't able to find the files because the root path was missing. Here's what I did with yeoman angular generator Gruntfile.js config:
cssmin: {
options: {
root: '<%= yeoman.dist %>/styles/'
}
},
Useful link grunt-contrib-cssmin issue #75
I know this question for a very long time but i post this for anybody that looking for this issue on stack overflow ... just put your code in /!..../ like this:
/*! * #import url('//fonts.googleapis.com/cssfamily=Roboto:300,400,400i,500,700,700i'); */
it will be include in your destination min css but don't forget to use remote import in top of your page.
Putting the imports at the top of my scss didn't work for me,I ended up importing the external stylesheets directly from the html:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Roboto:400,300"
rel="stylesheet">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
......
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/app.css -->
<link el="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="styles/app.css">

How should I configure grunt-usemin to work with relative path

I have a grunt project backed by a yeoman-generator that I've built based on the generator-webapp, if it's of any help, you can find it on GitHub
The grunt project makes us of the grunt-usemin task.
My project involve building a multilingual website, and to keep things clean, I've decided to put all the pages written in a language in a folder name after the 2-letter shortcode of the said language.
| project/
|--dist/
|----en/
|------index.html
|------404.html
|------...
|----fr/
|------index.html
|------404.html
|------...
The files are made from handlebars templates and processed with assemble. In the layout I have building blocks for usemin such as
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
Which, in a perfect world would translate to
<link rel="stylesheet" href="../styles/main.css">
<script src="../scripts/vendor/modernizr.js"></script>
but instead shows
<link rel="stylesheet" href="styles/main.css">
<script src="scripts/vendor/modernizr.js"></script>
which is less than ideal in my case.
The relevant part of the Gruntfile.js looks like this
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>'
},
html: [
'<%= yeoman.app %>/fr/{,*/}*.html',
'<%= yeoman.app %>/en/{,*/}*.html'
]
},
usemin: {
options: {
dirs: ['<%= yeoman.dist %>']
},
html: [
'<%= yeoman.dist %>/fr/{,*/}*.html',
'<%= yeoman.dist %>/en/{,*/}*.html'
],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
}
I have tried to use the basedir option
by setting it to <%= yeoman.dist %> as well as changing the build blocks to
<!-- build:css(.tmp) ../styles/main.css -->
<link rel="stylesheet" href="../styles/main.css">
<!-- endbuild -->
<!-- build:js ../scripts/vendor/modernizr.js -->
<script src="../bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
But unfortunately wasn't able to get a proper output.
More specifically, the first one didn't change anything, the second one had the folders scripts and styles outputted one level too high in the hierarchy
| project/
|--app/
|--dist/
|--styles/
|--scripts/
instead of
| project/
|--app/
|--dist/
|----styles/
|----scripts/
Would anyone happen to know what to do ? It seems a rather simple usecase but I couldn't find the help I need via Google, GitHub or SO...
I believe that you can achieve what you need in this way:
Html file:
<!-- build:css styles/main.css -->
<link href='../styles/css/style.css' rel='stylesheet' type='text/css'>
<link href='../styles/css/responsive.css' rel='stylesheet' type='text/css'>
<link href="../styles/css/skins/welld.css" rel='stylesheet' type='text/css' id="skin-file">
<!-- endbuild -->
Gruntfile.js
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>/'
},
html: ['<%= yeoman.app %>/snippets/head.html','<%= yeoman.app %>/snippets/tail.html']
},
usemin: {
options: {
dirs: ['<%= yeoman.dist %>/'],
blockReplacements: {
css: function (block) {
return '<link rel="stylesheet" href="../' + block.dest + '"/>';
},
js: function (block) {
return '<script src="../' + block.dest + '"></script>';
}
}
},
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
}
The key solution is in the blockReplacements option of the usemin task. Basically, the task will put your files under <%= yeoman.dist %>/styles/main.css, while your html will be under <%= yeoman.dist %>/en/somefileinEnglish.html and every instance of 'styles/main.css' in this file will be replaced with '../styles/main.css', adding the correct relative path.
As an extra tip, if you are building a multilingual website, you may want to consider grunt-i18n to translate your file while building, so you won't need to maintain a different html file for every language.
I was building my own Grunt scaffolding and I was frustrated by this issue. I managed to create a work around that I'd like to share it with you.
I'd like to use an example of my own to illustrate the reason behind his issue and how I managed to work around. Say my directory structure is the following:
| in/
+---- pages/
| +---- login.html
+---- js/
| +---- s1.js
| +---- s2.js
+---- index.html
| out/
| Gruntfile.js
Where in/ is where all of my source files reside and out/ is dest directory, where all of the output files will be stored. Say I want to import s1.js into login.html, I'd write something like this:
<!-- build:js ../js/login.js -->
<script src="../js/s1.js"></script>
<!-- endbuild -->
In here, usemin block performs a simple string replace so the output path should be exactly where I want to link the output file. The problem occurs when instead of having login.js land at out/js/login.js, useminPrepare end up landing it at js/login.js. The reason behind this is that useminPrepare simply performs a path join between dest (which is out) and the output path (which is ../js/login.js), while it should have performed a path join with respect to where the HTML file is found.
In order to work around this issue, observe that if I set dest to out/pages which respects where login.html is found, it will work out fine. BUT notice that if index.html imports js/s2.js in a similar fashion, then that will get screwed up. So in order to work around THAT, we need to create one useminPrepare target for index.html with dest: "out" and another target for login.html with dest: "out/pages". Hence my useminPrepare config now looks something like this:
"useminPrepare": {
t1: {
dest: "out",
files: [{src: ["in/*.html"]}],
...
},
t2: {
dest: "out/pages",
files: [{src: ["in/pages/*.html"]],
....
}
}
All targets will have to run. Now you will probably say; what if I have even more HTML files under other subdirectories? Does that mean I will have to create one target for each directory where HTML files are found? This is pain in the ass and stupid. It IS! I agree. So I wrote a very special grunt task to help out. I call it useminPreparePrepare I deliberately named it stupidly, because it IS stupid. I'm really hoping to get rid of this work around one day when usemin people fixes this issue. As its name suggests, useminPreparePrepare prepares configs for useminPrepare. Its own configs mirrors useminPrepare (in fact, most configs are simply copied over) with one exception; you will have to add a src property that points to the source root directory where all of your source files reside, so that it can figure out the relative path between your source root and HTML files. It will perform essentially what I mentioned above. Plus, it does the same for staging directory too, so staging files wont' break out of the staging directory. You can even have multiple targets in useminPreparePrepare, it will copy over the options for the target you ran.
In order to use this work around, you will first have to import useminPreparePrepare. I didn't put it on npm, so you will have to just copy and paste it. I don't mind. Then simply rename your useminPrepare config to useminPreparePrepare, and add src property. For the above example, src: "in". Then you need to run useminPreparePrepare with whichever target you'd normally like, then immediately run useminPrepare without specifying target so that all targets will run. Given the above example Grunt config could look something like this:
"useminPreparePrepare": {
html: "in/**/*.html", // All HTML files under in/ and its subdirectories.
options: {
src: "in",
dest: "out",
....
}
},
"copy": {
html: { // Copies all HTML files from in/ to out/ preserving their relative paths.
files: [{
expand: true,
cwd: "in",
src: ["**/*.html"],
dest: "out"
}
]
}
},
"usemin": {
html: "out/**/*.html", // Process all HTML files under out/ and its subdirectories.
...
}
You can see that the above config is simple enough to include all HTML files recursively under the source directory. useminPreparePrepare takes care of all the stupid work arounds while looking just like useminPrepare.
I hope this helps!
My solution was to manually modify grunt-usemin plugin.
Open node_modules/grunt-usemin/fileprocessor.js in you favourite text editor. Somewhere around line 152 find:
if (assetSearchPath && assetSearchPath.length !== 0) {
this.file.searchPath = assetSearchPath;
}
and replace it with:
if (assetSearchPath && assetSearchPath.length !== 0) {
this.file.searchPath.splice(0, 0, assetSearchPath);
}
By default this.file.searchPath is an array containing the absolute path to the current file. There's no point in overwriting it with ['dist'], it's better to prepend the array with 'dist'. This way if an item is not found in 'dist' directory it might be concluded that either the path is relative or it's wrong. Thus we use the second value from the searchPath array to look for the file and if it was a relative path - we get what we wanted.
I used multiple targets as shown below:
useminPrepare: {
target1 : {
src : ['target1/*.html'],
options : {
dest: 'out'
}
},
target2 : {
src : ['target2/folder/*.html'],
options : {
dest: 'out/subfolder'
}
}
},
Then in the HTML block you could this:
<!-- build:js ../subfolder/script.js -->
<script src="../subfolder/scripts/main.js></script>
<!-- endbuild -->
I have seen many questions about this and no real answers. In my project I have mapped the "dist" folder to "/static" server side. So I don't need to figure the relative path in index.html.
But still, the issue remains with usemin
<!-- build:css(.tmp) static/css/main.css -->
<link rel="stylesheet" href="css/main.css">
<!-- endbuild -->
the usemin file will be written in dist/static/css/main.css
and the the HTML will show the wrong (but expected) path
<link rel="stylesheet" href="static/css/main.css">
The only workaround I have found is to not touch the usemin block, run grunt and update the path manually.
If I'm understanding your question correctly I think you need the 'root' option:
{
useminPrepare: {
html: 'html/index.html',
options: {
root: 'app'
dest: 'dist'
}
}
}
Though index.html is in the html/ folder the files lookup will be from app/ not html/
I make the usemin blocks relative to the template.
I have a structure like this:
app/ - webroot source (devmode)
app/views/layouts - layouts for server-generated pages (also has usermin tags init)
app/js - source javascript
dist/ - production build dir
I make my html look like this in app/layouts/main.html:
<!-- build:js js/static.min.js -->
<script src="../../js/controllers/StaticCtrl.js"></script>
<script src="../../js/directives/backImg.js"></script>
<script src="../../js/smooth-scroll.js"></script>
<!-- endbuild -->
on dev (no usemin, just serving files) "../../" cleverly just resolves to "/", so it still works. This way you don't need to preprocess while you are developing (with watch tasks or whatever.)
useminPrepare: {
loyalty: {
src: '<%= loyalty.app %>/Views/index.tpl',
options: {
dest: '.',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
}
},
<!-- build:css /resources/v4/css/loyalty/index.css -->
<link rel="stylesheet" href="../Resources/css/main.css">
<link rel="stylesheet" href="../Resources/css/product.css">
<link rel="stylesheet" href="../Resources/css/use_code.css">
<!-- endbuild -->
use '.' as destination in gruntfile.
I make a bug fix for the relative path.
https://www.npmjs.com/package/grunt-usemin-fix
You can copy and past the change to source of use-min to use the relative path

Resources