Grunt watch less files in dynamic path - javascript

Good day!
As I can configure grunt to monitor a dynamic path, I explain, I have a path (/module/[namemodule]/assets/*.less), in the namemodule part it changes, it can be anything (name) how can I have the assets folder of all the modules monitored ?, now, the destination will also change, it will not be in assets, it will be public (/module/[namemodule]/public/*.css), the truth is that it is the first time I use grunt and I'm lost
Thanks for replying, I have this in my gruntfile.js...
less: {
developmen: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: {
"/modules/**/public/*.css": "/modules/**/assets/*.less"
}
}
}
and even then you can not compile the file less, grunt returns the following message.

Please see Globbing Patterns.
Double splat ** should do what you need.
UPDATE Not a valid key value pair methinks
files: {
"/modules/**/public/*.css": "/modules/**/assets/*.less"
}
Try using an absolute path for the first argument and see what happens.

Related

How to make couple of minified files from different js files using grunt

I am new to grunt and task runners in JS, so this might seem a simple question but I have been unable to find exact working answer.
I have :
concat: {
options: {
// define a string to put between each file in the concatenated output
separator: '\n\n'
},
dist: {
// the files to concatenate
src: ['scripts/app.js', 'scripts/constant.js'
],
// the location of the resulting JS file
dest: 'scripts/custom.js'
}
},
This task collects all my custom file together. What I want is to do similar thing for all my vendors file. Finally I should end up with two js only custom.js having my concatenated-minified code and vendor.js having concatenated-minfied libraries.
How do I write grunt configuration for this. Do I need to make two different tasks. If I write the above code twice with different input files, it seems to run the last code.
grunt-contrib-concat can be configured to utilize multiple-targets.
For further documentation on this subject refer to multi-tasks and Task Configuration and Targets in the grunt documentation.
Gruntfile.js
For your scenario you need to configure your concat task similar to this (Note: the new custom and vendor targets):
module.exports = function(grunt) {
grunt.initConfig({
concat: {
options: {
separator: '\n\n'
},
custom: {
src: ['scripts/app.js', 'scripts/constant.js'],
dest: 'scripts/output/custom.js'
},
vendor: {
// Modify the src and dest paths as required...
src: ['scripts/vendor/foo.js', 'scripts/vendor/baz.js'],
dest: 'scripts/output/vendor.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('concatenate', [
'concat:custom', // <-- Targets in a task are called using a colon separator.
'concat:vendor'
]);
};
Running concat
Using the example gist provided above you can run the concat task via the CLI by typing the following command:
$ grunt concatenate
Configuring Options
If you require different configuration options for both the custom and vendor targets you will need to move the options object inside their respective targets. As explained here.
Note: Using the example gist provided the options specified will apply to both targets.

Destination not defined error on grunt replace

I am trying to use grunt replace to change the names of files and add a random number to the file to prevent caching of images, css and js files.
So I am running the following code
module.exports = function replace(grunt) {
var randomVersion = ((new Date()).valueOf().toString()) + (Math.floor((Math.random() * 1000000) + 1).toString());
var replace = {
options: {
variables: {
'randomVersion': randomVersion
},
overwrite: true
},
files: [{
src: './target/dist/index.html',
dest: './target/dist/index.' + randomVersion + '.html'
}]
};
console.log(randomVersion);
grunt.config.set('replace', replace);
};
but all I get back is a "Destination is not defined
Can anyone shed any light on this?
Thanks
I am not completely certain about what your code is trying to achieve, but I will proceed to answer according to my understanding.
First, are you trying to use the grunt-replace library? If so, I think this is incorrect. This library is for replacing values within the contents of source files, and not the file paths themselves.
It looks to me that what you want to do is to copy your source index.html file to a file path with a unique identifier in it. You may be trying to wrap this in a custom task, but doing so is not necessary.
The following is a sample Gruntfile.js of how I would achieve this task. Note that this solution requires the installation of the grunt-contrib-clean and grunt-contrib-copy libraries.
module.exports = function (grunt) {
grunt.initConfig({
clean: {
dist: ['./target/dist/index.*.html']
},
copy: {
dist: {
src: './target/src/index.html',
dest: './target/dist/index.<%= Date.now() %>.html'
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['clean', 'copy']);
};
There are a few things about this solution that are worth pointing out:
The index.html file is not in the /dist folder because it is not
intended for distribution, but is, rather, a source.
Before creating new versions of index.*.html, we will delete any
existing versions in the /dist folder so that we don't have an
accumulation of each version.
Instead of using a "random" number for our versions, we will use a
timestamp. This is helpful because each version will have a greater
number than the one before it.

Grunt + Concat + Angularjs

Setup:
A Gruntfile with the following task:
concat: {
build: {
files: {
'build/app.js': [
'src/.js',
'src//.js',
'!src/vendors/'
],
}
}
A lot of angular modules, with its controllers, services, and so on, with a structure like this:
a/
a.js // Module declaration like: angular.module('a',[])
a-controller.ks // Which sets a controller in its root module definition like: angular.module('a').controller()...
Issue:
The task concatenates all the js files it finds in the build folder to a single app.js file, and it does this fine, but messes up with the order of files when concatenating.
For instance, it concatenates first the controller file instead of the main folder file containing the module declaration, triggering the following error:
Module xxxx not available!
I suppose the issue lies in the way concat builds up the files and that is done by the grunt core and specifically the minimatch library, and the possibility it treats dashes to be first than letters, but I don't know how configure to change that behavior, and even know if that is possible.
Question:
So, the question is: How can I make Grunt/Grunt-concat to process dashed f first than the others in the same folder so the ordering is maintained?
Thanks
Update 1:
After digging more, It seems that it has nothing to do with the ordering inside a folder, but Grunt/Core sending the root files to the end and putting them the leaf ones first.
Just specify the order you want to concat your files, placing them in order, what I mean is, first add your single files that should be concatenated at start, after your full folder that does not need to have an order, and finally your final files, something rougth like this:
grunt.initConfig({
concat: {
js: {
src: ['lib/before.js', 'lib/*', 'lib/after.js'],
dest: 'bundle.js',
}
}
});
You will have to specify to the grunt-concat task the order you want your files built. For my projects, I typically keep a folder structure where controllers go in a app/controllers folder, services in services, and etc, but names can vary. I also keep an app.js that declares my app module and specifies the config handler for it. I use a config like this for grunt-uglify but the same can be done for concat with little to no changes:
uglify: {
development: {
files: {
'public/scripts/app.js': [
'public/app/app.js',
'public/app/controllers/*.js',
'public/app/directives/*.js',
'public/app/services/*.js'
]
}
}
}
I just copy paste my answer, the detail you want on second picture, i hope help you.
you may consider this solution
Separate the module declaration to xxx.module.js
In grunt-contrib-concat modify the config like below :
place this outside grunt.initConfig
var clientApp = './app/';
grunt-contrib-concat config
dist: {// grab module first, state the second
src: [
clientApp+'**/*-controller.js',
clientApp+'**/*.module.js',
clientApp+'**/*.state.js',
clientApp+'**/*.js'
],
dest: 'dist/<%= pkg.name %>.js'
}
i use state to so i have to define state too before trying to navigate to any state. This is preview my code, the module declaration is declared fist before anything, then my state. even minified doesnt create any problem.
I hope this help you.
i follow this johnpapa's style guide, your problem might solve there if my solution not work

