Unable to get react to work in requirejs environment - reactjs

I have a regular ol' requirejs app, that pulls in modules in regular JS I write. I really want to start using reactjs but am not even able to get it to load with out throwing errors in the console.
My Paths
'react': '../node_modules/react/cjs/react.production.min', // there is a cjs and a umd (Universal Module Definition) version, I dont think I am UMD. we are Asynchronous Module Definition (AMD)
'reactDOM': '../node_modules/react-dom/cjs/react-dom.production.min',
'JSXTransformer': 'vendors/react/JSXTransformer-0.10.0',
'jsx': 'vendors/react/jsx',
Is it possible that there is a shim dependency that I need to setup?
'react' : {
'deps' : ['jquery']
},
'reactDOM' : {
'deps' : ['jquery']
}
I have also included them normally such as
require(["jquery", "jqueryUi", "bootstrap", "react", "reactDOM", "front", "owlCarousel", "select2", "blockui", ], function ($, jqueryUi, bootstrap, React, ReactDOM, front, owlCarousel, select2, blockui) {
$(document).ready(function(){
require([ $('#requirePageSpecificJs').val() ]); // this is set in php, result: "/require-mturk.js"
});
});
I get this error, when loading a page.
I am completely new to React, so I may be missing some things. Does the latest react require Babel to run, and if so do I need to include babel as a package, and add that as a shim? I am seeing some other posts of using requirejs with react but it is requiring different tools and stuff. completely lost here.

Related

babel: polyfill Array.from for IE11 support

I'm currently having trouble getting my React application working in IE11. The problem seems to be that some of the newer ES6 stuff isn't available in IE11. So my goal is to polyfill the missing functionality. I'm using nwb [1] which is a zero-configuration setup for React applications. However, I'm unsure how to configure Babel (or Webpack ?) to polyfill certain methods like Array.from. It looks like fetch, Promise, and Object.assign are all polyfill-ed but not Array.from for example. Any help would be greatly appreciated.
Here is my nwb.config file:
module.exports = {
type: 'react-app',
webpack: {
define: {
VERSION: JSON.stringify(require('./package.json').version),
HOSTNAME: JSON.stringify(process.env.NODE_ENV === 'production' ?
'https://xyz.azurewebsites.net' :
'http://localhost:8080')
},
rules: {
babel: {
test: /\.jsx?/
}
},
extra: {
resolve: {
extensions: ['.jsx']
},
devtool: '#inline-source-map'
},
html: {
favicon: 'src/img/favicon.ico'
}
}
};
Thanks,
[1] A toolkit for React app. https://github.com/insin/nwb
Sounds like you need to add babel-polyfill to your project.
This will emulate a full ES2015+ environment and is intended to be
used in an application rather than a library/tool. This polyfill is
automatically loaded when using babel-node.
This means you can use new built-ins like Promise or WeakMap, static
methods like Array.from or Object.assign, instance methods like
Array.prototype.includes, and generator functions (provided you use
the regenerator plugin). The polyfill adds to the global scope as well
as native prototypes like String in order to do this.
The easiest way for you would probably be to import it at the top of your main js file:
import 'babel-polyfill';

How can I declare the dependencies of lazy loaded (ocLazyLoad) features (e.g. ngAnimate, ui-bootstrap,..)?

