Concatenating php files and Javascript with Grunt.js - gruntjs

I am having an issue trying to get my Grunt.js file to work. Currently I have it set up to just concatenate all my php function files, and decided since a lot of my work projects use Bootstrap, to concatenate only the javascript files I'll be using. However, when I set it up, hoping I did set it up correctly, my grunt execution does not create/edit the javascript final destination file, nor the php functions file. I am not sure what I have done incorrectly but here is the following code:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
js: {
options: {
separator: 'rn'
},
dist: {
src: [
// Comment or uncomment any Bootstrap JS files
// you will not be using
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/alert.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/button.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/carousel.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/collapse.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/dropdown.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/modal.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/phantom.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/popover.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/qunit.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/scrollspy.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/tether.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/tab.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/tooltip.js'
],
dest: 'wp-content/themes/base_theme/assets/js/required/bootstrap/bootstrap.min.js'
}
},
php: {
options: {
stripBanners: true,
separator: '\n?>\n',
},
dist: {
src: [
// To create a new location, follow pattern below
// Comment out what you don't need a re-concat
'wp-content/themes/base_theme/assets/functions/basic.php',
'wp-content/themes/base_theme/inc/custom-header.php',
'wp-content/themes/base_theme/inc/customizer.php',
'wp-content/themes/base_theme/inc/extras.php',
'wp-content/themes/base_theme/inc/jetpack.php',
'wp-content/themes/base_theme/inc/template-tags.php',
'wp-content/themes/base_theme/inc/wpcom.php',
'wp-content/themes/base_theme/assets/functions/bootstrap-nav.php',
'wp-content/themes/base_theme/assets/functions/enqueue.php'
'wp-content/themes/base_themey/assets/functions/custom-post-type.php',
'wp-content/themes/base_theme/assets/functions/internal-template.php',
'wp-content/themes/base_theme/assets/functions/custom-taxonomy.php',
'wp-content/themes/base_theme/assets/functions/acf.php',
'wp-content/themes/base_theme/assets/functions/custom.php'
'wp-content/themes/base_theme/assets/functions/custom-sidebar.php'
],
dest: 'wp-content/themes/base_theme/functions-mod.php'
}
}
}
});
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-concat');
// Default task(s).
grunt.registerTask('default', ['concat']);
};
My package.json is the following (I know I'm not using jshint or uglify as of yet in my grunt.js, I am just testing one at a time).
{
"name": "base_theme",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-concat": "~1.0.0",
"grunt-contrib-jshint": "~0.8.0",
"grunt-contrib-uglify": "~0.2.7"
}
}
I've tried reading through the documentation on grunt's website, but either I"m not understanding something correctly, or I am just doing something completely wrong

Your config for Gruntfile.js is almost correct.
To fix it, simply avoid nesting src and dest in a dist object for both the js and php targets. For example:
Updated Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
js: {
options: {
separator: 'rn'
},
//dist: { <-- REMOVE the 'dist' object.
src: [
// Comment or uncomment any Bootstrap JS files
// you will not be using
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/alert.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/button.js',
'wp-content/themes/base_theme/assets/js/required/bootstrap/plugins/carousel.js'
// ...
],
dest: 'wp-content/themes/base_theme/assets/js/required/bootstrap/bootstrap.min.js'
},
php: {
options: {
stripBanners: true,
separator: '\n?>\n',
},
//dist: { <-- REMOVE the 'dist' object here too.
src: [
// To create a new location, follow pattern below
// Comment out what you don't need a re-concat
'wp-content/themes/base_theme/assets/functions/basic.php',
'wp-content/themes/base_theme/inc/custom-header.php',
'wp-content/themes/base_theme/inc/customizer.php'
// ...
],
dest: 'wp-content/themes/base_theme/functions-mod.php'
}
}
});
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-concat');
// Default task(s).
grunt.registerTask('default', ['concat']);
};
Further info:
Take a look at the example config for multiple-targets in the grunt-contrib-concat documentation and Task Configuration and Targets in the grunt documentation for further info.
Note: If you encounter any issues when you uglify the concatenated resultant files you may need to include a semicolon in your separator values. See here for more info. It reads:
Concatenated files will be joined on this string. If you're post-processing concatenated JavaScript files with a minifier, you may need to use a semicolon ';\n' as the separator.

Related

Grunt kill watch session & use variables in grunt file names

