Requirejs using shim - backbone.js

Using shim by requirejs2, there is a way to tell to requires that a module is already loaded?
Example:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="undescrore.js"></script>
<script type="text/javascript" src="require.js'"></script>
<script type="text/javascript">
require.config({
paths: {
"backbone": '/vendor/js/backbone-min.js'
},
shim: {
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['underscore', 'jquery'], // here I would like to load the already loaded library
}
}
});
</script>

Well, if underscore is already loaded and available, you do not need the shim at all. Backbone will happily load. If not, it's probably because underscore is not actually loaded.
It sounds however wrong to be only partially using require.js, you might as well AMD-load them all. To do that you will need to change your shim like this:
shim: {
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
underscore: {
exports: "_"
}
}
and of course update your paths.

I am not sure if you were able to find the best approach yet for your use case.
If you really - for some reason - need to add your other scripts without using RequireJS as in your code example #js999, then you would need to check if the global variable (jQuery, _) of those scripts exist and then define them as modules. From your code example it would look something like this:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="undescrore.js"></script>
<script type="text/javascript" src="require.js'"></script>
<script type="text/javascript">
// check for jQuery
if (window.jQuery) {
define('jquery', [], function () {
return window.jQuery;
});
}
// check for underscore
if (window._) {
define('underscore', [], function () {
return window._;
});
}
require.config({
paths: {
// remove the file extension (.js)
"backbone": '/vendor/js/backbone-min'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery']
}
}
});
</script>

Related

RequireJS configuration error - jQuery not found when calling Backbone

I'm trying to setup a require js project for learning purposes. I need to run a Backbone app.
Index.html, looks plain and simple:
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>RequireJS - Test drive</title>
<!-- data-main attribute tells require.js to load scripts/main.js after
require.js loads. -->
<script data-main="js/main" src="js/vendor/require.js"></script>
</head>
<body>
<h1>RequireJS - Test drive</h1>
</body>
</html>
Currently I have this config in my main.js: (which is the entry point in index.html for requirejs)
require.config({
paths: {
underscore: 'vendor/underscore-1.9.1.min',
jquery: 'vendor/jquery-3.4.1.min',
backbone: 'vendor/backbone-1.4.0.min',
app: 'app/app',
userModel: 'app/models/user.model',
userListView: 'app/views/user-list.view',
userSingleView: 'app/views/user-single.view',
},
bundles: {
'models': ['userModel']
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
},
});
// Start the app
define(['app'], (App) => {
return App.initialize();
});
In app.js, which I try to initiate the app with, I have the following:
define(['backbone'], (Backbone) => {
const initialize = () => {
console.log('App initialized.', Backbone);
const data = {title: 'title'};
const view = 0; // new View here....
};
return {
initialize: initialize
}
});
Now, if I remove backbone as a dependency, I am able to see the console.log message in the browser. If I leave it there, then the console throws this error:
require.js:5 GET http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js net::ERR_ABORTED 404 (Not
Found)
require.js:5 Uncaught Error: Script error for "js/vendor/jquery-3.4.1.min", needed by: backbone
https://requirejs.org/docs/errors.html#scripterror
at makeError (require.js:5)
at HTMLScriptElement.onScriptError (require.js:5)
Inspecting the network tab, I can see that the jQuery dependency has errored out, and for some reason an additional /js has been added to the path, which results in a 404 error for jQuery, but only when I try to use Backbone on the app.js file.
Path looks like this, with the additional /js added to it:
http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js
What is it that I am missing in the configuration/setup of the application?
I believe you should set baseUrl in your config
require.config({
baseUrl: '/js'
});

Lazy-load MonacoEditor

I have the following code to load MonacoEditor in index.html of my AngularJS website:
<link rel="stylesheet" data-name="vs/editor/editor.main" href="/monaco-editor/min/vs/editor/editor.main.css" />
<script src="/monaco-editor/min/vs/loader.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.js"></script>
<script>
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
console.log(monaco)
</script>
Running the website displays well monaco, which will be used in a further JavaScript file.
Now, I want to load MonacoEditor by ocLazyLoad:
.state('addin', {
abstract: true,
template: '<ui-view/>',
resolve: {
loadAddinCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({files: [
"/monaco-editor/min/vs/editor/editor.main.css",
"/monaco-editor/min/vs/loader.js",
"/monaco-editor/min/vs/editor/editor.main.nls.js",
"/monaco-editor/min/vs/editor/editor.main.js"
]}).then(function () {
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
console.log(monaco)
})
}]
}
})
The above code returns ReferenceError: monaco is not defined. Does anyone know why this happens?
Actually, I don't understand well the purpose of require.config, it seems to make the code much less flexible. Does anyone have an alternative to that?
You have loaded the dependencies, yet not loaded Monaco. Try this after your require.config:
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
require(['vs/editor/editor.main'], function onMonacoLoaded(){
console.log(monaco);
});

angular.module undefined when using webpack