I want to load angular-animate and angular-ui-bootstrap only for a certain view and for this reason I use oc.lazyLoad. In most cases it works properly.
In the following example I have some troubles (Errror: [$injector:nomod] Module 'ngAnimate' is not available!):
That's my module:
angular.module('myApp.whatEver', ['oc.lazyLoad', 'ngAnimate', 'ui.bootstrap'])
.controller('WhatEverController', ['$ocLazyLoad', function($ocLazyLoad) {
$ocLazyLoad.load('icons_and_fonts'); // works
$ocLazyLoad.load('angular-animate'); // does not work
$ocLazyLoad.load('angular-ui-bootstrap'); // does not work
}]);
The problem is, it is too early to declare dependencies at the top ('ngAnimate' and 'ui-bootstrap') because they are placed in the controller below and will be lazy-loaded.
What/how is the correct way to do that?
The following example runs without errors and ng-Animate and ui-boostrap have been loaded, but not available in the view because of missing dependencies.
angular.module('myApp.whatEver', ['oc.lazyLoad'])
.controller('WhatEverController', ['$ocLazyLoad', function($ocLazyLoad) {
$ocLazyLoad.load('icons_and_fonts'); // works
$ocLazyLoad.load('angular-animate'); // is loaded but not available
$ocLazyLoad.load('angular-ui-bootstrap'); // is loaded but not available
}]);
It currently works only then if I integrate script files directly (in the main view - index.html) and I forgo lazy loading (what is not my purpose):
Excerpt: index.html
<script src="components/angular-ui-bootstrap/ui-bootstrap-tpls-0.14.1.min.js"></script>
<script src="components/angular-animate/angular-animate.min.js"></script>
Excerpt: Whatever.js
angular.module('myApp.whatEver', ['oc.lazyLoad', 'ngAnimate', 'ui.bootstrap'])
.controller('WhatEverController', ['$ocLazyLoad', function($ocLazyLoad) {
$ocLazyLoad.load('icons_and_fonts'); // works
}]);
Some Additional information (not needed for the answer but for the sake of completeness) about ocLazyLoadProvider.config...
// LAZY LOAD
$ocLazyLoadProvider.config(
{
modules: [
{
name: 'icons_and_fonts',
files: [
'components/font-awesome/css/font-awesome.min.css',
'components/weather-icons/css/weather-icons.min.css'
]
},
{
name: 'angular-ui-bootstrap',
files: [
'components/angular-ui-bootstrap/ui-bootstrap-tpls-0.14.1.min.js'
]
},
{
name: 'angular-animate',
files: [
'components/angular-animate/angular-animate.min.js'
]
}
],
debug: true,
events: true
}
)
A couple of things:
Put the core Angular modules first in your block before you add Angular UI Bootstrap.
What are you trying to accomplish by lazy loading?
IMO, the right solution here, if you REALLY want lazy loading, is to use either AMD or ES6 import syntax with commonJS (preferably the latter, ES6 w/ commonJS) as it will do what you want by design and not require a 3rd party library.
Finally, this question has nothing to do with Angular or Angular UI bootstrap, but rather, generic Javascript module loading. You could replace the two with two random, but related, libraries and the same solution would apply.

In the ui-router-extras demo, I want to use ng-grid in module1 but it's not working