I am using grunt-contrib-watch and this sublime package sublime-grunt.
I am using the sublime-grunt package to start a watch session and livereload with the Chrome extension. Everything works great however once a 'watch' session is started what is the command to stop/kill/cancel a watch. I tried using a command in the sublime-grunt package called 'Grunt Kill Running Processes' and it tells me something has been canceled but if I change my style.scss file and save it, it compiles and updates are made to my html page, so 'watch' is still in effect. Right now I have to close down Sublime Text to kill the 'watch' session.
I am trying to use a variable for a path to my theme root directory but when I try to concat the variable with a string I received this error. What type of syntax should I use, do I need to create a variable in the package.json file?
Code
var theme_path = 'wp-content/themes/twentyfifteen/';
// Sass plugin
sass: {
dist: {
files: {
theme_path + 'style.css': theme_path + 'sass/style.scss',
}
}
},
// Error
Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: C:\wamp\www\grunt\Gruntfile.js:31
>> theme_path + 'style.css': 'wp-content/th
emes/twentyfifteen/sass/style.scs
>> ^
>> Unexpected token +
Warning: Task "default" not found. Use --force to continue.
Here is my Gruntfile.js:
module.exports = function(grunt) {
// Theme Directory Path
var theme_path = 'wp-content/themes/twentyfifteen/';
// Configure main project settings
grunt.initConfig({
// Basic settings and info about our plugins
pkg: grunt.file.readJSON('package.json'),
// Watch Plugin
watch: {
sass: {
files: 'wp-content/themes/twentyfifteen/sass/*.scss',
tasks: ['sass','postcss','uglify'],
options: {
livereload: true,
},
},
},
// Sass plugin
sass: {
dist: {
files: {
'wp-content/themes/twentyfifteen/style.css': 'wp-content/themes/twentyfifteen/sass/style.scss',
}
}
},
// Postcss plugin
postcss: {
options: {
map: true, // inline sourcemaps
// or
map: {
inline: false, // save all sourcemaps as separate files...
},
processors: [
require('pixrem')(), // add fallbacks for rem units
require('autoprefixer')({browsers: 'last 2 versions'}), // add vendor prefixes
require('cssnano')() // minify the result
]
},
dist: {
src: 'wp-content/themes/twentyfifteen/style.css'
}
},
// Minify JS Uglify
uglify: {
dist: {
files: {
'wp-content/themes/twentyfifteen/js/functions.min.js': ['wp-content/themes/twentyfifteen/js/functions.js']
}
}
}
});
// Load the plugin
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-uglify');
// Run plugin
grunt.registerTask('default', ['watch'] );
}
I think that tasks options can't have variable assigned, i don't have any source at the moment but i can suggest another way to do it:
you can use task params:
watch: {
sass: {
files: '<%= grunt.task.current.args[0] %>/sass/*.scss',
tasks: ['sass:<%= grunt.task.current.args[0] %>','postcss','uglify'],
options: {
livereload: true,
},
},
},
sass: {
dist: {
files: {
'<%= grunt.task.current.args[0] %>/style.css': '<%= grunt.task.current.args[0] %>/sass/style.scss',
}
}
},
and than
grunt.registerTask('default', ['watch:'+theme_path] );
This is a problem that i have already meet to make dynamic watch tasks

Grunt concat no errors but doesn't works

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"
},
},

Grunt task arguments do not work

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']);
});

Handle dependent files with Grunt and rewrite paths

This is my Gruntfile.js (assets is the Bower folder):
module.exports = function(grunt) {
grunt.initConfig({
distFolder: 'dist',
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';',
},
dist: {
src: [
'assets/jquery/dist/jquery.js',
'assets/jquery-ui/ui/jquery-ui.js',
'assets/jsplumb/dist/js/jquery.jsPlumb-1.5.5.js'
],
dest: '<%= distFolder %>/main.js',
},
},
uglify: {
dist: {
src: 'dist/main.js',
dest: 'dist/main.min.js',
},
},
cssmin: {
combine: {
files: {
'dist/main.min.css': [
'assets/font-awesome/css/font-awesome.min.css',
'assets/jquery-ui/themes/base/jquery-ui.css',
],
}
}
},
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('build', ['concat', 'uglify']);
};
All works fine, but as I suspected, Font-awesome will lose it's connection with its fonts when using grunt-contrib-mincss.
Can I automate with Grunt that it will do something like;
Copy font files from assets/font-awesome/fonts/ to dist/fonts/
Rewrite url(../fonts/ to url(fonts/
Thanks in advance!
fonts, images, #imports in bower components or vendors may be relative or absolute depend on the component itself, you should config your cssmin task to rewrite relative resources to a correct path in dist path.
using following code, all resources urls will be rewritten using absolute urls.
cssmin: {
options: {
root: 'app'
},
combine: {
files: {
'dist/main.min.css': [
'app/bower_components/lib1/main.css',
'app/bower_components/jquery-ui/themes/base/jquery-ui.css',
]
}
}
}
it's important to set the root option to the base path of your input files. in your case I'm believe you should set the root option to "/" or ""
If you tell me your project structure, I can help more.
I though your project structure is something like this
/
/assets
/other_files
/dist

Grunt SCSS - Not reloading

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

Resources