I find there to be a lot of confusion/lack a specific way of handling building with require in grunt. I'm just confused what configuration should go directly in Grunt task options:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
requirejs: {
compile: {
options: {
baseUrl: './js',
mainConfigFile: 'config.js',
optimize: 'none',
include: ['./main'],
out: 'optimized.js'
}
}
}
});
And then in config file:
({
appDir: './',
baseUrl: './js',
dir: './dist',
optimize: 'none',
optimizeCss: 'standard',
removeCombined: true,
paths: {
jquery: './js/jQuery/jquery',
}
})
Obviosuly there seems to be some redundancy but that is mostly what I've found. Can someone explain why or if I'm mistaken? Can I place all config in one or the other? I'm only planning on working off of the optimized single file with almond.
Also do I only state the initial single point of entry to build the dependency chain from ie my main.js file and any require calls in there or can I state a wildcard list of files that calls modules:
include: ['./variousFiles/*.js']
Any and all clarifications of how to best utilize require with Grunt will be appreciated. Thank you!
When you use RequireJS' r.js optimizer there are two configurations to speak of:
The runtime configuration which is what is described in the RequireJS documentation. This is where you tell RequireJS where to find modules at runtime.
The build configuration, which is what is described with r.js' documentation. This tells r.js how to build bundles from your modules.
The mainConfigFile option is for the build configuration, it tells r.js where to find the runtime configuration you plan to use when you run the bundles it will create. This is to prevent having to duplicate shim and paths options from the runtime configuration to the build configuration.
In your description, it looks like you are making mainConfigFile point to a build configuration. This is useless.
Related
I'm configuring my Gruntfile and I'm stuck on something I feel should be possible but I'm not able to find the right configuration for it. I'm trying to copy my bower components to my dist on build with the grunt-contrib-requirejs module. The part I'm stuck on is keeping the folder structure in tact when copying to dist.
My app's basic structure, and dist/ should build the same way
Gruntfile.js
app/
- assets/
- bower_components/
- js/
- img/
- etc/
- index.html
Currently, I define each file in the copy module and it copy's them all over
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: 'app',
dest: 'dist',
src: [
'*.{ico,png}',
'.htaccess',
'partials/**/*',
// Bower Components
'assets/bower_components/requirejs/require.js',
'assets/bower_components/fastclick/lib/fastclick.js',
'assets/bower_components/jquery/dist/jquery.min.js',
'assets/bower_components/modernizr/modernizr.js'
]
}]
}
},
But I want to eliminate this and use the paths I've already defined in main.js to copy these files over. Less hardcoded stuff, more automation.
My require task
requirejs: {
dist: {
options: {
mainConfigFile: app + '/assets/js/main.js',
dir: dist + '/assets/js',
optimize: 'uglify',
paths: {
modernizr: 'empty:',
jquery: 'empty:',
fastclick: 'empty:'
}
}
}
},
This current configuration combined with copy moves them all over properly. If I could eliminate the paths property all together and use directory properties only that would be great. If I have to copy my paths from my main.js into here thats ok... if it's the only way to do it.
Let me know if you need any more info!
The JS files in your bower directory should be included in the optimized output of requirejs, as long as they are configured and referenced in your require js app. If they're not referenced as dependencies, I don't think they get included.
The ico, png, htaccess and other files may need to be copied over manually.
Depending on your partials, the text plugin and hbs plugin could compile those into the optimized file I think.
I think defining empty: in paths are for using network resources (e.g. when using CDNs instead of using local bower libraries), so the paths config is probably unnecessary
I just created a custom build of jQuery, and I slimmed down the library to only include the parts that I need. I did this by following the instructions documented on the jQuery repo hosted on GitHub. It basically uses node.js, npm, git, and grunt, and you're able to exclude parts of the API all in command line, and make a build.
Now I need to do the same thing with jQueryUI, but I don't see such instructions in their documentation. Does anyone know if this can be done the same way? What's the easiest way to slim down a jQueryUI library, and customize it specifically according to my needs?
Thanks in advance!
If you want to use it with your grunt build, just add some params to your config. Example:
grunt custom:-ajax,-css,-dimensions,-effects,-offset
or modify the necessary Gruntfile.js (https://github.com/jquery/jquery-ui/blob/master/Gruntfile.js)
To build a custom version of jQuery UI from an NPM package, you have to use requirejs. Your grunt config will look something like this:
requirejs: {
jqueryui: {
options: {
expand: true,
baseUrl: '<%= nodeModules %>/jquery-ui/',
paths: {
jquery: './external/jquery/jquery',
external: './external/',
},
optimize: 'none',
findNestedDependencies: true,
skipModuleInsertion: true,
exclude: ['jquery'],
include:
grunt.file.expand(
{
cwd: path.resolve(appConfig.nodeModules + '/jquery-ui/'),
},
[
'ui/effect.js',
'ui/effects/*.js',
'list of files to include in your build',
]),
out: '<%= www %>/js/jquery-ui.js',
},
},
}
go to this page and select your favorite features, then download it as a custom build.
I'm using r.js optimization with CDN assets set to :empty in the paths configuration. However, when I hit the optimized file, require is not fetching the CDN assets. Specifically it is not reaching out for jQuery. I'm also using the grunt requirejs task.
Here is my require.js config:
require.config({
paths: {
jquery :'//ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min'
}
});
And here is the grunt.js config:
requirejs: {
compile: {
options: {
baseUrl: "public/resources/javascripts/",
mainConfigFile: "public/resources/javascripts/main.js",
out: "public/resources/javascripts/main-build.js",
paths: {
'jquery': 'empty:'
},
name: "main",
generateSourceMaps: true,
optimize: "uglify2",
preserveLicenseComments: false
}
}
}
And I'm hitting the built asset as:
<script data-main="/resources/javascripts/main-build.js" src="/resources/javascripts/libs/require.js"></script>
You must add the resources loaded from a CDN inside the exclude array too. Otherwise, the module is included, simply empty.
exclude: [ "jquery" ]
On a side note, loading jQuery from a CDN will be slower than bundling it into your builded file. You shouldn't use a CDN in this case.
Is there a way to keep one paths.js file to keep track of all paths for
//i know you can do this where configobject.paths = require('paths');
requirejs.config(configobject)
//and r.js build config
({
paths:require('paths'),
})
I also wanted to centralize my AMD module paths. This is an implementation in curl, but the same approach works for RequireJS:
Basically, but the config in a file:
https://github.com/SimpleAsCouldBe/appCore/blob/master/shared/appCore/setCurlPaths.js
And use the config in any page you want:
https://github.com/SimpleAsCouldBe/appCore/blob/master/exampleApp1/index.html
You can optimize this with grunt concat or something during the build. You can also tell grunt's requirejs optimizer about this shared config file:
# https://github.com/jrburke/r.js/blob/master/build/example.build.js
requirejs:
oneForAll:
options:
mainConfigFile: "shared/appCore/requireConfig.js"
I use require js in my single page app and I am wondering if it is possible to combine all modules, vendor libraries (jQuery, Underscore, Backbone) in one single file, since this would speed up my app.
app
css
html
homepage
main.html
login.html
signup.html
js
build.js
libs
jquery.js
backbone.js
underscore.js
require.js
modules
collections
models
views
main
main.js
app.js
router.js
app-build
My build configuration file currently is:
({
appDir: '../',
baseUrl: 'js/modules',
mainConfigFile: 'modules/main/main.js',
dir: '../../app-build',
optimize: 'uglify',
uglify: {
toplevel: true,
ascii_only: true,
beautify: true,
max_line_length: 1000
},
preserveLicenseComments: true,
logLevel: 0
})
I'm certainly not an expert in this area, but I did manage to get this working for one of my projects, admittedly mainly by trial and error.
I found that I needed to make either/both of appdir and baseUrl be a directory which contained both my code and the library code - in your case, this would either be ./app/js or ./app (depending on whether you also wanted your templates combined).
I also supplied paths to the various library functions.
Having got it working I really ought to go back and see what was actually necessary, and what was cargo-cult coding. For now I have more pressing code to be writing...
For your interest I include my options: note I am optimizing from node.js via rjs.optimize(...).
var options = {
baseUrl: "./site/app",
appdir: "./site/app",
name: "js/main",
out: "main-built.js",
paths: {
jQuery: 'js/libs/jquery/jquery',
Underscore: 'js/libs/underscore/underscore',
Backbone: 'js/libs/backbone/backbone',
Handlebars: 'js/libs/handlebars/handlebars',
templates: 'templates'
}
};
I'm not expecting this to be the correct answer, but hopefully it will lead you somewhere useful.