Require.js load CDN bootstrap and CDN popper - javascript

I wish to use require.js to load CDN hosted bootstrap and jquery.
I realise that this question has been asked before (Refer Steve Eynon's answer to Issue Loading PopperJS and Bootstrap via RequireJS, Even After Using Recommended PopperJS Version), but the posted answers do not work for me.
What I have tried so far
The host html file has content ...
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script data-main="js/market-place" src="js/lib/requirejs/require.min.js"></script>
</head>
<body>
html content etc.
</body>
</html>
File js/market-place.js has content ...
console.log( 'market-place.js');
requirejs(['./decision-market-common'], function(){
console.log( 'common requirement met.');
require(['bootstrap'], function( bootstrap){
console.log( 'bootstrap requirement met.');
});
});
File js/decision-market-common.js has content ...
console.log( 'decision-market-common.js');
requirejs.config({
paths: {
jquery : 'https://code.jquery.com/jquery-3.3.1.slim.min',
popper : 'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min',
bootstrap: 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min'
},
shim: {
bootstrap: {
deps: ['jquery', 'globalPopper']
}
}
});
define( 'globalPopper', ['popper'], function( p){
window.Popper = p;
console.log( 'global Popper is set.');
return p;
});
Result
Using Chrome as my development browser, I get the following results, at first in the javascript console ...
market-place.js
decision-market-common.js
common requirement met.
global Popper is set.
But then I get javascript error:
Failed to load resource: net::ERR_FILE_NOT_FOUND
require.js is trying to load ./popper.js, even after it has succesfully loaded the CDN popper.js ! Why?

The answer on this question / at Issue Loading PopperJS and Bootstrap via RequireJS, Even After Using Recommended PopperJS Version didn't work for me.
My scenario was:
Using Bootstrap 4.1.3 (not possible to move to a different version)
Unable to use the bundled version, as I wanted to change the defaults within Popper (specifically, to disable GPU Acceleration to resolve some issues with blurry text in a tooltip)
Using the bundled version, I wasn't able to access the version of Popper "inside" Bootstrap to change the defaults.
Eventually, I came across the "map" option within RequireJS (https://requirejs.org/docs/api.html#config-map). I added this to my RequireJS config:
map: {
'*': {
'popper.js': 'popper'
}
}
That resulted in RequireJS resolving Popper correctly.
Not a perfect solution and I can't guarantee it will work for anyone else, but I spent a while on this, so I hope this helps someone!

And the answer is ...
use bootstrap version 4.0.0-beta. Version 4.0.0-beta works, but any version later (4.0.0 through to 4.1.3) is broken, with respect to requirejs support.
An alternative is to use the bundle version of bootstrap, and then you can use the latest version and don't need to link popper. There is no CDN of bundle bootstrap, so you would need to make a local copy. In this case, file js/decision-market-common.js looks like:
need to explicitly
console.log( 'decision-market-common.js');
requirejs.config({
paths: {
jquery : 'https://code.jquery.com/jquery-3.3.1.slim.min',
bootstrap: 'lib/bootstrap/bootstrap.bundle.min'
},
shim: {
bootstrap: {
deps: ['jquery']
}
}
});
Also, one small point: It is better to use requirejs() rather than require() (, I think?).

Related

What is the correct way to add a NPM package to a Laravel 9 project with Laravel Mix?

Laravel Mix introduces itself as
An elegant wrapper around Webpack for the 80% use case.
I believe I have a widespread use case, and I want to know if the 80% covers this and how to do it right. It could be any other package, but I have editor.md as an example. They want you to install it with npm i editor.md and use it like the following.
<link rel="stylesheet" href="editor.md/css/editormd.min.css" />
<div id="editor">
<!-- Tips: Editor.md can auto append a `<textarea>` tag -->
<textarea style="display:none;">### Hello Editor.md !</textarea>
</div>
<script src="jquery.min.js"></script>
<script src="editor.md/editormd.min.js"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("editor", {
// width: "100%",
// height: "100%",
// markdown: "xxxx", // dynamic set Markdown text
path : "editor.md/lib/" // Autoload modules mode, codemirror, marked... dependents libs path
});
});
</script>
Now I want to know how to get the following paths right.
editor.md/css/editormd.min.css
jquery.min.js (not a dependency)
editor.md/editormd.min.js
editor.md/lib/
My ideas/questions:
I could copy the CSS and JS files with Mix.
mix.copy("node_modules/editor.md/css/editormd.min.css", "public/css/editormd.min.css");
mix.copy("node_modules/editor.md/editormd.min.js", "public/js/editormd.min.js");
But then I miss all the files from the lib folder (4th path). I could copy this folder as well. I could copy the entire node_modules/editor.md folder to my assets folder, but this feels too much. And finally, where is jQuery coming from? Do I add it from a CDN? Do I install the npm package? Again, I saw solutions requiring everything in the app.js file.
How to do it the right way?
For Laravel Mix, the correct way to implement this is to run the following.
npm i editor.md jquery
Then add your require() methods in the bootstrap.js file.
resources/js/bootstrap.js
window._ = require('lodash');
try {
window.$ = window.jQuery = require('jquery');
window.editormd = require('editor.md');
} catch (exception) {
console.error(exception);
}
In your template, likely located at /resources/views/layouts/app.blade.php, you will need to add the following at the bottom of the file before the closing </body> tag.
<script src="{{ mix('js/app.js') }}"></script>
This may not be the best way to do it, but you could copy the entire directory with mix.copyDirectory(srcDir, destDir) as seen here

