Create subtasks that override `options` but use task level `src` - gruntjs

My gruntfile thus far
uglify: {
src: [
...
],
dest: 'js/application.min.js',
options: {
'compress': {},
'reserveDOMCache': true,
'enclose': undefined,
'exportAll': false,
'expression': false,
'preserveComments': false,
'report': 'min',
'sourceMap': false,
'sourceMapIn': undefined,
'sourceMapIncludeSources': false,
'sourceMapName': undefined,
'wrap': undefined
},
development: {
options: {
'beautify': false,
'mangle': true
}
},
production: {
options: {
'beautify': true,
'mangle': false
}
}
}
However when I run the task uglify:development it will respond with No files created.

As far as I know this is not possible. You need to explicitly define a src for each target.
You could declare a variable outside of the config and add it to each target:
var mySources = ['file1.txt', 'file2.txt']; //declared outside config
development: {
src: mySources, //add variable to each target
Or you can declare a variable inside the config:
mySourcesInside: ['file1.txt'], //declared within config
development: {
src: '<%= mySourcesInside%>', //reference variable in each target
Alternatively you could use something like grunt-override-config https://github.com/masakura/grunt-override-config and declare just one uglify target and overrides for the options.

Related

How to use array variable properly in gruntfile.js

Trying to use a predefined array inside of a grunt file, thought using this.js_paths would work, but doesn't seem to work as I'm getting the error, "Cannot read property IndexOf of undefined" when it comes to trying to uglify the scripts. How can I link the js_paths variable to the files src property properly instead of copying the array into the files. Would like to define it separately at the top. Is this possible?
module.exports = function(grunt) {
// loadNpmTasks from package.json file for all devDependencies that start with grunt-
require("matchdep").filterDev("grunt-*", './package.json').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
js_paths: [
'inc/header1/js/*.js',
'!inc/header1/js/*.min.js',
'inc/header2/js/*.js',
'inc/header2/js/*.js',
'!inc/header2/js/*.min.js',
'js/*.js',
'!js/*.min.js'
],
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: this.js_paths,
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
watch: {
scripts: {
files: ['inc/header1/js/*.js', 'inc/header2/js/*.js', 'js/*.js'],
tasks: ['uglify'],
options: {
spawn: false,
}
}
}
});
grunt.registerTask('default', ['uglify', 'watch']);
};
Preferrably would like to use the same array js_paths in the watch files (since it's required there), if that makes sense? Still kinda new to using gruntfile.js
Utilize the Templates syntax. It's described in the docs as following:
Templates
Templates specified using <% %> delimiters will be automatically expanded when tasks read them from the config. Templates are expanded recursively until no more remain.
Essentially, change this.js_paths to '<%= js_paths %>' in your uglify task.
For instance:
// ...
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: '<%= js_paths %>', // <-----
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
// ...
Likewise for your watch task too.
For instance:
watch: {
scripts: {
files: '<%= js_paths %>', // <-----
tasks: ['uglify'],
options: {
spawn: false,
}
}
}

How to execute multiple targets with different options in grunt-contrib-jshint

Goal: to flex the execution of jshint to output results to the console (if in development) or to a file (if being released/in Jenkins).
Is it possible? I can add individual targets to my jshint settings, but all of my options are the same except for the reporter details. So it'd be nice to not duplicate those. I need to do the concatenation from "all" and use all of the global options and the specific options from the target that is called. How?
jshint.js:
module.exports = {
options: {
node: true,
browser: true,
blah: blah...
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/modules/**/*.js',
'<%= yeoman.app %>/*.js'
],
dev: {
options: {
reporter: 'checkstyle'
}
}
release: {
options: {
reporter: 'checkstyle',
reporterOutput: 'myfile.xml'
}
}
};
I hope this can help you, its just a sample you can improve the code.
install : grunt-contrib-jshint
Gruntfile.js
//Jshint ===============================
var jshint;
config.jshint = jshint ={};
jshint.dist = {
options: {jshintrc: ".jshintrc"},
files: {all: ["lib/main.js","lib/test.js"]}
};
jshint.dev = {
options: {jshintrc: ".jshintrc.dev"},
files: {all: ["lib/main.js","lib/test.js"]}
};
.jshintrc
{
"strict":true,
"laxcomma":true,
"sub":true
}
.jshintrc.dev
{
"strict":true,
"laxcomma":true,
"sub":true,
"debug":true
}
If you have a subset of options that will be the same between two targets, you can create a variable for the object and assign its value to both target's option key:
var reporterOptions = {
foo: 'red',
bar: 'green',
baz: 'blue'
};
module.exports = {
options: {
node: true,
browser: true,
blah: blah...
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/modules/**/*.js',
'<%= yeoman.app %>/*.js'
],
dev: {
options: reporterOptions
}
release: {
options: reporterOptions
}
};
If you want to maintain your option values in one place, but want to selectively decide which options are applied to which targets, you can reference the values stored in the variable using dot notation.
var reporterOptions = {
foo: 'red',
bar: 'green',
baz: 'blue'
};
module.exports = {
options: {
node: true,
browser: true,
blah: blah...
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/modules/**/*.js',
'<%= yeoman.app %>/*.js'
],
dev: {
options: {
foo: reporterOptions.foo
bar: reporterOptions.bar
}
}
release: {
options: {
foo: reporterOptions.foo
baz: reporterOptions.baz
}
}
};
I ended up going the variable route but using that for the files source and then overriding the necessary options in the targets.
var files = [
'Gruntfile.js',
'<%= yeoman.app %>/modules/**/*.js',
'<%= yeoman.app %>/*.js'
];
module.exports = {
options: {
reporter: require('jshint-stylish'),
node: true, ...
},
dev: {
src: files
},
release: {
src: files,
options: {
reporter: 'checkstyle',
reporterOutput: 'myfile.xml',
reporterOutputRelative: false
}
}
}
Based on other things I had read, I didn't think the default options would work in the targets and allow overriding, and I also had encountered problems with the files, but this solved everything.

Gruntjs not correctly inheriting options in task

Below is a part of my Gruntfile. Running '$grunt msbuild:migrate:local' works fine, but '$grunt msbuild:migrate:dev' doesnt seem to be pulling in my ConnectionString property. Am I organizing things correctly for the options in inherit correctly?
msbuild: {
src: ['Web Platform\Web Platform.csproj'],
options: {
projectConfiguration: 'Dev',
targets: ['Clean', 'Rebuild'],
maxCpuCount: 4,
verbosity: 'minimal',
stdout: true,
buildParameters: {
WarningLevel: 2,
DeployOnBuild: false,
Configuration: 'Dev',
},
},
migrate: {
// Defaults -----------------------------------------
src: ['Migrate.msbuild'],
options: {
targets: ['Migrate'],
buildParameters: {
DryRun: 'False',
Verbose: 'False',
RollbackSteps: '1',
},
verbosity: 'minimal',
},
// Tasks -----------------------------------------
local: {
// Uses defaults from above (I hope)
},
dev: {
options: {
buildParameters: {
ConnectionString: 'Data Source=<%= credentials.aws_rds_hostname %>,1433;Initial Catalog=DevDatabase;User ID=<%= credentials.aws_rds_admin_username %>;Password=<%= credentials.aws_rds_admin_password %>'
}
}
}
}
}
Grunt doesn't support deeply nested tasks. The only thing that can run here is "grunt msbuild:migrate" (inheriting the global configuration, overridden by its own config)
See this ticket for example.

jshint grunt exported options

Hi I'm trying to achieve the following. I'm using grunt for jshint validating.
Somewhere in a file I have used:
var logger = function () {
// some ode
}
Because logger is never actually used jshint correctly shows me the following error.
W098: 'logger' is defined but never used.
I could set unused to false and it would work perfectly. But I actually want the option to take place in other files and warn me about unused variables. So the unused option is not gonna work for me.
I also saw that I could use a inline comment like this:
* exported EXPORTED_LIB */
But I would actually prefer to avoid cluttering my files with such comments. Is there any chance I can specify an exported options in my grunt file like I can for example for globals.
Heres the jshint part of my gruntfile:
jshint: {
// global options
options: {
camelcase: true,
curly: true,
eqeqeq: true,
forin: true,
immed: true,
indent: 4,
latedef: true,
newcap: true,
noarg: true,
nonew: true,
plusplus: false,
quotmark: 'single',
undef: true,
unused: true,
strict: true,
maxparams: 4,
maxdepth: 4,
trailing: true,
maxlen: 120,
browser: true,
node: true
},
server_logger: {
src: [BASE_PATH_SERVER_LOGGER, '/**/*.js'].join(''),
options: {
browser: false
}
},
client_logger: {
src: [BASE_PATH_CLIENT_LOGGER, '/**/*.js'].join(''),
options: {
node: false,
devel: true
}
}
}
Thanks for your time.
Best regards
Playerwtf
UPDATE: I made an issue on jshint github repository here
This was recently fixxed and works now as I would expect it.
github-issue
As an example I use it like this in my gruntfile
client_logger: {
expand: true,
cwd: BASE_PATH_CLIENT_LOGGER,
src: '**/*.js',
options: {
node: false,
devel: true,
globals: {
logger: true,
expect: true,
it: true,
describe: true,
beforeEach: true,
afterEach: true
},
exported: ['logger']
}
}
But the npm module was not yet updated. If you want this to work you will have to manually copy the newest version from the jshint github repository and replace the one in the current module or wait until it is updated.
i think you can exclude files in your src-files, so you could exclude your logger file from your basic linting (i suppose the logger file is logger.js here), and lint the logger file separatly with the unused-flag turned off.
read more about that here -> "! at the beginning of a pattern will negate the match"
you could set the cwd (and leave the join stuff). see more about that in the docs: Building the files object dynamically
jshint: {
// global options
options: {
... your global options here
},
server_logger: {
options: {
browser: false
},
files: [{
cwd: BASE_PATH_SERVER_LOGGER,
src: ['/**/*.js', '!logger.js']
}]
},
client_logger: {
options: {
node: false,
devel: true
},
files: [{
cwd: BASE_PATH_CLIENT_LOGGER,
src: ['/**/*.js', '!logger.js']
}]
},
lint_logger: {
options: {
unused: false
},
files: [{
src: ['logger.js']
}]
}
}
not 100% sure if that works, but i think it should at least lead you into the right direction. if you need to specify a path and not only a file for excluding you could put your logger-file in a separate folder an just exclude that folder!

Specifying Whitespace Only option for UglifyJS2

I am trying to use grunt for minifying javascript files in a project using UglifyJS2.
Does UglifyJS2 have any options like WHITESPACE_ONLY ( which exists in Closure Compiler)?
What are the values do I have to pass in options node in GruntFile.js for that effect?
uglify: {
options: {
mangle: { toplevel: false },
squeeze: { dead_code: false }
},
'dist': {
src: '**/*.js',
dest: '**/*.js'
}
}

Resources