MathJax with RequireJS, how to set config - requirejs

Usually, I can include MathJax in a script tag like:
<script src="path-to-MathJax/MathJax.js?config=default"></script>
But with RequireJS, I can include the config, but what happens to the config?

It's now explained in the Mathjax documentation :
https://github.com/mathjax/MathJax-docs/wiki/Integrating-mathjax-into-x%3A-require.js

The requirejs documentation on github mentions that you can gain fine-grained control on the URL, by overriding the requirejs load function:
https://github.com/jrburke/requirejs/wiki/Fine-grained-URL-control
<script src="require.js"></script>
<script>
(function () {
var load = requirejs.load;
requirejs.load = function (context, moduleId, url) {
//modify url here, then call original load
return load(context, moduleId, url);
};
//Now load code.
require(['main']);
}());
</script>

Not ideal as you would loose the ability to load it only when required. If nothing else works, you can always use this approach as last resort.
Instead of loading MathJax from within require, load it as a script.
Instead of:
<script data-main="main" src="libs/require.js"></script>
Try this:
<script src="libs/require.js"></script>
<script src="path-to-MathJax/MathJax.js?config=default"></script>
<script>require(["main"]);</script>

You could also load require.js and do
<script>require(["path-to-MathJax/MathJax.js?config=default"]);</script>

Related

PouchDB and SvelteKit

I want to use PouchDB with SvelteKit. I have copied pouchdb-7.2.1.js to /src/libd in SvelteKit and renamed it to pouchdb.js. Pouchdb should run in the browser. Therefore I have used ssr=false to suppress server side rendering. I get the first error at the import statement. This is my first very short page (couchdb.svelte):
<script context="module">
export const ssr = false;
</script>
<script>
import PouchDB from '$lib/pouchdb.js';
</script>
I get an error 500
import not found: PouchDB
I have tried a lot of diffent version without any success. For example:
import PouchDB from 'pouchdb-browser'; (After npm i pouchdb-browser)
import PouchDB from 'pouchdb'; (After npm i pouchdb)
What is the correct way to use pouchdb?
Here is a work-around that uses PouchDB via a script tag:
index.svelte:
<script>
import { onMount } from 'svelte'
// Ensure execution only on the browser, after the pouchdb script has loaded.
onMount(async function() {
var db = new PouchDB('my_database');
console.log({PouchDB})
console.log({db})
});
</script>
<svelte:head>
<script src="//cdn.jsdelivr.net/npm/pouchdb#7.2.1/dist/pouchdb.min.js"></script>
</svelte:head>
When imported, PouchDB seems to expect a certain environment that Svelte/Vite/Rollup does not provide. (Svelte/Vite is happiest with proper ESM modules; PouchDB seems to be a "window.global" script that was converted to a JS module.)
There may be a way to modify the configuration to create the environment expected by PouchDB. I think you would have to modify the svelte.config.cjs file. (Specifically the vite section that determines the rollup configuration.)
You might find some hints in this related issue for PouchDB + Angular.
I would just use the <script> work-around above.
For future googlers trying to integrate pouchdb-browser and/or RxDB with sveltekit here are the changes to "fix" the enviornment for pouchdb in the browser when using vite.
Add to your <head> section before %svelte.head%
<script>
window.process = window.process || {env: {NODE_DEBUG:undefined, DEBUG:undefined}};
window.global = window;
</script>
In svelte.config.js add the optimizeDeps to config.kit.vite.optimizeDeps
optimizeDeps: {
allowNodeBuiltins: ['pouchdb-browser', 'pouchdb-utils', 'base64id', 'mime-types']
}
Here is a commit that makes these changes to my app:
https://github.com/TechplexEngineer/bionic-scouting/commit/d1c4a4dcdc7096ae40937501d97a7ef9ee10ab66
Thanks to:
pouchdb/pouchdb#8266 (comment)
I have been battling this very same problem for a while. I decided to go a different route. This may not be right, but it is working.
I added two scripts to my app.html head:
<head>
<meta charset="utf-8" />
<meta name="description" content="" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-
scale=1" />
<!-- Call the Pouchdb import -->
<script type="text/javascript" src="../src/lib/pouchdb.js">
</script>
<!-- create new databases for use in the app -->
<script>
const user = new PouchDB('user');
</script>
%svelte.head%
</head>
Then in any component that I want to use the database, I add an additional script tag to define the variable "user":
<script lang="ts" context="module">
//Declare the database name so that it is recognized.
declare const user;
</script>
<script lang="ts">
//Example use of database.
const addUser = () => {
//Call the database by name established in app.html
user.put({
_id: 'someid',
firstName: 'Jon',
lastName: 'doe'
});
};
</script>
That has been the easiest method for me to employ PouchDB with SvelteKit. Every other solution required significant modifications to configuration files, changes to environment variables, and unnecessary adaptations of code throughout the application. I hope this helps.

System.import async module loading conflicts with scripts tags sync loading

