Grunt: Destination File Same Name as Source File After Templating - javascript

I'm trying to template all of the files in a directory and put the result in bin/admin directory such that the destination file has the same name as the source file. However, it seems like the dest in data is the name of file and cannot be specified as a destination directory.
module.exports = function(grunt) {
grunt.initConfig({
'template': {
'process-html-template': {
'options': {
'data': {
'api_url': 'My blog post'
}
},
'files': {
'bin/admin/': ['src/admin/*'] // <-- Here
}
}
}
});
grunt.loadNpmTasks('grunt-template');
grunt.registerTask('default', ['template']);
}
What can I do to template all of the files in src/ and put them in a destination folder with the same name as the source? I tried to use bin/admin/* as the destination, but that just create a file with the filename * in bin/admin. I want to avoid listing all of the files in the source directory manually.

I figured it out. It's an object with a src and dest attribute.
module.exports = function(grunt) {
grunt.initConfig({
'template': {
'process-html-template': {
'options': {
'data': {
'api_url': 'My blog post'
}
},
'files': [
{
expand:true,
src: 'src/admin/*',
dest: 'bin/admin/'
}
]
}
}
});
grunt.loadNpmTasks('grunt-template');
grunt.registerTask('default', ['template']);
}

Related

Terser does not give minified file

I am trying to minify an angularjs application using grunt and terser. I first used uglifiy-es but then read that it has some issues. So I tried terser. But the output does not give me minified files.
The gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//grunt task configuration will go here
ngAnnotate: {
options: {
singleQuotes: true
},
app: {
files: {
'./public/min-safe/js/_config_min.js': ['./controllers/_config.js'],
'./public/min-safe/js/ctrl_accountingdashboard.js': ['./controllers/ctrl_accountingdashboard.js'],
}
}
},
concat: {
js: { //target
src: ['./public/min/app.js', './public/min-safe/js/*.js'],
dest: './public/min/app.js'
}
},
terser: {
options: {},
files: {
'./public/min/app.js': ['./public/min/app.js'],
},
}
});
//load grunt tasks
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-terser');
grunt.loadNpmTasks('grunt-ng-annotate');
//register grunt default task
grunt.registerTask('default', ['ngAnnotate', 'concat', 'terser']);
}
I had the same problem. According to the documentation, this should work but it didn't for me. Wrapping the "files" setting in a custom target works for me:
terser: {
options: {},
main: {
files: {
'./public/min/app.js': ['./public/min/app.js'],
}
}
}
To add to #Tim's great answer:
Here is an example that allows to run grunt-terser with path / file wildcard patterns (globbing) – which it does not support out of the box.
Please note the helper properties _src and _dest in the terser config which are not read by grunt-terser itself but by the task terser_all. This task expands the globbing pattern(s) in _src and builds the real config in the files property. When done it runs terser with that updated config.
module.exports = function (grunt) {
grunt.initConfig({
terser: {
dist: {
options: {
compress: {
drop_console: true // remove console.log, console.info, ...
}
},
files: {
// FILLED through terser_all task below!
// Examples config:
// "dist/example.js": [ "path/to/files/example.js" ]
// "dist/example_joined.js": [ "path/to/files/*.js" ]
},
// -----
// HELPER PROPERTIES to build the files prop (see above) in the terser_all task below.
_src: [
"path/to/files/*.js"
],
_dest: "dist/"
}
}
});
grunt.registerTask('terser_all', function () {
// work on this target in terser config
var terser_target_name = "dist";
// read the terser config
var terser_config = grunt.config.get('terser') || {};
var terser_target_config = terser_config[terser_target_name] || {};
// get the destination dir
var destDir = terser_target_config._dest;
// loop through all source files and create an entry in the terser config for each of it
var files = grunt.file.expand(terser_target_config._src);
for (const [i, file] of files.entries()) {
grunt.log.writeln(file);
// add this file to the terser config as: dest_file: src_file
terser_target_config.files[destDir + file] = file;
}
// show new config on CLI
grunt.log.writeflags(terser_target_config);
// write back config and run task
grunt.config.set('terser', terser_config);
grunt.task.run('terser');
});
grunt.loadNpmTasks('grunt-terser');
grunt.registerTask('build', ['terser_all']);
grunt.registerTask('default', ['build']);
};
Just a note:
If you try to "disable" some options by renaming this disables the whole process. At least this was my result with grunt-terser. I was left with the original js file.
{
mangleX: {
reserved: [/* ... */]
}
}

compile sass files multiple times with grunt-contrib-concat

