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.
Related
how can I use a external library in a grafana datasource plugin?
My plugin works but when i require the "mqtt" library which I have installed and saved to the package.json file I get the following error:
Plugin Error
Error loading http://localhost:3000/public/mqtt as "mqtt" from http://localhost:3000/public/plugins/myfirstplug/datasource.js
this is what my datasource.js head looks like:
define([
'mqtt'
'angular',
'lodash',
'../core_module',
'app/core/config',
],
function (mqtt,angular, _, coreModule, config) {
'use strict';
As I said the package.json already includes mqtt as dependency and ive put the mqtt folder in almost every folder which may be used as library folder manually , too.
How can I use a npm library in a grafana datasource plugin so that it works?
Thanks in advance!
I came across the same issue with including additional dependency for my plugin. I used this experimental plugin as boilerplate to tackle this issue:
You need to create a folder: src/external/
Add the compiled single file dist versions of your dependency under this folder like src/external/mqtt.js. (Actually even Grafana project has vendors in git repository)
In build task, you need to copy the files under your external folder, so your Gruntfile.js should be like this: https://github.com/NatelEnergy/grafana-plotly-panel/blob/master/Gruntfile.js
...
copy: {
...
externals: {
cwd: 'src',
expand: true,
src: ['**/external/*'],
dest: 'dist'
}
...
},
...
grunt.registerTask('default', ['clean', 'copy:src_to_dist', 'copy:pluginDef', 'copy:img_to_dist', 'copy:externals', 'babel']);
Now you can import the external library: import * as mqtt from './external/mqtt';
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.
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 the RequireJS optimiser to minify and concatenate my code. At the moment r.js doesn't minify a lot of my scripts because of the nested dependencies.
I want to include nested dependencies for:
All dependencies inside: 'js/services'
All nested dependencies for a list of specific JavaScript files
Note: I do realise that there is the option findNestedDependencies: true but this looks for absolutely every dependency across all JavaScript files in the app where as I only want to do this for certain JavaScript files and folders as I have a set of files which are always used on every page/view.
My current build file looks like:
({
baseUrl: '../static/js',
mainConfigFile: '../static/js/main.js',
name: 'main',
out: '../static/js/scripts.min.js',
paths: {
requireLib: 'vendor/require/require.min'
},
include: 'requireLib'
})
I have been following this tutorial to get the optimiser running:
http://www.youtube.com/watch?v=m6VNhqKDM4E
You can use include to specify all dependencies you want to force into the output file:
// ...
include: ['requireLib', 'js/services/dep1', 'js/services/dep2'],
// ...
I don't think there's a way to include entire folder (something like "js/services/*"), though.
Since in my project I had many dynamic dependencies I wanted to include in the output I ended up creating an "js/services/_all.js" module which lists files in its directory, for example:
define([
'./dep1',
'./dep2'
],
function () {
// this module imports all modules from current folder so
// there's no need to list every single file in the build config
});
and then configuring r.js with:
// ...
include: ['requireLib', 'js/services/_all'],
// ...