I started using JSPM with atom/electron for porting a web site I've built using Marionette.
I have all my App written around Marionette modules so I want to load all the JavasSript files before starting the app.
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
loadApp = System.import('./scripts/app_definition').then(function(m){
window.App = m['App'];
});
</script>
<!-- inject:js -->
##LOTS INJECTED SCRIPTS THAT NEEDS window.App to be defined##
<script src="compiled/modules/video/video_app.js"></script>
<!-- endinject -->
<script type="text/javascript">
loadApp.then(function(){
App.start();
})
</script>
I'm having problems with the Async nature of System.import(). How would you load the scripts after System.import has finished loading the App code?
For production I have no problem with this, because I would concatenate all the files in a single js module and the load that module using System.import, but that would be a nightmare to debug, I would prefer to have the files loaded separately.
Any thoughts? Thanks!
Global variables are a big no no when using ES6 modules.
You could load your scripts after the app definition:
loadApp = System.import('./scripts/app_definition').then(function(m){
window.App = m['App'];
var scriptEl = document.createElement('script');
scriptEl.src = "compiled/modules/video/video_app.js";
document.head.appendChild(scriptEl);
});
But i'm not sure what's the use of having JSPM here in the first place. So the real solution would be to transform all your modules to ES6 import syntax and avoid global variables all together.

using EJS with requirejs

I had a problem include ejs into requirejs. I put <script data-main="js/app" src="js/require.js"></script> in my and inside of body create EJS object.
In my app.js,
require.config({
paths: {
//library
jquery: 'lib/jquery-1.11.1.min',
jquerymobile: "lib/jquery.mobile-1.4.2.min",
text: 'text',
ejs: 'ejs_0.9_alpha_1_production'
},
shim: {
"ejs": {
exports: 'ejs'
}
}
});
require(['jquery', 'jquerymobile','text','ejs'], function ($, mobile) {
console.log('jQuery version:', $.fn.jquery); // 1.9.0
});
when it is running, it throws EJS is not defined error. However, if I include
<script type="text/javascript" src="js/ejs_0.9_alpha_1_production.js"></script>
in the head, everything goes well.
Regards
Hammer
Lately I just get through similar trouble using ejs from the browser. I post the answer as it could save somebody's time.
I suggest you double check your ejs library is indeed coming from https://github.com/visionmedia/ejs. There is quite some tuned version of ejs around right now because it is becoming very popular. Unfortunatly most of thoses versions target specific needs and return different object to the window (eg. EJS instead of ejs) or don't even return anything usefull for requirejs.
=> In both case this would expalin why your shim exports return undefined.
Once you get it to load properly, let me also spot on an awesome requirejs-ejs plugin at https://github.com/whitcomb/requirejs-ejs . It could help you preload and render your template in a nice requirejs way.

Behavior when async: false and true

I am using AMD way of coding and when I make async:false I don't see any difference in execution behavior i.e. making async true or false I see no difference.
Please have a look at code snippet below:
<html>
<script type="text/javascript" src="../../dojoroot/dojo/dojo.js" data-dojo-config="async:true, parseOnLoad:true"></script>
<script type="text/javascript">
require(["dojo/domReady!"], function(){
alert("I am inside DOM ready");
});
require(["dojo/ready"], function(ready){
ready(function(){
alert("I am inside ready");
});
});
</script>
<body>
some div's here
</body>
</html>
OUTPUT:
In both the case i see first "I am inside DOM ready" and then "I am inside ready" alert next.
Could you please explain what is the difference if I add async : true and async:false?
Thanks.
To answer your question, if async is set to a truthy value (true, 1, etc.), dojo/domReady and dojo/ready will be loaded when require is called. If async is not set, these modules are loaded immediately when dojo.js is loaded. So there is no impact on how your code executes, it’s just about when those modules become available for use.
This is snippet from Dojo AMD description:
For backwards-compatibility, the loader starts up in synchronous mode by default, which loads the Dojo base API automatically:
<script src="path/to/dojo/dojo.js"></script>
<script>
// the dojo base API is available here
</script>
To put the loader in the AMD mode, set the async configuration variable to truthy:
<script data-dojo-config="async: 1" src="path/to/dojo/dojo.js"></script>
<script>
// ATTENTION: nothing but the AMD API is available here
</script>
Note that you can only set the async flag before dojo.js is loaded, and that in AMD mode, neither Dojo Base nor any other library is automatically loaded - it is entirely up to the application to decide which modules/libraries to load.

Chrome Extension: Using addEventListener()

In the tutorial for migrating a Google Chrome Extension to Manifest Version 2, I am directed to Remove inline event handlers (like onclick, etc) from the HTML code, move them into an external JS file and use addEventListener() instead.
OK, I currently have a background.html page that looks like this…
<html>
<script type="text/javascript">
// Lots of script code here, snipped
…
</script>
<body onload="checkInMyNPAPIPlugin('pluginId');">
<object type="application/x-mynpapiplugin" id="pluginId">
</body>
</html>
Following another directive, I've moved that Lots of script code into a separate .js file, and following this directive, I need to remove the onload= from the body tag, and instead cal addEventListener() in my script code. I've tried several approaches, but am apparently guessing wrong. What will that code look like? In particular, upon what object do I invoke addEventListener()?
Thanks!
I normally use this for body onload event...
document.addEventListener('DOMContentLoaded', function () {
// My code here.. ( Your code here )
});
For somethings it is working.. but really, I think we should use..
window.addEventListener('load', function () {
document.getElementById("#Our_DOM_Element").addEventListener('change - or - click..', function(){
// code..
});
});

Resources