grunt uglify can't find my files in parent directory - node.js

Unlike all of the other node projects i've written, this one needs the node server's folder to not be root. Here's the current folder hierarchy:
- Root/
- build/
- css/
- im/
- js/
- nodeserver/ <-- gruntfile and package are here
GruntFile.js, package.json, and server.js are all located in nodeserver/
Here is my GruntFile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
files: {
'../build/all.min.js':['../js/config.js']
},
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
report: true
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
When I run grunt, it can't find the file that I'm specifying. This is the response:
Running "uglify:files" (uglify) task
------------------------------------
Verifying property uglify.files exists in config...OK
File: [no files]
Options: banner="/*! demo-webservice 2014-03-28 */\n", footer="", compress={"warnings":false}, mangle={}, beautify=false, report
Why can't it see my js file?

Wrapping files: {} in my_target: {} solved my problem.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
my_target: {
files: {
'../build/all.min.js':['../js/config.js']
}
},
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
report: true
}
}
});
^--- the new version of that initConfig.
It should also be noted that my_target could be anything, and is used by default since it is the only uglify profile supplied. If i had supplied more than one profile, i.e. "test: {}, prod: {}, etc: {}", then I would refer to them after the task in the following way: uglify:test, uglify:prod, uglify:etc

Related

How to setup Gruntfile.js to watch for SASS (compass) and JS

I'm new to using gruntjs and nodejs. I wanted to know how can I setup the gruntfile so that it watches both the sass files and the js files compiles using watch.
This is what I have so far:
module.exports = function ( grunt ) {
"use strict";
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
config: 'config.rb',
watch: true
}
}
}
});
grunt.registerTask('default', []);
};
Any help will be much appreciated. Thank you!
Try grunt-contrib-watch with grunt-contrib-sass. They're both Grunt plugins specifically for this kind of thing:
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'css/build/global.css': 'scss/screen.scss'
}
}
},
watch: {
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false
}
}
},
The watch plugin configuration above will watch for changes in any .scss files, and will run the sass tasked (also defined above). You can even hook into livereload this way. You can also have multiple watches (the above only defines a css watch); creating a second watch to minify JS would be easy with grunt-contrib-uglify
I have an example you can look at that also concatenates JavaScript and does some minification with grunt-contrib-uglify. Here is the example.

Trying to use grunt-contrib-requirejs to minify all JS to one file