EDIT: upon further reflection I believe my question is about grunt-contrib-concat rather than sass.
I have a folder of sass files one of which is called colors.scss
//neutrals
$white: #fff;
$light-gray: #eee;
$gray: #9f9f9f;
$slate: #59595A;
$charcoal: #404041;
$gold: #FFD34E;
//define non-neutral colors by use. These are what would change if our app was whitelabeled.
$bright-accent-color: tint(#FF4849, 0%);
$muted-accent-color: $bright-accent-color;
$dark-accent-color: $bright-accent-color;
$note-color: #FFFAD5;
$bright-warning-color: black; // will this be used in new scheme?
$muted-warning-color: tint(#DB9E36, 20%);
$dark-warning-color: $charcoal;
$light-background-color: #f3f6f9;
$primary-nav-color: #172740; // dark blue
$secondary-nav-color: #263D59; // blue
I would like to produce a dozen sets of compiled css files, of which I would swap out the colors.css file for each compiled set. I'm trying to figure out how to incorporate this into my gruntfile without producing seperate tasks for each one. I would like one task that looks in folder called colors that in turn contains all of the colors.scss files and then for each one does a compilation and puts that compiled set of css files in a folder with the same name as the colors.scss file. The problem is I have no idea where to start. I'm using grunt-contrib-sass currently and I'm able to produce one set of files. My gruntfile looks like this:
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'dist/main.css': 'app/css/main.scss'
}
}
},
which works fine for compiling one set, but I want to iterate over the colors files and produce one set for each file found. is this possible? where should I start?
Think I got it. I edited my gruntfile with the following modules: sass, concat, and copy.
In summary, I concat the specific brand scss file to the main scss file and then copy all of the support files to a sass folder in the dist directory. Then I run sass on the concat'd files and output the final css files to the dist css folder.
Heres the configuration:
module.exports = function(grunt) {
'use strict';
var sassFiles = [];
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['concat', 'copy:sass', 'sass']);
grunt.initConfig({
concat: (function(){
var concat = {
options: {
sourceMap: true
}
};
var files = [];
grunt.file.recurse('app/css/brands/', function(abspath, rootdir, subdir, filename){
files.push(filename);
});
sassFiles = files;
files.forEach(file => {
concat[file] = {
src: [
'app/css/brands/'+file,
'app/css/main.scss'
],
dest: 'dist/css/sass/'+file
};
});
return concat;
}()),
sass: {
dist: {
options: {
style: 'expanded'
},
files: (function(){
var fileObject = {};
sassFiles.forEach(file => {
var filename = file.split('.')[0];
fileObject['dist/css/'+filename+'.css'] =
'dist/css/sass/'+file;
});
return fileObject;
}())
}
},
copy: {
sass: {
files: [
{ expand: true, cwd: 'app/css', src: '**', dest: 'dist/css/sass/' }
]
}
}
});
};

copy JSON files from one dir to another

In my web project I have the following directory structure
|- target
|- foo
|- bar
|- baz
I'm trying to write a Grunt task that will copy all JSON files into the target directory from the directory whose name matches a parameter provided to the build
grunt.registerTask('flavor', function(srcDir) {
var from = './' + srcDir + '/*.json';
var dest = './target/';
grunt.file.expand(from).forEach(function(src) {
grunt.file.copy(src, dest);
});
});
But when I call this with
grunt flavor:foo
I get an error
Warning: Unable to write "./target/" file (Error code: EISDIR). Use --force to continue.
As #DanielApt mentioned, you should just use grunt-contrib-copy. To build on his answer regarding on your comment about build-parameters, you can get them to the task via grunt-option.
Way one: running different target
grunt.initConfig({
copy: {
foo: {
files: [
{
'expand': 'true',
'cwd': 'foo/',
'src': [**],
'dest': 'dist/en'
}
]
},
bar: {
files: [/**/]
},
baz: {
files: [/**/]
}
}
});
var target = grunt.option("target") || "foo";
grunt.registerTask("default", ["copy:" + target]);
// run with grunt --target=foo
Way 2: Arbituary folder with templating:
var target = grunt.option("target") || "foo";
grunt.initConfig({
target: target,
copy: {
default_target: {
files: [
{
'expand': 'true',
'cwd': '<%= target %>/',
'src': [**],
'dest': 'dist/en'
}
]
},
}
});
grunt.registerTask("default", ["copy"]);
// run with grunt --target=anyfolderhere
Do you need to write your own task? If you don't I achieved this with grunt-contrib-copy.
copy: {
default: {
files: [
{
expand: true,
src: ['foo/**', 'bar/**'],
dest: 'target/'
}
]
}
}

Grunt won't process lesscss file

I am trying to concatenate a set of .less files into a big .less file, and then have it processed into a big .css file using Grunt's grunt-contrib-less module.
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
concurrent: {
target1: ['concat:lesscss'],
target2: ['less']
},
concat: {
lesscss: {
files: {
'server/static/css/big.less':
['server/static/css/commons-reset-and-core.css',
'server/static/css/base.less',
'server/static/css/ads.less',
'server/static/css/ext.less']
}
}
},
less: {
files: {
'server/static/css/big.css':
'server/static/css/big.less'
}
}
});
grunt.registerTask('default', ['concurrent:target1', 'concurrent:target2']);
};
The big.less is created properly, but the big.css file is not. Yet, Grunt returns
Done, without errors.
What am I doing wrong?
Did you try to wrap it as here:
less: {
development: {
files: {
'server/static/css/big.css': 'server/static/css/big.less'
}
}
},
I think that's required

Save jade file to html with same name

Trying to get jade to save my jade files as HTML files while keeping the same file name.
So the file views/index.jade should save as dist/index.html
Same for additional files.
I am using grunt-contrib-jade
The jade configuration of my Gruntfile:
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jade: {
compile: {
options: {
pretty: true
},
files: {
'dist/*.html': ['views/*.jade']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.registerTask('default', ['jade']);
};
But it just saves the file as *.html
I think it's doing what you are telling it to do.
Try this for configuration of the jade task:
jade: {
compile: {
options: {
pretty: true
},
files: [{
expand: true, // setting to true enables the following options
cwd: '/jade', // src matches are relative to this path
src: ['{,*/}*.jade'], // matches *.jade in cwd and 1 level down
dest: 'dist/', // destination prefix
ext: '.html' // replace existing extensions with this value
}]
}
}
here is is some information about building file lists dynamically with Grunt.

Categories