How to use webjars! loader plugin? - requirejs

In my previous Play app, I used to use Webjars & RequireJS to manage dependencies. I could use require(['angular', 'webjars!ui-bootstrap-tpls.js'], function(angular) {...}) without problem.
Recently I updated webjars and several webjars related deps (webjars-ui-bootstrap, etc.) to the latest version on www.webjars.org, and I found webjars! loader plugin not working properly. I checked out the webjars-seed-play app and modified some code like:
require(['angular', './controllers', './directives', './filters', './services', 'angular-route', 'webjars!ui-bootstrap-tpls.js'],
function (angular, controllers) {
// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngRoute', 'ui.bootstrap']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: controllers.MyCtrl1});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: controllers.MyCtrl2});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
angular.bootstrap(document, ['myApp']);
});
It just complains that ui.bootstrap is not available, which should be loaded by webjars!ui-bootstrap-tpls.js in my opinion. What am I doing wrong here? Please help me. Thanks.
My deps in build.sbt:
libraryDependencies ++= Seq(
"org.webjars" %% "webjars-play" % "2.2.1-2",
"org.webjars" % "angularjs" % "1.2.13",
"org.webjars" % "bootstrap" % "3.1.1",
"org.webjars" % "requirejs" % "2.1.11-1",
"org.webjars" % "angular-ui-bootstrap" % "0.10.0"
)

Sorry about the hassle. Now that RequireJS is officially supported in WebJars we had to make some changes: http://www.jamesward.com/2014/02/19/official-support-for-requirejs-in-webjars
In short, the webjars! plugin loader has been replaced with just normal RequireJS modules and path configs. Some of the WebJars haven't been updated yet. So if you run into problems please file an issue against the WebJar.

Related

OpenEDX RequireJS error when overriding factory with AWS setting