Dynamically add version number to dest output files w/ grunt

I have a package.json file with our version number, such as:
{
name: "myproject"
version: "2.0"
}
My goal is to dynamically add the version number from the package.json file into the output files. For example, in the javascript I don't want to manually update the version number, but would like something similar to this to be generated after each grunt build:
/* My Project, v2.0 */
window.myProject = {
version: "2.0"
};
Is there an easy way to do this in my Gruntfile.js configuration?
I implemented: https://github.com/erickrdch/grunt-string-replace
In my source css/js files, I use the text {{ VERSION }} which gets replaced with the version number set in the package.json file. Below is the config I added to Gruntfile.js.
'string-replace': {
version: {
files: {
// the files I did string replacement on
},
options: {
replacements: [{
pattern: /{{ VERSION }}/g,
replacement: '<%= pkg.version %>'
}]
}
}
},
pkg: grunt.file.readJSON('package.json'),
I think that what you only want to do is to put some kind of trick for unable the page to use the cache files that maybe the browser have, and by now, the only way for that cross-browser is putting something on the href urls like "app.v2_2.js" or "app.js?ver=22". So I use this grunt npm package:
https://www.npmjs.org/package/grunt-cache-breaker
By default it only adds a parameter to your javascript and in almost the cases is the thing you need for not using cache, but you can configure even if you change the name of the file in other grunt process. This only change the HTML headers to what you desire.
After you install the grunt-cache-breaker, add this to your GruntFile:
// Append a timestamp to 'app.js', 'controllers.min.js' which are both located in 'index.html'
// resulting in the index the call of : href="~/app.js?rel=1415124174159"...
cachebreaker: {
dev: {
options: {
match: ['app.js', 'styles.css']
},
files: {
src: ['dist/index.html']
}
}
},
Then where you load the modules:
grunt.loadNpmTasks('grunt-cache-breaker');
Add on the task you want to:
grunt.registerTask('deploy', [
'clean:app',
'copy:views',
'copy:imgs',
'copy:css',
'uglify:app',
'cssmin:app',
'cachebreaker:dev'
]);
And finally run the grunt action on the console/command prompt
> grunt deploy
I would suggest using the banner feature in grunt-contrib-concat
this can be done as well with the banner option of https://github.com/gruntjs/grunt-contrib-uglify - which takes also care of the minifiaction of the javascript files.
filerev provides this option now. Use process to manipulate the filename that will be otherwise suffixed with md5 hash of the file content. You can use this to insert your version to every file you want.
Ref: https://github.com/yeoman/grunt-filerev
create something like package.json in the root of your project
it should read that or you can do something like
pkg: grunt.file.readJSON('package.json'),
in that you'll have a version declaration which would obviously correspond to <%= pkg.version %> so have that string in your json output and then run grunt.config.process to do the variable replacement
do something similar for the comment header

