Using grunt-ts on my project, here is my Gruntfile:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
ts: {
build: {
src: ['ts-src/**/*.ts'],
//compile using the requirejs module style
module: 'amd',
//write generated files to ts-out directory
outDir: '../js/ts-out',
amdloader: 'loader.js',
//generate a reference file
reference: 'reference.ts',
//generate .d.ts files
declaration: true,
options: {
comments: true, //preserves comments
target: 'es5' //emit ECMAScript5 JS
}
}
},
watch: {
files: ['<%= ts.build.src %>'],
tasks: ['ts']
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ts');
grunt.registerTask('default', ['watch']);
}
This "works", but it is generating a loader.js file that incorrectly prepends the outDir value onto the entries in the file. This results in a path for each file that contains js/ts-out, twice.
Does the amdloader option have configuration options, where I can override this?
I suspect it should be :
outDir: '../js/ts-out',
amdloader: '../js/ts-out/loader.js',
See : https://github.com/grunt-ts/grunt-ts/blob/master/Gruntfile.js#L101-L117 i.e.:
amdloadersrc: {
test: true,
src: ['test/amdloader/ts/app/**/*.ts'],
html: ['test/amdloader/ts/app/**/*.html'],
reference: 'test/amdloader/ts/app/reference.ts',
outDir: 'test/amdloader/js/app',
amdloader: 'test/amdloader/js/app/loader.js',
// watch: 'test/amdloader/app'
},
amdloadertest: {
test: true,
src: ['test/amdloader/ts/test/**/*.ts'],
html: ['test/amdloader/ts/test/**/*.html'],
reference: 'test/amdloader/ts/test/reference.ts',
outDir: 'test/amdloader/js/test',
amdloader: 'test/amdloader/js/test/loader.js',
},
amdloader takes an absolute path to the generated JS location
Related
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,
}
}
}
I have setup grunt task to concatenate the CSS files into a combined.css file and it successfully concatenates the CSS files.
grunt.initConfig({
concat: {
options: {
separator: '\n\n\n',
base: "../../../",
},
css: {
src: [ '../../my/demo/v1.0/1.css',
'../../my/demo/v1.0/2css',
'../../my/demo/v1.0/3.css',
],
dest: '../../my/demo/v1.0/combined123.css',
},
});
grunt.loadNpmTasks('grunt-concat-css');
grunt.registerTask('default', ['concat']);
However, I am not able to figure out how should I replace 1.css, 2.css and 3.css in the index.html with the combined123.css file using Grunt.
When manually trying to replacing these css files with the css files in index.html, running the grunt command reverts back the changes made to index.html. When I do the View Source Code for the page in browser, it shows the multiple css files instead of the latest concatenated combined123.css file.
How can I replace these css files with the combined123.css file in the tag of index.html, using the Grunt task.
This is the Gruntfile.js
grunt.initConfig({
root: root,
//concat:css task implemented here as mentioned in above code snippet
connect: {
server: {
options: {
port: grunt.option('port') || 9090,
keepalive: false,
base: "../../../"
}
}
},
open: {
all: {
path: 'http://localhost:<%= connect.server.options.port%>/my/demo/v1.0/dest/index.html'
}
},
watch: {
html: {
files: ['views/*.html', 'index_temp.html'],
tasks: ['mergeFiles']
},
livereload: {
files: ['dest/index.html'],
options: { livereload: true }
}
},
htmlbuild: {
dist: {
src: 'index_temp.html',
dest: '.tmp/',
options: {
beautify: true,
relative: true,
sections: {
headers: 'views/abc.html',
input: 'views/def.html',
}
}
}
},
replace: {
example: {
src: ['.tmp/index_temp.html'],
dest: 'dest/index.html',
replacements: [ {
from: /^\s*\n/gm,
to: ''
},
{
from: /\s+$/,
to: ''
}],
}
});
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-concat-css');
grunt.registerTask('server', ['mergeFiles', 'open' ,'connect', 'watch' ]);
grunt.registerTask('default', ['mergeFiles', 'open' ,'connect', 'watch', 'concat']);
grunt.registerTask('mergeFiles', ["htmlbuild:dist", "replace:example"]);
Any help would be much appreciated.
Hi Grunt concat doesn't shows errors, but it doesn't concentrate my styles.css file. Here is a screenshot of it:
link: http://i.imgur.com/gHlbROe.png
And here is a screenshot of my css file, which still isn't being concatenated(also you can see my folder structure here below):
link: http://i.imgur.com/UlGWQv1.png
And here is my gruntfile.js (Maybe I should have a different separator in concat_css.):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
css: ['concat']
},
files: {
"css/styles.css": "css/styles.less" // destination file and source file
}
}
},
concat_css: {
options: {
// Task-specific options go here.
separator: '}'
},
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},
watch: {
styles: {
files: ['css/styles.less'], // which files to watch
tasks: ['less', 'concat_css'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-concat-css');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less', 'watch', 'concat_css']);
};
I'm pretty sure the task is called concat, not concat_css. You're config will need to match that name (that is, you should not be using concat_css at all). Aside from that, why would you make the separator the closing brace (})? If you ever have more than one file that will almost certainly cause a syntax error in the concatenated CSS file. I would leave out that option unless you have a specific need for it.
concat: { // <-- change this to match the name of the task: "concat"
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},
I'm trying to configure grunt to have 2 tasks (development and production). But for whatever reason, whenever I add an argument, the task gets run (as you will see) but there is not output/action:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dev: {
options: {
// define a string to put between each file in the concatenated output
separator: ';'
},
dist: {
// the files to concatenate
src: [
'public/js/jquery-1.10.2.min.js'
],
// the location of the resulting JS file
dest: 'public/js/aaaaa.src.js'
}
},
prod: {
options: {
// define a string to put between each file in the concatenated output
separator: ';'
},
dist: {
// the files to concatenate
src: [
'public/js/jquery-1.10.2.min.js'
],
// the location of the resulting JS file
dest: 'public/js/bbbbbb.src.js'
}
}
}
});
// Load Plugins
grunt.loadNpmTasks('grunt-contrib-concat');
// Default task(s).
grunt.registerTask('default', ['concat:dev']);
});
Output:
$ grunt
Running "concat:dev" (concat) task
Done, without errors.
The plugin does not support nested targets:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dev: {
// the files to concatenate
src: [
'public/js/jquery-1.10.2.min.js'
],
// the location of the resulting JS file
dest: 'public/js/aaaaa.src.js'
},
prod: {
// the files to concatenate
src: [
'public/js/jquery-1.10.2.min.js'
],
// the location of the resulting JS file
dest: 'public/js/bbbbbb.src.js'
}
}
});
// Load Plugins
grunt.loadNpmTasks('grunt-contrib-concat');
// Default task(s).
grunt.registerTask('default', ['concat:dev']);
});
I am trying to achieve a smooth workflow.
my problem:
My JS modifications are shown and minified and the live reload works fine. When I make changes to my SCSS files they do not run under the run command:
grunt
or the grunt plugin:
grunt watch
It only works when I invoke:
grunt sass
This was the output from the 'grunt sass' console window:
Macintosh:grunt-test Neil$ grunt sass
Running "sass:dist" (sass) task
File "css/global.css" created.
Done, without errors.
Notes:
When I run 'grunt watch' on a sass file I have noticed that grunt runs the minification on the javascript for no reason. Surely this be invoked when that file or one of its dependencies is effected?
Gruntfile.js Contents:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
files: ['css/*.css'],
livereload: true
},
css: {
files: ['css/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
scripts: {
files: ['js/*.js', 'scss/*.scss'],
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
expand: true,
cwd: 'scss/',
src: ['*.scss'],
dest: 'css/',
ext: '.css'
}
},
concat: {
// 2. Configuration for concatinating files goes here.
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
'js/global.js' // This specific file
],
dest: 'js/build/production.js',
}
},
uglify: {
build: {
src: 'js/build/production.js',
dest: 'js/build/production.min.js'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images-lossy/',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/'
}]
},
png: {
options: {
optimizationLevel: 7
}
},
jpg: {
options: {
progressive: true
}
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
// CONCATENATION PLUGIN
grunt.loadNpmTasks('grunt-contrib-concat');
// MINIFY PLUGIN
grunt.loadNpmTasks('grunt-contrib-uglify');
// IMG CRUSH PLUGIN
grunt.loadNpmTasks('grunt-contrib-imagemin');
// GRUNT WATCH PLUGIN
grunt.loadNpmTasks('grunt-contrib-watch');
// SASS LIBARY PLUGIN
grunt.loadNpmTasks('grunt-contrib-sass');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['sass','concat', 'uglify', 'imagemin', 'watch']);
};
I hope the above information helps. I have previously used Codekit, and it a really great app. I want to move to grunt but maybe my configuration file is incorrect I am close.
Any help would be greatly appreciated.
Neil
It looks like both of your issues occur within the watch configuration.
First, the reason the SASS task isn't working during watch is due to the files entry pointing to the wrong location. Your current files entry points to the "css" folder, but it should point to the "scss" folder, according to what you've specified in the actual "sass" task. In other words, your entry should be: files: ['scss/*.scss'].
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
}
Second, the JavaScript minification occurs during the watch whenever a SASS file changes because you have it listed here:
scripts: {
files: ['js/*.js', 'scss/*.scss'], // <-- scss is covered here
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
Change it to files: ['js/*.js'], instead to have the watch task kick in for JavaScript files only.
Once you address those issues, if things are slightly working you might want to expand the patterns so that it covers all files in the subdirectories for your JavaScript, CSS, SASS, etc. For example, js/*.js includes all .js files under the js folder, while js/**/*.js covers the js folder and its subfolders. You can read more under the GruntJS "globbing patterns" documentation.
EDIT: here's how the updated watch should look like...
watch: {
options: {
livereload: true
},
// css is really for Sass
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
// scripts will detect js changes
scripts: {
files: ['js/**/*.js'],
tasks: ['jshint', 'concat', 'uglify'],
options: {
spawn: false,
}
}
},
As mentioned, your individual tasks might need to use the ** pattern similar to what I've done with the "scripts" entry above: js/**/*.js