I'm having an issue with OpenEDX when deploying to a server as opposed to devstack. On devstack the override works perfectly, although on dev it fails to load.
I am overriding the student_account/account_settings.html as well as student_account/views/account_settings_factory.js and student_account/views/account_settings_view.js.
When loading the account section of the LMS, the following error is produced on production, but not on dev:
Mismatched anonymous define() module: function(gettext, $, _, Backbone, Logger, UserAccountModel, UserPreferencesModel,
AccountSettingsFieldViews, AccountSettingsView, StringUtils) {
return function(
fieldsData,
ordersHistoryData,
authData,
passwordResetSupportUrl,
userAccountsApiUrl,
userPreferencesApiUrl,
accountUserId,
platformName,
contactEmail,
allowEmailChange
) {
var accountSettingsElement, userAccountModel, userPreferencesModel, aboutSectionsData,
accountsSectionData, ordersSectionData, accountSettingsView, showAccountSettingsPage,
showLoadingError, orderNumber, getUserField, userFields, countryDropdownField, emailFieldView;
accountSettingsElement = $('.wrapper-account-settings');
userAccountModel = new UserAccountModel();
userAccountModel.…
The define in my factory looks like the following:
(function(define, undefined) {
'use strict';
define([
'gettext', 'jquery', 'underscore', 'backbone', 'logger',
'js/student_account/models/user_account_model',
'js/student_account/models/user_preferences_model',
'js/student_account/views/account_settings_fields',
'academy/js/student_account/views/account_settings_view',
'edx-ui-toolkit/js/utils/string-utils'
], function(gettext, $, _, Backbone, Logger, UserAccountModel, UserPreferencesModel,
AccountSettingsFieldViews, AccountSettingsView, StringUtils) {
As stated, works flawlessly in development, but production throws the error. Hopefully someone knows a solution to this issue.
The issue was because in the AWS paver settings for some reason the custom factory is expected to be optimized, which can be done by overriding the build.js file for the lms. This issue isn't really clear anywhere in the docs and was therefore a bit difficult to reach this conclusion.

Glob ignore pattern does not appear to be working with gulp

I have an AngularJS project with Karma-run Jasmine unit tests and am trying to use Gulp as my task automator. I have the test spec files alongside the other concept files as prescribed by the JohnPapa Angular 1 style guide.
I am trying to ignore the *.spec.js files in my application concatenation step using glob's ignore option to prevent including the test code in the distributed app file but it's not working.
gulp.task('js:concat:application', function() {
return gulp.src([
our.js + 'app.js',
our.js + '**/*.module.js',
our.js + '**/*.js'
], { ignore: ['**/*.spec.js'] })
.pipe(concat('application.js'))
.pipe(gulp.dest(our.built.js));
});
I've tried '*.spec.js', '**/*.spec.js', and 'spec.js', and the same values but as the only value in an array as shown above.
gulp.src's documentation says that node-glob's options (which includes the ignore option) are supported, but adding them how the documentation describes doesn't appear to be working. At this point, I'm not sure why it's not working.
Versions:
gulp CLI: 1.2.2
gulp Local version: 3.9.1
node: 6.9.2
You can exclude specific files in gulp.src by prepending an exclamation mark to the pattern as indicated in the glob documentation.
gulp.task('js:concat:application', function() {
return gulp.src([
our.js + 'app.js',
our.js + '**/*.module.js',
our.js + '**/*.js',
'!**/*.spec.js'])
.pipe(concat('application.js'))
.pipe(gulp.dest(our.built.js));
});

Durandal optimization with Gulp and Gulp-Durandal not working

We are building an application with Durandal which is quite big at the moment and we currently looking into bundling all JS files located in the App folder into a main-built.js file. Pretty basic and usual stuff I guess.
I'm using Gulp with the Gulp-Durandal extension. Here our gulpfile :
var gulp = require('gulp');
var durandal = require('gulp-durandal');
gulp.task('build-portal', function () {
durandal({
baseDir: 'app',
main: 'main.js',
output: 'main-built.js',
almond: false,
minify: false
}).pipe(gulp.dest('app'));
});
And here's a snippet of our main.js file
require.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions'
},
shim: {
},
waitSeconds: 0
});
define('jquery', [], function () { return jQuery; });
define('knockout', [], function () { return ko; });
define('ga', function () { return ga; });
define(
["require", "exports", "durandal/app", "durandal/viewLocator", "durandal/system", "plugins/router", "services/logger", "modules/knockout.extensions", "modules/knockout.validation.custom"],
function (require, exports, __app__, __viewLocator__, __system__, __router__, __logger__, __koExtensions__, __koValidationCustom__) {
var app = __app__;
var viewLocator = __viewLocator__;
var system = __system__;
var router = __router__;
As you can see in the gulpfile, we do not want to use Almond but RequireJs instead, for some reasons almond isn't workin with our project and anyhow, we prefer RequireJs whether its bigger than almond at the end. That's where it look to brake. Running the command to build the main-built.js file took sometime but at the end I get the file built with everything in it.
The problem is that when I try to load the application, it is stuck to the loading screen. It doesn't go any further and there's no errors at all in the browser console.
I created a new project on the side to test if our code was somewhat faulty and found that it might not. You can found that project here :
https://github.com/maroy1986/DurandalGulpBundling
If I build that project with almond option to true, everything works fine but if I switch almound off to tell gulp to use RequireJs, I got the same behavior as our app. You got stuck at the loading screen, without any errors.
So here I am, I do read a lot on the subject but didn't found anything to solve this. Hope someone here already encounter these behavior and have a solution to share.
Thanks!
I had the same requirement and issue. It seems require.js wasn't calling the main module which will startup the Durandal app, that's why it's stuck in the loading screen. I was able to resolve it by implicitly calling the main module:
gulp.task("durandal", function() {
return durandal({
baseDir: "app",
main: "main.js",
output: "main-built.js",
almond: false,
minify: true,
rjsConfigAdapter: function(config) {
//Tell requirejs to load the "main" module
config.insertRequire = ["main"];
return config;
}
})
.pipe(gulp.dest("dist"));
});
I downloaded your project and tried building it with the latest versions of gulp and durandal. Initially it didn't build and gave me the following error:
TypeError: Cannot read property 'normalize' of undefined
This is a problem with the text-plugin of rjs and you can solve this by adding the following to your gulp-file (next to the almond, minify, output... properties):
rjsConfigAdapter : function(rjsConfig){
rjsConfig.deps = ['text'];
return rjsConfig;
}
Once I did that, the build finished and I could build with or without minify, almond and require and the application works fine.

jQuery file upload and RequireJS configuration

I'm trying to use jQuery file upload, but I'm getting stuck with the RequireJS configuration. We install our dependencies in a /ext/ folder, e.g:
/src
/ext
/jquery-file-upload
In my main.js I use the following config:
require.config({
paths: {
"ext/jquery-file-upload": "../ext/jquery-file-upload/js/jquery.fileupload"
}
});
require([
"ext/jquery-file-upload"
]);
But then RequireJS tries to load jquery.ui.widget.js from the root instead of as a relative file. It is located in the jquery-file-upload directory..
Does anyone know what I'm doing wrong, or does anyone know of a working RequireJS config for jQuery file upload?
Thanks,
Martijn
If you look at the jquery.fileupload.js file, at the top it declares its own dependencies
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'jquery.ui.widget'
], factory);
You need to edit your require.config path for the jquery.ui.widget item.
require.config({
paths: {
'jquery.ui.widget': 'your_path_here/jquery.ui.widget'
}
});
If I don't mistake, your problem is that your plugin - jquery-file-upload - tries to load its dependencies by itself.
The problem is that filepaths in JS are relative to the page loading the script file, not to the file itself (Relative Paths in Javascript in an external file). This explains why your file seems to be loaded relatively to the root and not the given path.
In this case, you probably will have to manipulate a bit of the plugin code and take a look at the explanations given here concerning requireJS and dependencies loading:
How do I use requireJS and jQuery together? .
Try mapping jquery.widget.ui to the correct path...
require.config({
paths: {
"ext/jquery-file-upload": "../ext/jquery-file-upload/js/jquery.fileupload"
"jquery.ui.widget": "../ext/jquery-file-upload/js/vendor/jquery.ui.widget"
}
});
require([
"ext/jquery-file-upload"
]);
For anyone else having this problem...this is the config that worked for us.Hope it helps someone
The paths declaration
paths: {
'jquery.ui.widget': '../../Scripts/FileUpload/jqueryui/jquery.ui.widget',
'jquery_iframe_transport': '../../Scripts/FileUpload/jquery.iframe-transport',
'jquery.fileupload': '../../Scripts/FileUpload/jquery.fileupload'
}
The Define statement
define(['jquery.ui.widget','jquery_iframe_transport','jquery.fileupload'])
The above is dependent on jquery being loaded. We are using Durandal hence dont need a shim but you will need to ensure jquery is loaded before anything else
The initialisation in code
function uploadFile() {
var url = '/Backload/UploadHandler';
$('#fileupload').fileupload({
url: url,
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo('#files');
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}
});
}
This is the basic upload example..