I have the following directory structure (relevant bits only):
app
- build
- script.js
- js
- lib
- require.js
- jquery-1.10.2.js
- app.js
- index.html
Gruntfile.js
Gruntfile.js contains the following:
module.exports = function (grunt) {
var gruntConfig = {
pkg: grunt.file.readJSON('package.json'),
requirejs: {
compile: {
options: {
name: 'app',
baseUrl: 'app/assets/js',
out: 'app/assets/build/script.js',
include: ['lib/require'],
uglify: {
// beautify: true,
defines: {
DEBUG: ['name', 'false']
}
},
paths: {
jquery: "lib/jquery-1.10.2"
}
}
}
},
};
grunt.initConfig(gruntConfig);
grunt.loadNpmTasks('grunt-contrib-requirejs');
};
app.js contains the following:
require(['jquery'], function ($) {
// Do stuff
});
How do I set it up so that it copies all the JavaScript needed into build/script.js, not just app.js and require.js when I tell it to (erroring when I try to use jQuery)? I also want to be able to add modules without adding them to my Gruntfile, just by adding them to script.js.
You can have a mainConfigFile defined and inside config file have paths to you lib code like this
Contents of gruntfile:
requirejs: {
compile: {
options: {
baseUrl: "app/js/",
mainConfigFile: app/config.js",
out: "build/script.js",
name: "config"
}
}
}
Contents of config file:
require.config({
paths: {
lib: "<path to>/js/lib",
jquery: "<path to>/js/lib/jquery-1.10.2.min",
.
and particular file required
.
}
Requirejs will add the contents of all path files to the optimized code.
Try adding this to your options object:
findNestedDependencies: true
This way grunt-contrib-requirejs (actually just requirejs) will find whatever dependencies are listed on your config file.
Hope it works for you.

Merge requireJS files with grunt

I want to combine the js used in a simple requireJS solution.
This is my main.js
require.config({
paths: {
'jquery': 'jquery-2.0.3.min',
'dataTable': 'jquery.dataTables'
}
});
define(['jquery','dataTable'], function($) {
'use strict';
$(function () {
$('.tablesorter').dataTable();
});
});
And my gruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
out: "optimized.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', 'requirejs');
};
WHen I load optimized.js in the html like this
<script src="optimized.js"></script>
I get
ReferenceError: require is not defined
You must include require.js on the page before including optimized.js.
Like so:
<script src="/path/to/require.js"></script>
<script src="/path/to/optimized.js"></script>
I found out that requireJS only accepts 'main' as the data-main src
So instead of
<script data-main="optimized" src="require.js"></script>
I got
<script data-main="prod/main" src="require.js"></script>
And changed the grunt config to
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
out: "prod/main.js"
}
}
}
Looking at the comments in addition to the question, first I see that George Raith hit on one problem with your code: you needed to include require.js.
Then you said that $('.tablesorter').dataTable() is not executed. That's because you use define rather than require. Use this:
require(['jquery','dataTable'], function($) {
'use strict';
$(function () {
$('.tablesorter').dataTable();
});
});
A call to define only registers a module with RequireJS. It does not execute a module. So it is not surprising that $('.tablesorter').dataTable() would not execute. You have to use the form of require that takes a callback to do what you want to do.
As for including RequireJS with your project into a single file, you have to ask for it explicitly. The optimizer's documentation gives this example:
node ../../r.js -o baseUrl=. paths.requireLib=../../require name=main include=requireLib out=main-built.js
Your configuration (updated from the one in the question) would look something like this:
grunt.initConfig({
requirejs: {
production: {
options: {
name: "main",
baseUrl: "",
mainConfigFile: "main.js",
paths: {
requireLib: <path to require js>
},
out: "optimized.js",
include: "requireLib"
}
}
}
});
(I've not run this code, so lookout for typos.) You have to put the path to your require.js file for requireLib. We have to use requireLib as a module name because require is reserved. With this kind of configuration, you should be able to load only your optimized.js file.

What am I doing wrong with Gruntjs targets?

I followed the instructions on the grunt.option page to create different configurations for different environments/targets such as development, staging, and production in my Gruntfile. However, upon doing so I found that my tasks silently fail.
I've reduced the problem to a very simple example. The following Gruntfile fails to build the file:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
dev: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less:dev']);
};
The output in my terminal is the following:
$ grunt
Running "less:dev" (less) task
Done, without errors.
If, however, I use the following Gruntfile, the build output is as expected:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less']);
};
The terminal output for this Gruntfile reflects the built file:
$ grunt
Running "less:build" (less) task
File build/css/test.css created.
Done, without errors.
What am I doing wrong in the first Gruntfile? What is it that I am missing about this task:target convention?
Your first Gruntfile - If you want per-target options, you need to specify the files object. So your code would be something like this:
less: {
dev: {
files: {
"build/css/test.css": "src/css/test.less"
}
},
production: {
options: {
compress: true
},
files: {
"build/css/test.css": "src/css/test.less"
}
},
}
Basically in your first Gruntfile build is an unknown object. Your target is named dev and grunt-contrib-less doesn't have an option called build so Grunt doesn't know where to write the files. Your second Gruntfile works because you set the options as a global. Use the above code if you want per-target options.

RequireJS with server generated JS file

I'm using RequireJS with a server generated file that contains translation strintgs and is reachable at http://hostname/i18n.js. I have added it to RequireJS with the paths config like so:
requirejs.config({
paths: {
'i18n': '/i18n'
},
});
Now I'm trying to minify this with grunt-contrib-requirejs' like this:
module.exports = function(grunt) {
'use strict';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'), // the package file to use
jsDir: '<%= baseDir %>/static/js',
requirejs: {
compile: {
options: {
mainConfigFile: "<%= jsDir %>/common.js",
dir: '/tmp/www-release',
modules : [
{
name: 'common',
exclude: ['i18n'],
include: [
/* some filess */
]
}
]
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
};
As you can see, I have excluded i18n. Yet I still get the following error when running grunt requirejs:
Running "requirejs:compile" (requirejs) task
[Error: Error: ENOENT, no such file or directory '/i18n.js'
at Object.fs.openSync (fs.js:427:18)
]
How do I tell grunt to ignore the translation strings?

Resources