I'm working on a Node.js website and I'm using Grunt to concat and minify my CSS and JS files. However, after running the grunt command I'm getting the error message:
fullPage: Fullpage.js can only be initialized once and you are doing it multiple times!
Here's my grunt file:
/*global module */
module.exports = function (grunt) {
"use strict";
grunt.initConfig({
// read in the project settings from the package.json file into the pkg property
pkg: grunt.file.readJSON("package.json"),
// Install only the bower packages that we need
bower: {
install: {
options: {
"targetDir": "./public/lib",
"copy": true,
"cleanup": true,
"install": true
}
}
},
concat: {
css: {
src: ["public/lib/css/**/*.css", "public/css/cts.css"],
dest: "public/lib/dist/main.css"
},
js: {
src: ["public/lib/**/jquery.js", "public/lib/**/*.js", "public/js/cts.js"],
dest: "public/lib/dist/main.js"
}
},
cssmin: {
target: {
files: {
"public/lib/dist/main.min.css": "public/lib/dist/main.css"
}
}
},
uglify : {
js: {
files: {
"public/lib/dist/main.min.js": "public/lib/dist/main.js"
}
}
},
copy: {
files: {
expand: true,
flatten: true,
src: ["public/lib/fonts/**/*"],
dest: "public/lib/fonts/",
filter: "isFile"
}
}
});
// Add all plugins that your project needs here
grunt.loadNpmTasks("grunt-bower-task");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-watch");
// this would be run by typing "grunt test" on the command line
// the array should contains the names of the tasks to run
grunt.registerTask("test", []);
// define the default task that can be run just by typing "grunt" on the command line
// the array should contains the names of the tasks to run
grunt.registerTask("default", [ "bower", "concat", "cssmin", "uglify", "copy"]);
grunt.registerInitTask("install", ["bower"]);
};
If anything I would have thought jQuery would be the one that's getting concatenated multiple times but it's not. Any suggestions what I might be doing wrong?
EDIT: Here's my upgraded grunt file with all 3rd party libraries listed in the concat.src.
/// <binding BeforeBuild='default' />
/*global module */
module.exports = function (grunt) {
"use strict";
grunt.initConfig({
// read in the project settings from the package.json file into the pkg property
pkg: grunt.file.readJSON("package.json"),
// Install only the bower packages that we need
bower: {
install: {
options: {
"targetDir": "./public/lib",
"copy": true,
"cleanup": true,
"install": true
}
}
},
concat: {
css: {
src: ["public/lib/css/**/*.css", "public/css/cts.css"],
dest: "public/lib/dist/main.css"
},
js: {
src: [
"public/lib/js/jquery/jquery.js",
"public/lib/js/bootstrap/bootstrap.js",
"public/lib/js/fullpage.js/jquery.fullpage.js",
"public/lib/js/jquery-easing-original/jquery.easing.js",
"public/lib/js/slimscroll/jquery.slimscroll.js",
"public/lib/js/wow/wow.js",
"public/js/cts.js"
],
dest: "public/lib/dist/main.js"
}
},
cssmin: {
target: {
files: {
"public/lib/dist/main.min.css": "public/lib/dist/main.css"
}
}
},
uglify : {
js: {
files: {
"public/lib/dist/main.min.js": "public/lib/dist/main.js"
}
}
},
copy: {
files: {
expand: true,
flatten: true,
src: ["public/lib/fonts/**/*"],
dest: "public/lib/fonts/",
filter: "isFile"
}
}
});
// Add all plugins that your project needs here
grunt.loadNpmTasks("grunt-bower-task");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-watch");
// this would be run by typing "grunt test" on the command line
// the array should contains the names of the tasks to run
grunt.registerTask("test", []);
// define the default task that can be run just by typing "grunt" on the command line
// the array should contains the names of the tasks to run
grunt.registerTask("default", [ "bower", "concat", "cssmin", "uglify", "copy"]);
grunt.registerTask("combine", [ "concat", "cssmin", "uglify", "copy"]);
grunt.registerInitTask("install", ["bower"]);
};
Your issue seems to be in concate.js.src
src: ["public/lib/**/jquery.js", "public/lib/**/*.js", "public/js/cts.js"]
This will have your files added multiple times as there might some files common among the paths mentioned in src.
You should probably move all your vendor files like jquery out of the public directory and put in a different one, say vendor.
Your src should then look something like
src: ["vendor/**/*.js", "public/**/*.js"]
As you see now there are no common files among these two paths.
Also its a good practice to always have 3rd party code outside your app directory as a sibling folder and not inside it.
EDIT:
Ah! I see whats your problem. You want to have jquery first among the other vendor files.
public/lib/**/jquery.js and public/lib/**/*.js together might be causing files added twice.
Try this
src: ["public/lib/jquery/jquery.js", "public/lib/**/*.js", "!public/lib/jquery/jquery.js", public/js/cts.js"]
Put the full path of jquery first public/lib/jquery/jquery.js and then the !public/lib/jquery/jquery.js should prevent jquery being added again as part of public/lib/**/*.js
Got the above pattern from here http://gruntjs.com/configuring-tasks#globbing-patterns
If this still doesn't work, then another option is to add all paths in the src array individually. If you have a requirejs config just copy the paths from there, as jquery might not be the only dependency issue you face in future.
Related
edit for clarity
old question: grunt watch task leading zeros in minified css for some styles truncated
new diagnosis: There are several people that push to the same repository and I have observed a different behavior to minified files with the same setup of grunt watch.
end edit
In my repo I have multiple stylesheets. I use grunt to watch for scss changes and only modify the correlating CSS file. I've had a problem lately where grunt will see a modified file in older, non modified CSS files.
Here's the problem:
I pull from master.
I run grunt in the command line.
I make no changes to a scss file but save the file anyway.
I stop grunt and git status.
Git sees four modifications in the minified CSS files.
I save the changes commit and push to a branch.
When I git diff I can see that grunt has removed some of the leading zeros in front of decimal points for opacity.
Here is a screenshot of the diff.
If I commit and push these modifications to my branch I can go about making other changes and only modifying the correlating CSS minified files. But after merging these changes to master and then pulling from master again, when I run grunt locally I will see these same four "ghost" modifications with the same zero's being removed in the minified file. I've tried changing my version of node, sass, and grunt but all different versions have the same result!
Has anyone else experienced this or know how to stop grunt from making these changes and bloating the repo with excessive recompiling and commits?
Version of node: 5.1.0
Version of sass: 3.4.19
Version of grunt 0.4.5
Version of grunt cli: 0.1.13
I just recently updated my version of node from 0.10.33 to 5.1.0
And here is my gruntfile:
module.exports = function(grunt) {
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// set notifications that run after other tasks
notify: {
uglify: {
options: {
title: 'Task Complete',
message: 'Uglify finished running',
}
},
sass: {
options: {
title: 'Task Complete',
message: 'Sass finished running',
}
}
},
// concat and minify js task
uglify: {
site: {
files: {
'assets/four/js/site.js': [
'assets/four/js/src/plugins/*.js',
'assets/four/js/src/global.js',
'assets/four/js/src/data/*.js',
'assets/four/js/src/forms/*.js',
'assets/four/js/src/modules/*.js',
'assets/four/js/src/pages/*.js'
],
'assets/four/js/analytics.min.js': ['assets/four/js/src/analytics.js'],
'assets/four/js/social.js': ['assets/four/js/src/social.js']
}
},
pages: {
files: grunt.file.expandMapping(['assets/js/pages/**/*.js', '!assets/js/pages/**/*.min.js'], 'assets/js/pages', {
rename: function(destBase, destPath) {
return destPath.replace('pageassets/js/pages', destBase).replace('.js', '.min.js');
}
})
}
},
//concat and minify scss -> css task
sass: {
options: {
sourceMap: true,
outputStyle: 'compressed'
},
dist: {
files: {
'assets/css/style.css': 'assets/css/scss/style.scss',
'assets/css/old.css': 'assets/css/scss/old.scss',
'assets/css/pages/brand.css': 'assets/css/pages/scss/brand.scss',
'assets/css/pages/custom-design-showcase.css': 'assets/css/pages/scss/custom-design-showcase.scss',
'assets/css/landings.css': 'assets/css/scss/landings.scss',
// 4.0
'assets/four/css/site.css': 'assets/four/css/scss/site.scss',
'assets/four/css/ie.css': 'assets/four/css/scss/ie.scss',
'assets/four/css/interim.css': 'assets/four/css/scss/interim.scss'
}
}
},
// compress images losslessly task
imagemin: {
dynamic: {
options: {
optimizationLevel: 3,
progressive: true,
svgoPlugins: [{removeUselessStrokeAndFill: false}]
},
files: [{
expand: true,
cwd: 'assets/four/img',
src: ['**/*.{png,jpg,gif,svg}'],
dest: 'assets/four/img'
}]
}
},
// watch for changes in repo and run tasks automatically
watch: {
options: {
// Google Extension: https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei?hl=en
livereload: true
},
html: {
files: ['templates/default_site/**/*.html']
},
js: {
files: [
'assets/js/*.js',
'assets/four/js/src/global.js',
'assets/four/js/src/plugins/*.js',
'assets/four/js/src/data/*.js',
'assets/four/js/src/forms/*.js',
'assets/four/js/src/pages/*.js',
'assets/four/js/src/modules/*.js',
//dont
'!assets/four/js/*.min.js',
'!assets/four/js/*.js',
'!assets/js/*.min.js',
'assets/js/pages/**/*.js',
'!assets/js/pages/**/*.min.js',
'assets/js/geo/**/*.js',
'!assets/js/geo/**/*.min.js'
],
tasks: ['uglify', 'notify:uglify']
},
sass: {
options: {
livereload: true
},
files: ['assets/css/scss/*.scss', 'assets/four/css/scss/*.scss', 'assets/four/css/scss/pages/*.scss', 'assets/four/css/scss/modules/*.scss', 'assets/css/scss/modules/*.scss', 'assets/css/pages/scss/*.scss'],
tasks: ['sass:dist', 'notify:sass']
},
css: {
files: ['assets/css/*.css', 'assets/four/css/*.css', 'assets/css/pages/*.css']
}
},
});
//load plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-notify');
// to run watch task, enter 'grunt' command line in project DIR
grunt.registerTask('default', ['watch']);
};
I am new to Grunt and all its plugins, but I want to learn and setup some awesome front-end tools. With that said, I have been following the Grunt docs and some's similar issue with Grunt and Babel via Github, but I seem to keep getting the following traceback:
Running "babel:dist" (babel) task
Warning: Unable to write "dist" file (Error code: EISDIR). Use --force to continue.
Aborted due to warnings.
Any clearer explanation to this newbie would be HIGHLY appreciated. I'm new to programming in JS and setting up DevOps, so some helpful tips and best practices are encouraged.
Setup:
js_practice/ (Root Project)
|----package.json
All the distributions and packages
|---node_modules/
Server-Side (Node) support
|---es6/
| ------ test.js
|---dist/
Client (browser) support
|----public/
|---es6/ (this is within the public folder)
| ----- test2.js
|---dist/ (this is within the public folder)
Here is my current code:
Grunt file.js
module.exports = function(grunt) {
// All of your Grunt code must be specified inside this function!
// Setup configuration...
// Load tasks...
// Define tasks...
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
babel: {
options: {
sourceMap: true,
presets: ['babel-preset-es2015']
},
dist: {
files: [
// Node source
{
src: ['es6/**/*.js'],
dest: 'dist'},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'},
],
},
},
browserify: {
dist: {
options: {
transform: [["babelify", { "stage": 0 }]]
},
files: {
"build/bundle.js": "src/main.js"
}
}
},
jshint: {
scripts: {
src: ['scripts/**.js', 'lib/**.js']
},
tests: { // We can have more than one jshint task, this ones called `jshint:tests`
src: 'tests/**.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
},
scripts: {
expand: true,
cwd: 'scripts/',
src: '**.js',
dest: 'build/',
ext: '.min.js'
}
},
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['jshint'],
},
styles: {
files: 'styles/**.less',
task: 'less:styles'
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-babel');
grunt.registerTask('default', ['babel','browserify','jshint']);
grunt.registerTask('build', ['jshint', 'uglify']);
};
Just expanding on what I said in the comments
Any clearer explanation to this newbie would be HIGHLY appreciated.
Nodejs is trying to write a file called dist, but produces an error because a directory with this name exists.
The cause of this is found in the babel task.
files: [{
src: ['es6/**/*.js'],
dest: 'dist'
},
// Browser source
{
src: ['public/es6/**/*.js'],
dest: 'public/dist'
}]
You have to tell Babel to take each file in es6/, transform them and place the new files in the dist/ folder. As it stand now, the transformer tries to create a file called dist. Rewriting it to
files: [{
expand: true,
cwd: 'es6/'
src: ['**/*.js'],
dest: 'dist/'
},
// Browser source
{
expand: true,
cwd: 'public/es6/'
src: ['**/*.js'],
dest: 'public/dist/'
}]
should yield a better result, but play around with it. Like I mentioned, I haven't used Grunt in a while. Take a look at the documentation on building the files object
And like I said in the comments, use jshint or other such tools (eslint is all the hype...) to keep your own code neat. Don't waste time by running a jshint task on lib files that you probably don't want to fix yourself anyway. And always run jshint on the source files, not files that are transformed by babel or browserify. It's just a tool to help you write better code, not some generator.
I have the following grunt file:
module.exports = function(grunt) {
grunt.initConfig({
cssmin: {
options: {
shorthandCompacting: false,
roundingPrecision: -1
},
target: {
files: {
'css/output.css': ['css/one.css', 'css/two.css']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['cssmin']);
};
just started using grunt.js today and just had a look at the documentation and the examples , i am using the following plugin:
CSS-CONTRIB-MIN
Now, My files get minifined into one , but what i really want is for them to only be combined into one and not minified. how do i achieve that ?
You should use the grunt-contrib-concat plugin for this task. Take a closer look at the GitHub documentation on how to configure the task (e.g. separator, banner, ...)
grunt.initConfig({
concat: {
dist: {
src: ['css/one.css', 'css/two.css'],
dest: 'css/output.css',
},
},
});
Goal
My goal is to concatenate all my css,js files and minify all of them.
I can minify my concat.js, but I'm struggling trying to minify my concat.css.
Gruntfile.js
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
concat: {
js: {
src: [
'js/bootstrap.min.js',
'js/jquery-1.10.2.min.js',
'js/jquery.easypiechart.min.js',
'js/jquery.isotope.min.js',
'js/jquery.magnific-popup.min.js',
'js/waypoints.min.js',
'js/respond.min.js',
'js/jquery.vegas.min.js',
'js/modernizr-2.6.2.min.js',
'js/jquery.nav.js',
'js/html5shiv.js',
'js/jquery.scrollTo.js',
'js/jquery.sticky.js',
'js/jquery.validate.js',
'js/main.js',
],
dest: 'dist/concat.js'
},
css: {
src: [
'css/magnific-popup.css',
'css/main.css',
'css/xl.css',
'css/lg.css',
'css/md.css',
'css/sm.css',
'css/xs.css',
'css/print.css',
'css/bootstrap.min.css',
'css/font-awesome.min.css',
],
dest: 'dist/concat.css'
}
},
watch: {
js: {
files: ['js/*.js'],
task: ['concat:js']
},
css: {
files: ['css/*.css'],
task: ['concat:css']
}
},
uglify: {
js: {
files: {
'dist/minified.js': ['dist/concat.js']
}
},
css: {
files: {
'dist/minified.css': ['dist/concat.css']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['concat', 'uglify']);
};
Result
I concatenate all my css and js files succesfully, and they're generated at :
dist/concat.js
dist/concat.css
Then, I can also minify my concat.js with no problem, but I'm struggling trying to minify my concat.css.
I kept getting this error in the bottom of my Terminal :
Running "uglify:css" (uglify) task
{ message: 'Unexpected token: punc (.)',
filename: 'concat.css',
line: 4,
and line4 is just the beginning of my class : .mfp-bg {
Can someone please give me a little push here ?
Also, should I perform minify after concatenation or the other way around ?
Is there a better way to do this ?
uglify is for minimising JavaScript only, not CSS.
If you want to minimise CSS you can use the cssmin task for Grunt instead.
I have recently discovered grunt as it is used within an opensource project I have started to work on. Having not worked with grunt before I am struggling to see how it works, or in my case doesn't.
The grunt file is supplied by the project and I assume it works for everyone else. I have installed grunt and the necessary grunt modules have all installed in the "Node_modules" directory.
When running the grunt file the first process performs a number of concatenations and this seems to work fine. The concatenated files are created.
All of the other steps do not seem to execute. The files they are intended to create are not created. There is no error message displayed on the console when grunt is executed.
I'm stumped - anyone have any clues what might be the problem.
The grunt file is :
/*global module:false*/
module.exports = function(grunt) {
// Project configuration...
grunt.initConfig({
manifest: grunt.file.readJSON('chrome/manifest.json'),
concat: {
dist: {
src: ['chrome/js/requester/**/*.js'],
dest: 'chrome/js/requester.js'
},
requester_html: {
src: [
'chrome/html/requester/header.html',
'chrome/html/requester/sidebar.html',
'chrome/html/requester/main.html',
'chrome/html/requester/loggers/*.html',
'chrome/html/requester/modals/*.html',
'chrome/html/requester/footer.html'
],
dest: 'chrome/requester.html'
},
requester_tester: {
src: [
'chrome/html/requester/header.html',
'chrome/html/requester/sidebar.html',
'chrome/html/requester/main.html',
'chrome/html/requester/modals/*.html',
'chrome/html/requester/loggers/*.html',
'chrome/html/requester/footer.html',
'chrome/html/requester/tester.html'
],
dest: 'chrome/tester.html'
}
},
mindirect: {
dist: {
src: ['chrome/js/requester.js'],
dest: 'chrome/js/requester.min.js'
}
},
watch: {
requester_templates: {
files: ['chrome/html/requester/templates/*'],
tasks: ['handlebars'],
options: {
livereload: true
}
},
requester_js: {
files: ['chrome/js/requester/**/*.js'],
tasks: ['concat:dist'],
options: {
livereload: true
}
},
requester_html: {
files: ['chrome/html/requester/*', 'chrome/html/requester/modals/*', 'chrome/html/requester/loggers/*'],
tasks: ['concat:requester_html', 'concat:requester_tester'],
options: {
livereload: true
}
},
requester_css: {
files: ['chrome/css/**/*.scss'],
tasks: ['sass'],
options: {
livereload: true
}
}
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
jQuery: true
}
},
handlebars: {
compile: {
options: {
partialsUseNamespace: true,
namespace: 'Handlebars.templates',
processPartialName: function(filePath) {
var pieces = filePath.split("/");
var name = pieces[pieces.length - 1].split(".")[0];
return name;
},
processName: function(filePath) {
var pieces = filePath.split("/");
var name = pieces[pieces.length - 1].split(".")[0];
return name;
}
},
files: {
"chrome/html/requester/templates.js": "chrome/html/requester/templates/*"
}
}
},
sass: {
dist: {
files: {
'chrome/css/requester/styles.css': 'chrome/css/requester/styles.scss'
}
}
},
compress: {
main: {
options: {
archive: 'releases/v<%= manifest.version %>.zip'
},
files: [
{src: ['chrome/**', '!chrome/tests/**', '!chrome/manifest_key.json', '!chrome/tester.html'], dest: '/'}, // includes files in path and its subdirs
]
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-handlebars');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-mindirect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-compress');
// Default task.
grunt.registerTask('default', ['jshint', 'concat']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
};
The output from the console is as follows :
Running "jshint:globals" (jshint) task
>> 0 files lint free.
Running "concat:dist" (concat) task
File "chrome/js/requester.js" created.
Running "concat:requester_html" (concat) task
File "chrome/requester.html" created.
Running "concat:requester_tester" (concat) task
File "chrome/tester.html" created.
Done, without errors.
Given that the tasks are defined like this:
grunt.registerTask('default', ['jshint', 'concat']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
the output you show is what you'd expect if you are running grunt without a task name. It runs the jshint and concat tasks.
If you want to run the tasks associated with package, then you have to run grunt package to run those tasks.
It looks like I did not understand "tasks" within grunt.
Instead of executing "grunt" which runs the "default" tasks, I had to execute "grunt package" which runs the tasks that I was interested in.
As Louis said, you have to specify the right task to run.
But you can also create or modify the tasks you have in order to make it simpler. In your example you may include package in the default task. Because concat task is already executed inside package, you may just replace it in the default task:
grunt.registerTask('default', ['jshint', 'package']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
and, in order to build your site, just type
grunt
both jshint and package tasks will be executed