In my project, I hope the lazy loaded modules can add their own state, so I found the ui-router-extras. It's really useful for me, but when I want to use ng-grid in the lazy loaded module like the module1 in demo, the module1.js file looks like this:
define(['angularAMD', 'ngGrid'], function () {
var app = angular.module("module1", ['ui.router','ngGrid']);
...
and the main.js file looks like this:
require.config({
waitSeconds: 100,
paths: {
"angularAMD": "../../lib/angularAMD",
...
"jQuery": "../../lib/jquery",
"ngGrid": "../../lib/ng-grid-2.0.14.debug"
},
shim: {
"angular": { exports: "angular" },
...
"ngGrid": ["angular", "jQuery"],
},
deps: ["app"]
});
But I got an exception from ng-grid : "Uncaught TypeError: Cannot read property 'factory' of undefined". I found the ng-grid source code where the exception happened:
angular.module('ngGrid.services').factory('$domUtilityService',['$utilityService', '$window', function($utils, $window) {....}
So I found in the lazy loaded module, get module by angular.module('mymodule') returns the undefined. Is there something I forgot to write, or is there another way to use ng-grid or other plugin in the lazy load module with ui-router-extras future?
You need to use the 'ngload' plugin for AngularAMD to load a module on the fly.
Excerpt from the docs:
3rd Party AngularJS Modules
3rd party AngularJS modules, meaning any module created using angular.module syntax, can be loaded as any normal JavaScript file before angularAMD.bootstrap is called. After bootstraping, any AngularJS module must be loaded using the included ngload RequireJS plugin.
define(['app', 'ngload!dataServices'], function (app) {...});
In case you need to load your module using the RequireJS plugin or if you have complex dependecies, you can create a wrapper RequireJS module as below:
define(['angularAMD', 'ui-bootstrap'], function (angularAMD) {
angularAMD.processQueue();
});
In this case, all dependencies will be queued up and when .processQueue() is called, it will go through the queue and copy them into current app using app.register:
https://github.com/marcoslin/angularAMD

Chrome extension using RequireJS, Backbone (Chaplin) conflicts

I am creating a Google Chrome Extension that have to add content on the visited websites (like a toolbox).
I have to use RequireJS and BackboneJS (Chaplin) and everything is ok except when i'm visiting a website using RequireJS (and Backbone, but the problem seems to come from RequireJS conflicts).
(This is when I use content scripts to include a -script- tag that includes RequireJS.)
I suppose it's normal to have conflicts if I add content directly in the page so I tried the solution here : Loading multiple instances of requireJS and Backbone
It seems to work (for now), but the website is trying to reload his own RequireJS file (with his path, but in my extension) before loading mine and I'm afraid it could lead to unexpected behaviour.
Plus, I have to precise my file paths in requirejs.config or it's looking for them in Bitbucket sources (cloudfront). (Maybe it's normal though)
Example with bitbucket :
Denying load of chrome-extension://mgncmiffelpdhlbkkmmaedbodabdchea/https://d3oaxc4q5k2d6q.cloudfront.net/m/7aaf1677069c/amd/build/main.js?8uxr. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
<--------- This file is Bitbucket's RequireJS, Bitbucket is still working fine though
Is there another solution I didn't find yet ? Or am I doing it wrong ? I'm a beginner with RequireJS (and Chrome ext.. and Backbone...) so I might have missed something.
Here is the Content script part in manifest.json
"content_scripts": [
{
"matches": ["https://*/*", "http://*/*"],
"js": ["bower_components/requirejs/require.js",
"extension/init-app.js",
"extension/main.js"]
}],
init-app.js is Rob's script
require.load = function(context, moduleName, url) {
url = chrome.extension.getURL(url);
var x = new XMLHttpRequest();
// Append Math.random()... to bust the cache
x.open('GET', url + '?' + Math.random().toString(36).slice(-4));
x.onload = function() {
var code = x.responseText;
x += '\n//# sourceURL=' + url; // Optional, for debugging.
window.eval(code);
context.completeLoad(moduleName);
};
x.onerror = function() {
// Log error if you wish. This is usually not needed, because
// Chrome's developer tools does already log "404 Not found"
// errors for scripts to the console.
};
x.send();
};
and main.js contain requirejs.config + app
// Configure the AMD module loader
requirejs.config({
skipDataMain: true,
// The path where your JavaScripts are located
baseUrl: 'extension',
// Specify the paths of vendor libraries
paths: {
jquery: '../bower_components/jquery/jquery',
underscore: '../bower_components/lodash/dist/lodash',
backbone: '../bower_components/backbone/backbone',
handlebars: '../bower_components/handlebars/handlebars',
text: '../bower_components/requirejs-text/text',
chaplin: '../bower_components/chaplin/chaplin',
application: '/extension/application',
routes: '/extension/routes',
},
// Underscore and Backbone are not AMD-capable per default,
// so we need to use the AMD wrapping of RequireJS
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
handlebars: {
exports: 'Handlebars'
}
}
// For easier development, disable browser caching
// Of course, this should be removed in a production environment
//, urlArgs: 'bust=' + (new Date()).getTime()
});
// Bootstrap the application
require(['application', 'routes'], function(Application, routes) {
new Application({routes: routes, controllerPath: 'scripts/controllers/', controllerSuffix: '-controller'});
});
It works on gooogle.com for instance, but I get
GET chrome-extension://ccgfmmmnebacpnbdpdnphmnmicaooddg/extension/Home.js?9zfr net::ERR_FILE_NOT_FOUND
on https://www.cloud9trader.com (website using RequireJS) because it has
<script data-main="/0.2.59/scripts/Home.js" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js"></script>
in its source. To summarize I just need the script to ignore the "current" website Require file.
The skipDataMain option is synchronously checked when require.js is loaded. Setting this variable after loading require.js has no effect on the loader any more, because the data-main scan has already run at that point.
The correct way to skip data-main is to declare the configuration before loading require.js, as follows:
// extension/config.js
var require = {
skipDataMain: true
};
manifest.json:
{
...
"content_scripts": [{
"matches": ["https://*/*", "http://*/*"],
"js": [
"extension/config.js",
"bower_components/requirejs/require.js",
"extension/init-app.js",
"extension/main.js"
]
}],
...
}

Issues initialising AngularStrap with Require.js

I'm looking to use AngularStrap in an existing Angular.js application which is using require.js as the module loader. I'm having trouble getting AngularStrap loaded correctly in the application. When I try to include 'angularStrap' in my Angular module, it fails to initialise. Below is an extract from my requirejs config.
paths: {
'angular' : 'lib/angularjs/angular',
'angularStrap': 'lib/angularstrap/angular-strap',
'angularStrapTpl': 'lib/angularstrap/angular-strap.tpl',
},
shim: {
'angularStrap' : {
deps : [ 'angular', 'angularStrapTpl' ],
},
}
Has anyone managed to use AngularStrap with require.js? I suspect my dependencies are slightly incorrect.
Yo need to add angular-animate to your requirejs configuration.
Github Link: https://github.com/Augus/ngAnimate

Resources