Angular 1.5.8, Webpack 2.1.0-beta.25
I'm getting an error that angular is undefined when I try to use it with webpack. I've tried to load angular as an external and as part of the package as detailed here: Webpack ProvidePlugin vs externals?
I've added this code at my entry point to test:
import * as angular from 'angular';
// import angular from 'angular'; <!-- have tried this too
angular.module('test', []);
I can hold my mouse over the line of code in the debugger and it seems to be able to find angular. Yet once I hit F10 I get the error.
My webpack.common.config:
externals: {
jquery: 'jQuery',
window: 'window',
angular: 'angular'
},
new webpack.ProvidePlugin({
$: 'jquery',
angular: 'angular',
_: 'lodash',
moment: 'moment'
}),
Index.html (when providing externally):
<body id="bootstrap-overrides">
<sb-app></sb-app>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/slideout/0.1.11/slideout.min.js"></script>
<script type="text/javascript" src="polyfills.bundle.js"></script>
<script type="text/javascript" src="vendor.bundle.js"></script>
<script type="text/javascript" src="sbMain.bundle.js"></script>
</body>
sbMain.bundle.js is where the error is occuring, even though it's loaded last (angular is first)

Apache Zeppelin - Angular Display system load external Angular modules

How would it be possible to register new Angular modules in Zeppelin:
Based on this Angular example
https://material.angularjs.org/latest/getting-started
Here is the possible converted code in Zeppelin (the same code works fine in a standard webapp)
print(s"""%angular
<div id="myAngularApp">
<md-button class="md-raised md-primary">Angular Material Button</md-button>
</div>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc2/angular-material.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.22/require.js"></script>
<script>
require.config({
paths: {
'angular': 'http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min',
'ngAnimate': 'http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.min',
'ngAria': 'http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-aria.min',
'ngMaterial': 'http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc2/angular-material.min'
},
shim: {
'ngAnimate': ['angular'],
'ngAria': ['angular'],
'ngMaterial': {
deps: ['ngAnimate', 'ngAria']
}
}
});
require([ 'angular', 'ngMaterial' ], function () {
var app = angular.module('StarterApp', ['ngMaterial']);
angular.bootstrap(document.getElementById('myAngularApp'), ['StarterApp']);
return app;
});
</script>
""")
Unfortunately, I didn't find any ways to make it work. I tried with multiple ways, nothing works!
In brief, how to register a new Angular Module within Zeppelin?
The Angular Display system looks nice but is useless if no external modules can easily be registered.
Please, help :) Or provide a concrete example

No module and Modernizr error when adding angular to requirejs

Im trying to add AngularJS to my web application which already makes use of RequireJS. When loading my test page, i am seeing:
1) Error: No module: MyApp
...),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$prov...
2) TypeError: Modernizr is undefined
if (!Modernizr.history) {
I am using AngularJS v1.1.5
Here's my tree:
resources
- CSS
- js
- controllers
- MainController.js
- libs
- angular.js
- jquery.js
- require.js
- mondernizr.js
......
......
......
main.js
mainApp.js
pages
test.html
main.js
(function(require) {
'use strict';
require.config({
baseUrl: '/resources/js',
paths: {
'zepto' : 'libs/zepto',
'jquery' : 'libs/jquery',
'angular' : 'libs/angular',
'router' : 'libs/page',
'history' : 'libs/history.iegte8',
'event' : 'libs/eventemitter2'
},
shim: {
'zepto' : { exports: '$' },
'angular' : { exports : 'angular' },
'router' : { exports: 'page'},
'modernizr' : { exports: 'Modernizr' }
}
});
require([ 'jquery', 'angular', 'routes', 'modernizr', 'event' ], function($, angular, routes, Modernizr, Event) {
function bootstrap() {
var app = new Event(),
router = routes(app);
if (typeof console !== 'undefined') console.info('>> module routes loaded ... executing router');
router({ click: false, popstate: false });
if (typeof console !== 'undefined') console.info('>> executed router');
}
$(function() {
if (!Modernizr.history) {
require([ 'history' ], bootstrap);
require([ 'controllers/MainController' ], bootstrap);
} else {
require([ 'controllers/MainController' ], bootstrap);
bootstrap();
}
});
});
})(this.require);
mainApp.js
define(['angular'], function(angular) {
return angular.module('MyApp', []);
})
MainController.js
require(['mainApp'], function(mainApp) {
mainApp.controller('MainController', function($scope) {
$scope.data = {message: "Hello"};
})
});
test.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<script src="/assets/js/vendor/require.js" data-main="/assets/js/main"></script>
</head>
<body>
<div ng-controller="MainController">
{{ data.message + " world" }}
</div>
</body>
</html>
Any help appreciated.
The No module: MyApp problem is causes by the Angular automatic initialization: <html ng-app="MyApp">. Angular loads before mainApp.js, sees the ng-app and tries to find a module which is not (yet) there.
The solution is to manually bootstrap Angular from within main.js and inside the document load event, as described here.
I am not sure about the problem with Modernizr; I guess you are NOT loading it at all. RequireJs is not complaining because of the shim. How are you loading it? It is not included in your paths configuration. You may want to load Modernizr as independent script before all other scripts (as per recommendations), in which case no paths configuration is needed and the shim is enough.

Resources