Have RequireJS load a specific library based on browser - requirejs

Our project is using a library that has two different versions depending on whether its running in IE or not-IE. We are currently using RequireJS to load libraries -- is there a way to configure RequireJS to load the library based on the detected browser? I've looked at the documentation but I can't find any examples that fit my use case.

What about using https://requirejs.org/docs/api.html#config-map ?
You can check the browser via user agent and then map the module to different one:
function isIe() {
// return true if is Internet Explorer
}
requirejs.config({
map: {
'*': {
'foo': isIe() ? 'foo-for-ie' : 'foo'
}
}
});

Related

Having Issues using Esri ArcGIS API for JavaScript in Lightning Web Component (require is not defined at eval)

I'm trying to implement Esri ArcGIS JS in Lightning Web Component. While using ArcGIS JS, the sample code uses require function to load modules. In order to do that I'm trying to use require.js. I downloaded it from here (Require.js). And then uploaded to my sandbox as static resource. I'm trying to use that static resource in my Lightning Web Component. I also added the script tag for the ArcGIS Javascript API in my Experience Cloud site's header as
<script src="https://js.arcgis.com/4.24"></script>
Lightning Web Component:
import { LightningElement, track } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import requireJS from '#salesforce/resourceUrl/requireJS';
export default class TestMap extends LightningElement {
renderedCallback() {
loadScript(this, requireJS).then(() => {
console.log('requireJS loaded');
require([
"esri/geometry/Extent"
], (
Extent
) => {
var initExtent = new Extent({
xmin: -15884312,
ymin: 1634835,
xmax: -6278767,
ymax: 7505198,
spatialReference: 102100
});
});
}).catch(exception => {
console.log(exception);
});
}
}
My problem right now, eventhough I can see in the Network tab that the require.js is loaded from static resource, require function cannot be found.
Exception message catched
I'm not sure where is the issue since this is how I loaded my all javascript files before.
I was expecting to see the the require function is working after the require.js script loaded from Static Resource.
This one is a bit tricky, I will try to guide you as much as I can.
First, don't put the script tag in your website header. This is a last chance solution, we'll keep it if nothing else work.
Second, requireJS is not compatible with LWC (or Locker Service to be precise). So you can forget it. loadScript is in someways similar.
Now the solution, usually I download the whole from a CDN and host it as a static resource. Then you can load it via loadScript and use it as per the documentation.
In case the library is really small, it could be created as a LWC and then be imported but usually libraries are too heavy regarding Salesforce limit.
Looking at the library, it seems that they do not provide any compiled full version (which is probably huge). In this case I would recommend to make a custom build locally containing only the necessary pieces of code and then uploading as a static resource. Unfortunately I can't help on this part as I still didn't do it myself yet.
Feel free to comment and I will improve my answer is it's unclear.

A javascript library fails to load with requirejs

Let me clear the context first. I have bought an admin panel template from themeforest and stuck on implementing that with requirejs. The seller does not provide support for implementation.
The theme requires the following JS file, in order to run:
https://altair_html.tzdthemes.com/assets/js/common.js
I have created a fiddle, where I have included the file and defined that with requirejs. But a function (moment) is not being defined. I dont know where I am doing wrong.
Check the fiddle here:
requirejs.config({
paths: {
'common': 'https://altair_html.tzdthemes.com/assets/js/common'
}
});
require(['common'], function (common) {
console.log(moment);
});
http://jsfiddle.net/tareksiddiki/q5kumwvg/
But the moment function loads when we load the external javascript (https://altair_html.tzdthemes.com/assets/js/common.js) within the <script> tag in old school way.

Load Google Maps + MarkerWithLabel together?

Is anyone else using Google Maps + MarkerWithLabel + RequireJS? I basically want to see if it's possible to eliminate the extra http request for MarkerWithLabel and somehow optimize how everything is loaded and initialized.
Right now I'm loading the Google Maps library dynamically from within a Require module (I need this for dynamic params), but I can only get MarkerWithLabel working after Google Maps has been loaded. Ideally it would be great to either fetch them together or at the very least preload MarkerWithLabel and keep the Google Maps handle (URL) dynamic.
I'm considering 'Delayed Module Evaluation' if there's no way to consolidate Maps + MarkerWithLabel. I'm curious how others are approaching this.
http://blog.millermedeiros.com/requirejs-2-0-delayed-module-evaluation-and-google-maps/
You can use requirejs async plugin. Basically you should end-up with something like :
require.config({
paths: {
/* Bower Libraries */
async: '../bower_components/requirejs-plugins/src/async',
markerlabel: '../bower_components/gmaps-makerwithlabel/index',
...
and after that, you can shim it to make sure google maps loads first:
markerlabel: {
deps: ['async!https://maps.googleapis.com/maps/api/js&sensor=false']
}
Take a look to this: https://github.com/lupugabriel1/gmaps-markerwithlabel-amd
Based on Google Maps MarkerWithLabel 1.1.9. This is basically a fork that adds src/markerwithlabel-amd.js.
This extension offers AMD support for Google Maps MarkerWithLabel utility library of Google Maps Javascript API v3. Also fixes the problem with requirejs optimizer.

Adding paths to RequireJS configuration on runtime

Ok, I already know that you should configure paths with RequireJS like this
require.config({
paths: {
name: 'value'
}
});
And call it like this.
require(['name'], function() {
/* loaded */
});
But the thing is, I'm working in environment in which I don't have access to the existing call to require.config(...). For those who care, the environment is Azure Mobile Services scheduled job. Microsoft has already included RequireJS in the environment and configured the paths. My question is two-fold.
1. How do I add paths to the existing require.config()?
I know calling require.config() again will destroy the existing configuration. Which is what I do not want to do.
2. How do I get to know which paths have already been configured?
I really wouldn't like to overwrite any existing path name or overwrite any existing library by accident.
Running require.config() again does not override your original config file. It actually extends it and adds your new paths to it. Right now I am using it this way, where configfile is also a require.config({})
<script data-main="configfile" src="require.js"></script>
<script>
require.config({
paths: {
prefix-name: 'path/to/file'
}
});
</script>
One way to avoid name collisions with Azure Mobile paths would be to simply prefix all your custom paths.
Disclaimer: I have never used Azure Mobile, just RequireJs. You may have to implement it a little differently but it is possible.

Grunt task to optionally include an AMD module for different environment

I'm developing a web app using Require.js for AMD and amplify.request to abstract away my AJAX calls. The other advantage to amplify.request is that I've defined an alternative module containing mocked versions of my requests that I can use for testing purposes. Currently, I'm switching between the two versions of my request module by simply commenting/un-commenting the module reference in my main.js file.
What I'd love to do is use Grunt to create different builds of my app depending on which module I wanted included. I could also use it to do things like turn my debug mode on or off. I'm picturing something similar to usemin, only for references inside JavaScript, not HTML.
Anyone know of a plugin that does this, or have a suggestion about how I could do it with Grunt?
On our current project we have a few different environments. For each of them, we can specify different configuration settings for the requirejs build.
To distinguish between these different environments, I've used a parameter target.
You can simply pass this to grunt by appending it to your call like
grunt --target=debug
And you can access this parameter in the Gruntfile, by using grunt.option, like
var target = (grunt.option('target') || 'debug').toLowerCase();
The line above will default to debug. You could then make use of the paths configuration setting of requirejs to point the build to the correct module. Example code below.
requirejs: {
compile: {
options: {
paths: {
"your/path/to/amplify/request": target === "debug" ? "path/to/mock" : "path/to/real",
}
}
}
}

Resources