r.js optimizer resolving configured deps files

I try requireJS optimizer to pack all my scripts into one file and I cannot overcome one issue.
My requireJs configuration is
var require = {
// 'baseUrl': 'static/scripts',
'paths': {
'external': 'global/external'
},
'waitSeconds': 2,
// 'enforceDefine': true,
'deps': ['external/jquery-1.7.2'],
'config': {
}
};
requireJs will load everything that is in deps before it starts loading any other scripts. since jquery wraps itself with define function and with name jquery I can load it to my scripts simply by calling
var var $ = require('jquery');
This works great when code is not optimized.
PROBLEM:
when I run r.js (with node - but this I think is irrelevant) optimizer prints error that it cannot resolve jquery dependency.
There is nothing in requireJs optimizer faq on that. I tried play with configuring 'path' property but it didnt fix anything.
I removed deps property and added new element to paths
var require = {
// 'baseUrl': 'static/scripts',
'paths': {
'external': 'global/external'
'jquery': 'global/external/jquery-1.7.2'
},
'waitSeconds': 2,
...
};
it didnt play before because I tried to setup path to jquery like
'jquery': 'external/jquery-1.7.2'
thinking that external should evaluate to
'global/external/jquery-1.7.2'
then I just set path.jquery in build script (or as argument to r.js) once again and it worked

Resources