Flattening of File Tree when using Grunt Copy Task

Not sure if I'm missing something but I have the following grunt setup for grunt-contrib-copy tasks.
copy: {
build: {
files: {
"server-dist/": "server/**/*.!(coffee)",
"client-dist/": "client/**/*.!(coffee)"
}
}
}
The client-dist copies as I expect recursively running through the file tree but the server-dist all sub-folders get flattened to the base folder. Any ideas why this is happening? Here is the i/o
server/
views/
errors/
404.jade
layouts/
base.jade
becomes
server/
errors/
layouts/
base.jade
the views folder gets completely blown out. One more thing...when I removed !(coffee) it works but I need to exclude coffee files since I have a grunt-coffee watch task running.
A followup to zacks comment:
copy: {
mytask: {
files: [
{expand:true, cwd:'dev-js/abc/', dest:'js/test/', src:['def.js']}
]
}
}
This copies the file ./dev-js/abc/def.js to ./js/test/def.js - at least on my 0.4.1 version. Zacks comment and the link included was very helpful, especially the fact, that basePath has been replaced.
Apparently the grunt-contrib-copy task has a sophisticated logic that's trying to automatically detect the base directory for copying source files (see related issue)
The solution is to explicitly specify the basePath option:
copy: {
build: {
files: {
"server-dist/": "server/**/*!(.coffee)"
},
options: {
basePath: 'server' // base directory in the source path
}
}
}
P.S. I'm not sure, however, why removing !(.coffee) changes the behaviour for you. I tried the same on my local machine and get the same results when specifying "server/**/*" instead of "server/**/*.!(coffee)" (i.e. the views folder is skipped)

Categories

Resources