How can I use an configuration file (config.json) for easier grunt setup
I want to add/setup all needed plugins in my config.json and I want a seperated file for all Plugins or seperate FOlder for images
config.json
{
"images": {
"pluginA": [
"./faces/*.jpg"
],
"pluginB": [
"./corpes/*.jpg"
]
},
"javascript": {
"pluginA": [
"./faces/*.js"
],
"pluginB": [
"./corpes/*.js"
]
}
}
Gruntfile.js
plugins: grunt.file.readJSON('plugins_config.json')
jshint: {
development: {
files: {
**plugins.javascript**
}
}
}
desired output
dist/
images
pluginA
faces1.jpg
faces2.jpg
pluginB
corpes1.jpg
corpes2.jpg
javascript
pluginA.js
pluginB.js
styles
pluginA.css
pluginB.css
The way you usually access a grunt config is through the method grunt.config(key), so your json file is accessible through grunt.config('plugins').
Unfortunately the config object is initialized by grunt.initConfig, so you can't use it in the call to initConfig itself, which is what you need to do.
Your solution is to use a separate local variable outside initConfig, instead of a config:
module.exports = function(grunt) {
var plugins = grunt.file.readJSON('plugins_config.json');
// ...
grunt.initConfig({
jshint: {
development: {
files: {
src: plugins.javascript.pluginA,
}
}
},
// ...
});
};
Related
Write a grunt file to validate js
files using jshint, minify html files, start the web server and watch the local web server.
Validate js files with jshint.
The source file is located in "src/js".
Minify the html files in "src" folder and place it inside "dest/src" folder with same file
name.
After html minification, setup and run a local web server.
Run the watch task to watch the webserver.
Use the IDE terminal to install
plugins.
Use official grunt plugins only.
Install necessary grunt commands for all the below tasks and make sure the commands are saved in packages.json and try this:
module.exports = function(grunt) {
require('jit-grunt')(grunt);
grunt.initConfig({
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
globals: {
jQuery: true
}
}
},
htmlmin: { // Task
dist: { // Target
options: { // Target options
removeComments: true,
collapseWhitespace: true
},
files: { // Dictionary of files
'dest/src/form.html': 'src/form.html', // 'destination': 'source'
'dest/src/management.html': 'src/management.html'
}
}
},
watch: {
styles: {
files: ['less/**/*.less'], // which files to watch
tasks: ['less'],
options: {
nospawn: true
}
}
},
connect: {
server: {
options: {
port: 9000,
base: 'app',
keepalive: false
}
}
}
});
grunt.registerTask('default', ['htmlmin','jshint','connect','watch']);
};
I've got several projects that each use an identical Gruntfile to run tasks and put the output in their own dist folder. Folder setup:
MyProjects
- Project1
- src
- dist
- Project2
- src
- dist
.....
I can't figure out how to run Grunt at the top level (MyProjects) and still have the output generated in the correct dist folder dynamically.
Is there a way I can have Grunt put the output in the correct dist folder without having to hard code it into the Gruntfile? Something like:
dist: {
files: {
// destination : source js
'<% ProjectName %>/dist/app.js': '<% ProjectName %>/src/app.js'
},
Thanks
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
// Project configuration.
grunt.initConfig({
watch: {
scripts: {
files: ['src/**/*.js'],
tasks: ['browserify', 'file_append', 'concat'],
options: {
spawn: false
}
},
sass: {
files: "src/scss/*.scss",
tasks: ['sass', 'file_append', 'concat']
}
},
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
// destination // source file
"format/css/styles.css": "src/scss/styles.scss"
}
},
options: {
sourcemap: "none",
style: "compact",
noCache: true
}
},
file_append: {
default_options: {
files: [
// Development build
{
append: "",
prepend: "",
input: "format/app.js",
output: "format/dev.app.js"
},
{
append: "</style>`)",
prepend: "document.body.insertAdjacentHTML('afterbegin', `\n<style>\n",
input: "format/css/styles.css",
output: "format/css/dev.styles.html"
},
// Production build
{
append: "</script>",
prepend: "<script>\n",
input: "format/app.js",
output: "format/prod.app.html"
},
{
append: "</style>",
prepend: "<style>\n",
input: "format/css/styles.css",
output: "format/css/prod.styles.html"
}
]
}
},
concat: {
options: {
seperator: '\n'
},
// Development build
dev: {
src: ['format/dev.app.js', 'format/css/dev.styles.html'],
dest: 'dev/dev.app.js'
},
// Production build
prod: {
src: ['format/prod.app.html', 'format/css/prod.styles.html'],
dest: 'dist/prod.app.html'
}
},
browserify: {
dist: {
files: {
// destination for transpiled js : source js
'format/app.js': 'src/app.js'
},
options: {
transform: [
[
'babelify', {
presets: "es2015",
comments: false,
plugins: "transform-object-rest-spread"
}
]
],
browserifyOptions: {
debug: false
}
}
}
}
});
grunt.registerTask('default', [
'sass',
'browserify:dist',
'file_append',
'concat',
'watch'
]);
};
There's a couple ways you can tackle this.
One option is to overload the arguments you pass to the task & include the folder name you wish to target.
grunt sass:dist:Project1
The additional argument is accessible via lodash templates which are a part of the GruntJS framework, and allows the configuration to be set at the time the task is ran:
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
// destination // source file
"MyProjects/<%= grunt.task.current.args[0] %>/format/css/styles.css": "MyProjects/<%= grunt.task.current.args[0] %>/src/scss/styles.scss"
}
},
options: {
sourcemap: "none",
style: "compact",
noCache: true
}
}
This approach works in the context of the function that's executing, but it wouldn't continue to pass the args to the next task. To do that, we need to add a custom task which will set a configuration object before executing the task list:
grunt.registerTask("build", (project) => {
const buildConfig = { project };
grunt.config.set("build", buildConfig);
grunt.task.run([
'sass',
'browserify:dist',
'file_append',
'concat',
'watch'
]);
});
Now when we run grunt build:Project1, your custom task build will run and set the property we passed in the grunt config object. We can then reference that value in our other grunt config objects using lodash like we did for the first option. To access config values with lodash templates, we just have to provide the config pointer in json notation:
files: {
"MyProjects/<%= build.project %>/format/css/styles.css": "MyProjects/<%= build.project %>/src/scss/styles.scss"
}
Grunt compiles the configs required for a task at the time they're run & will process the lodash templates then, allowing you to inject your project name into a task. Since we stored the value in the config object, the value will persist through until grunt completes and exits.
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.
I currently have a custom location to which I want to output the generated css file from grunt-sass. In my GruntFile.js I have:
sass: {
options: {
includePaths: ['bower_components/foundation/scss']
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'dist/assets/css/app.css': 'src/assets/scss/app.scss'
}
}
}
I want to replace 'dist/assets/css/app.css' with a custom location specified from command line. Is there any way to do this for grunt-sass?
Grunt provides applying command line parameters. Here is explanation: http://gruntjs.com/api/grunt.option
In your case solution may looks like:
Declare variable somewhere at the top of Gruntfile.js:
var myVariable = grunt.option('src')';
grunt.initConfig({
...
In your sass task change:
files: {
'dist/assets/css/app.css': 'src/assets/scss/app.scss'
}
to
files: [
{ src: ['src/assets/scss/app.scss'], dest: myVariable
]
And finally, in command line call:
grunt sass --src='your/new/src'
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