jquery not working well on node-webkit

I am practicing node-webkit as a nodejs beginner.
My main page is a simple html page including a main.js script
I've installed jquery using npm install jquery
index.html
<!-- index.html -->
...
<script src="js/main.js"></script>
</head>
<body>
<div id="demo">Hi! </div>
</body>
</html>
main.js
// main.js
const $ = require('jquery')
$(document).ready(function () {
$('#demo').click(function () {
$(this).text($(this).text() + 'Hi! ')
})
})
If I load jquery in my index.html like <script src="path/to/jquery.js"></script> it works well, but if I require jquery in my main.js it doesn't!
I've already tested:
main.js is properly including and working with native js methods (like document.getElementById('demo').onclick = ...)
Other node modules or libraries such as vue, lodash or natives like fs, url work well. So require function works good.
While I'm requiring jquery as above, inline <script>s doesn't work as well.
Also I realized $(document).ready(...) works! But the real problem is that $('#demo') is undefined! (I checked the console-I'm using SDK version of node-webkit)
I don't know if it's because of node-webkit or something else I'm missing?
found the solution,
I should define jquery like this:
window.$ = window.jQuery = require('jquery')
this is simply because of variable scopes in ECMAS
so if I define it like this, I can use it everywhere

Import monaco editor using require js

I have installed monaco-editor using
npm install monaco-editor
now I want to require in my js file
so I have tried to require using
var monaco = require('monaco-editor');
but it is giving me module not found error.
Is there wrong I am doing?
They just released ESM distribution which is compatible with webpack etc. Check out the docs here.
Also there are many examples for using monaco with webpack, parcel an so on. See all.
Monaco-editor uses a custom AMD style module loader. the loader.js will result in the global require being set to Monaco-editor's loader.
The samples GitHub has many examples of using the editor in different contexts.
Check out how they solve your problem in the Electorn samples index.html. After persisting the Monaco-editor custom loader you would use it like in most of the examples out there. It is an AMD style loader so the syntax differs from node var me = require('monaco') . I am not sure if it is possible to use like node loader but after loading loader.js and persisting the require to some variable such as amdRequire you will use such as:
amdRequire(['vs/editor/editor.main'], function ()
{
// your code using monaco ns here
monaco.editor.create( document.getElementById('elementId'), {} );
})
In my case, I'm trying to load Monaco Editor in nw.js app which had require.js.
Usually Monaco Editor examples recommends using its 'Loader.js'. But if you already have another amd loader (ex: require.js), then you don't need to include & use Monaco's Loader.js. By this Github comment I got to know the Monaco's Loader.js will not do anything if it detects another amd loader.
This official sample might be useful.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<h2>Monaco Editor Sample - Loading with requirejs</h2>
<div id="container" style="width: 800px; height: 600px; border: 1px solid grey"></div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"
integrity="sha256-0SGl1PJNDyJwcV5T+weg2zpEMrh7xvlwO4oXgvZCeZk="
crossorigin="anonymous"
></script>
<script>
require.config({ paths: { vs: '../node_modules/monaco-editor/min/vs' } });
require(['vs/editor/editor.main'], function () {
var editor = monaco.editor.create(document.getElementById('container'), {
value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
language: 'javascript'
});
});
</script>
</body>
</html>

RequireJS, jquery still undefined

I know this has already been discussed, but after searching for a while I can't figure out why my small setup does not load jquery correctly with requireJS.
I'm running a small sample html page from 'file://' and try to load 2 modules with a call to require:
jquery
a custom module I wrote
If my custom module loads correctly (i can use it with its alias in the require call, jquery is always undefined)
I tried to setup paths in require.config, as well as shim (exporting '$' or 'jQuery') but it does not work.
The only way i can get jquery to correctly load, is removing all paths definition and naming the jquery file on my filesystem 'jquery.js'
Here is my config:
main.js:
require.config({
baseUrl: 'scripts',
paths: {
jquery: 'jquery-2.1.3.min' //does not work
//jquery: 'http://code.jquery.com/jquery-2.1.3.min.js' //does not work either
}
});
console.log( "main.js is loaded" ); //this is correctly ouputed to the console
test.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--
... page content ...
-->
<!-- main.js is loaded from data-main -->
<script data-main="scripts/main" src="scripts/require.js"></script>
<script type='text/javascript'>
require(
['jquery','custom'],
function($, Custom){
console.info('$:');
console.info($); //outputs undefined
console.info('Custom:');
console.info(Custom); //outputs my custom object
});
</script>
</body>
</html>
Once again, it works if I remove all paths definition for jquery, and simply name my jquery js file 'jquery.js' but this is sloppy.
Can somebody points me on the right way to go ?
The problem is that you load your RequireJS configuration, which is in main, through data-main. The data-main attribute merely tells RequireJS to load the module listed there but the loading is still asynchronous, so main may load after RequireJS tries to load jQuery. When this happens, RequireJS fails to find jQuery and $ is undefined. (Incidentally, I'd suggest setting enforceDefine to true in your RequireJS configuration so that you get an error message telling you when a module has not loaded. That's a better clue than having an undefined symbol.)
One solution would be to move your configuration outside of main. So you remove it from main and add it to a script element in front of the one loading RequireJS:
<script>
// RequireJS will use the value of `require` as its configuration.
require = {
baseUrl: 'scripts',
paths: {
jquery: 'jquery-2.1.3.min'
},
enforceDefine: true
};
</script>
<script src="scripts/require.js"></script>
Or you can nest require calls to force main to load before any other module:
require(['main'], function () {
require(['jquery','custom'], ...
});

Dependencies in RequireJS with Backbone, Underscore, and jQuery in 2014

I have seen a lot of questions regarding using RequireJS w/ Backbone, Underscore, and jQuery. My question is slightly different; my app works, but I don't know why.
Currently, Underscore, jQuery, and Backbone all export AMD modules, so there is no need for me to shim them and export their variables anymore. Therefore, my main.js looks like the following code snippet.
main.js
require.config({
paths: {
jquery: 'lib/jquery/jquery-1.10.2',
'jquery-ui': 'lib/jquery/jquery-ui-1.10.4.min',
underscore: 'lib/underscore/underscore.min',
backbone: 'lib/backbone/backbone.min',
'backbone.localStorage': 'lib/backbone/backbone.localStorage'
}
});
require(['jquery', 'jquery-ui', 'underscore', 'backbone', 'backbone.localStorage'], function() {
});
require.html
<!DOCTYPE html>
<html>
<head>
<title>My Sample Project</title>
<!-- data-main attribute tells require.js to load
scripts/main.js after require.js loads. -->
</head>
<body>
<h1>My Sample Project</h1>
<div id="test"> </div>
<script type="text/javascript" data-main="js/main" src="js/lib/require/require.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
When I go to require.html, I can go to console and all my variables are there correctly loaded. For example, var x = Backbone.Model.extend({}); var y = new x; works just fine. However, Backbone depends on both Underscore and jQuery. Does RequireJS automatically resolve these dependencies using the modules supplied by these library, or is it only working as a fluke?
You have require right after requirejs config setup
require(['jquery', 'jquery-ui', 'underscore', 'backbone', 'backbone.localStorage'], function() {
});
They loaded in the correct order by a chance, to control that sequence you need to define dependencies of each module in a shim
Require helps a lot with this kind of work.
You can specify dependencies in a easy and correct way usim 'shim' command like this.
//Coffeescript example
paths:
backbone : 'path/backbone'
underscore : 'path/underscore'
jquery: 'path/jquery'
shim:
backbone:
deps:['underscore','jquery']
exports: 'Backbone'
This way you define that when a module called 'Backbone' was called, require will load all the dependencies written inside deps:[].
Now it will never load backbone before underscore.
I have a blog and a post about it, unfortunately it's only in portuguese, but maybe helps.
http://www.rcarvalhojs.com/backbone/2014/06/03/comecando-require-backbone.html

Categories

Resources