My goal is to use Bootstrap5 Tooltips with my Tapestry 5.8.1 web application. I try to use requireJS for my JavaScript code as much as possible. So I use the Bootstrap5 JS files in their separated form. That means, I don't use the bundle file but single files like this:
src/main/resources
- META-INF
- modules
- bootstrap5
- alert.js
- alert.js.map
- base-component.js
- base-component.js.map
- ...
- tooltip.js
- tooltip.js.map
In my own JS I activate the tooltips by defining this module:
define(["bootstrap5/tooltip"], function(Tooltip) {
var setuptooltips = function() {
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new Tooltip(tooltipTriggerEl)
})
};
return {
"setuptooltips" : setuptooltips
};
})
and then calling require(...).setuptooltips().
That all works. But.
For each *.js file in my modules/bootstrap5 directory I now get a warning on the JavaScript console about the missing source map files:
Source-Map-Fehler: Error: request failed with status 404
Ressourcen-Adresse: http://localhost:8080/webapp/modules.gz/bootstrap5/tooltip.js
Source-Map-Adresse: tooltip.js.map
And I don't know how to resolve this. Tapestry stores all the modules that are actually used in this modules.gz path. I have to knowledge of the inner workings of this. In the debugger I can browser this path and only the files that have been loaded via require() calls are listed their. Obviously, the source map files are missing. Is there a way to either resolve the issue or at least remove the warnings without the need to edit all the Bootstrap5 JS files? Since it is those JS files that refer to the source map files.
Thanks!
Related
I use the FayeJS and the latest version has been modified to use RequireJS, so there is no longer a single file to link into the browser. Instead the structure is as follows:
/adapters
/engines
/mixins
/protocol
/transport
/util
faye_browser.js
I am using the following nodejs build script to try and end up with all the above minified into a single file:
var fs = require('fs-extra'),
requirejs = require('requirejs');
var config = {
baseUrl: 'htdocs/js/dev/faye/'
,name: 'faye_browser'
, out: 'htdocs/js/dev/faye/dist/faye.min.js'
, paths: {
dist: "empty:"
}
,findNestedDependencies: true
};
requirejs.optimize(config, function (buildResponse) {
//buildResponse is just a text output of the modules
//included. Load the built file for the contents.
//Use config.out to get the optimized file contents.
var contents = fs.readFileSync(config.out, 'utf8');
}, function (err) {
//optimization err callback
console.log(err);
});
The content of faye_browser.js is:
'use strict';
var constants = require('./util/constants'),
Logging = require('./mixins/logging');
var Faye = {
VERSION: constants.VERSION,
Client: require('./protocol/client'),
Scheduler: require('./protocol/scheduler')
};
Logging.wrapper = Faye;
module.exports = Faye;
As I under stand it the optimizer should pull in the required files, and then if those files have required files, it should pull in those etc..., and and output a single minified faye.min.js that contains the whole lot, refactored so no additional serverside calls are necessary.
What happens is faye.min.js gets created, but it only contains the content of faye_browser.js, none of the other required files are included.
I have searched all over the web, and looked at a heap of different examples and none of them work for me.
What am I doing wrong here?
For anyone else trying to do this, I mist that on the download page it says:
The Node.js version is available through npm. This package contains a
copy of the browser client, which is served up by the Faye server when
running.
So to get it you have to pull down the code via NPM and then go into the NPM install dir and it is in the "client" dir...
Im creating my first site in Drupal (converting an existing site over to the Drupal 8 CMS).
Ive loaded the CSS and Script libraries. The CSS is working but the Script files are not. Im not sure if its the script files not loading or jQuery not loading - or both.
Am I doing something wrong?
Here is the code calling the libraries in the .info file:
libraries:
- saq7704/global-styles
- saq7704/global-scripts
and here is the code in the libraries file:
global-styles:
version: 1.x
css:
theme:
css/styles.css: {}
global-scripts:
version: 1.x
js:
js/scripts.js: {}
js/responsiveTabs.js: {}
dependencies:
- core/jquery
I'm wondering that the CSS is loading. As you have to attach your libraries to some render array explicitly (element, node, page etc.). Declaring them in your module's info file shouldn't do anything at all.
Have a look at the docs on Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module.
To have your libraries loaded on every page you have to use hook_page_attachments:
<?php
/**
* Implements hook_page_attachments().
*/
function MYMODULE_page_attachments(array &$attachments) {
$attachments['#attached']['library'][] = 'saq7704/global-styles';
$attachments['#attached']['library'][] = 'saq7704/global-scripts';
// Also have a look at this gem.
// If you've written your JS file the right way you now could do
// <code>console.log(settings.MYMODULE.foo);</code> in your JS
// and guess what it will print ;)
$attachments['#attached']['drupalSettings']['MYMODULE']['foo'] = 'bar';
}
Read on how to write Drupal JS files the right way:
JavaScript API overview (watch out for Drupal.behaviors, context and settings). Then your *.libraries.yml should better look like:
global-scripts:
version: 1.x
js:
js/scripts.js: {}
js/responsiveTabs.js: {}
dependencies:
- core/jquery
- core/jquery.once
- core/drupalSettings
It is the first time I use RequireJS and I don't know why it doesn't work...
I have a file example.js inside Folder A.
In the same folder I have 2 other folders that are libraries.
geokdbush
kdbush
In my file I add this code (hoping to add libraries):
require.config({
paths: {
kdbush: 'kdbush',
geokdbush: 'geokdbush'
}
});
And inside function where I should to use libraries I add this:
require(['kdbush', 'geokdbush'], function(kdbush,geokdbush) {
//code
});
But there are two errors: Error: Script error for "kdbush" and Error: Script error for "geokdbush".
I don't know where the problem is in my code. These libraries are used to create K-D tree:
Reverse geocoding with big array is fastest way? - javascript and performance
I have to setup a, most of the time, offline installation of Node-RED and need to use the "Chart.js" Library in a template node. Currently my working approach is to copy the Chart.js dictory to node-red-dashboard/dist/js and import it with <script src= "js/chart.js/dist/Chart.min.js"></script>. But when I want to update the dashboard I need to copy everything again. So it would be nice to have a permanent Solution for this.
I tryed two other approaches until now. For both I installed Chart.js to the .node-red dictory.
First I tryed it like this:
var canvas = document.getElementById('myChart').getContext('2d');
var ChartJs = require('Chart.js');
var chart = new ChartJs(canvas, {... }
in a script tag (... stands for the working chart code that is not edited), but it didn't work aswell as to put
functionGlobalContext: {chartjs:require('Chart.js')} into settings.js and change require('Chart.js') to global.get('chartjs')
Does anyone here has an Idea to solve this properly? Unfortunately the node throws no Error to the console so I don't get an idea whats wrong here.
Thanks in advance for every hint or solution,
manni
When I want to use any 3rd party charting library in my node-red dashboard, I put 2 ui_template nodes into my flow:
under "Template Type" select the "Added to site <head> section" and add the link to the library's url:
<script src="url/to/library.js"></script>
(which in your offline case would be a local url)
use the library's exported objects directly within the template, without using require, such as:
<div id="myChart"></div>
<script>
var canvas = document.getElementById('myChart').getContext('2d');
var chart = new ChartJs(canvas, { ... }
</script>
The trick is to have your local node-red instance serve the ChartJS library through a local url. For that, first add this require path line to the settings.js file, before the exports section:
// The `https` setting requires the `fs` module. Uncomment the following
// to make it available:
var fs = require("fs");
var path = require ("path");
then, uncomment the httpStatic section below that, within the exports:
// When httpAdminRoot is used to move the UI to a different root path, the
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.
httpStatic: path.join(__dirname, 'public'),
(you can use any directory name, in place of public) The __dirname references the node-red server's working directory, usually .node-red under your home directory.
Create this new public directory, copy the ChartJS files under it, and restart node-red. At startup, you should see a line in the console log showing the path to your new static file location:
5 Feb 12:12:23 - [info] Settings file : C:\NODE\node_red_ui\settings.js
5 Feb 12:12:23 - [info] HTTP Static : C:\NODE\node_red_ui\public
5 Feb 12:12:23 - [info] User directory : C:\NODE\node_red_ui
Now you can serve the local file public\scripts\abc.js using the local url
http://localhost:1880/scripts/abc.js
This way, npm updates to the dashboard code will not overwrite your static files.
I'm using requireJS to load scripts. It has this detail in the docs:
The path that is used for a module name should not include the .js
extension, since the path mapping could be for a directory.
In my app, I map all of my script files in a config path, because they're dynamically generated at runtime (my scripts start life as things like order.js but become things like order.min.b25a571965d02d9c54871b7636ca1c5e.js (this is a hash of the file contents, for cachebusting purposes).
In some cases, require will add a second .js extension to the end of these paths. Although I generate the dynamic paths on the server side and then populate the config path, I have to then write some extra javascript code to remove the .js extension from the problematic files.
Reading the requireJS docs, I really don't understand why you'd ever want the path mapping to be used for a directory. Does this mean it's possible to somehow load an entire directory's worth of files in one call? I don't get it.
Does anybody know if it's possible to just force require to stop adding .js to file paths so I don't have to hack around it?
thanks.
UPDATE: added some code samples as requested.
This is inside my HTML file (it's a Scala project so we can't write these variables directly into a .js file):
foo.js.modules = {
order : '#Static("javascripts/order.min.js")',
reqwest : 'http://5.foo.appspot.com/js/libs/reqwest',
bean : 'http://4.foo.appspot.com/js/libs/bean.min',
detect : 'order!http://4.foo.appspot.com/js/detect/detect.js',
images : 'order!http://4.foo.appspot.com/js/detect/images.js',
basicTemplate : '#Static("javascripts/libs/basicTemplate.min.js")',
trailExpander : '#Static("javascripts/libs/trailExpander.min.js")',
fetchDiscussion : '#Static("javascripts/libs/fetchDiscussion.min.js")'
mostPopular : '#Static("javascripts/libs/mostPopular.min.js")'
};
Then inside my main.js:
requirejs.config({
paths: foo.js.modules
});
require([foo.js.modules.detect, foo.js.modules.images, "bean"],
function(detect, images, bean) {
// do stuff
});
In the example above, I have to use the string "bean" (which refers to the require path) rather than my direct object (like the others use foo.js.modules.bar) otherwise I get the extra .js appended.
Hope this makes sense.
If you don't feel like adding a dependency on noext, you can also just append a dummy query string to the path to prevent the .js extension from being appended, as in:
require.config({
paths: {
'signalr-hubs': '/signalr/hubs?noext'
}
});
This is what the noext plugin does.
requirejs' noext plugin:
Load scripts without appending ".js" extension, useful for dynamic scripts...
Documentation
check the examples folder. All the info you probably need will be inside comments or on the example code itself.
Basic usage
Put the plugins inside the baseUrl folder (usually same folder as the main.js file) or create an alias to the plugin location:
require.config({
paths : {
//create alias to plugins (not needed if plugins are on the baseUrl)
async: 'lib/require/async',
font: 'lib/require/font',
goog: 'lib/require/goog',
image: 'lib/require/image',
json: 'lib/require/json',
noext: 'lib/require/noext',
mdown: 'lib/require/mdown',
propertyParser : 'lib/require/propertyParser',
markdownConverter : 'lib/Markdown.Converter'
}
});
//use plugins as if they were at baseUrl
define([
'image!awsum.jpg',
'json!data/foo.json',
'noext!js/bar.php',
'mdown!data/lorem_ipsum.md',
'async!http://maps.google.com/maps/api/js?sensor=false',
'goog!visualization,1,packages:[corechart,geochart]',
'goog!search,1',
'font!google,families:[Tangerine,Cantarell]'
], function(awsum, foo, bar, loremIpsum){
//all dependencies are loaded (including gmaps and other google apis)
}
);
I am using requirejs server side with node.js. The noext plugin does not work for me. I suspect this is because it tries to add ?noext to a url and we have filenames instead of urls serverside.
I need to name my files .njs or .model to separate them from static .js files. Hopefully the author will update requirejs to not force automatic .js file extension conventions on the users.
Meanwhile here is a quick patch to disable this behavior.
To apply this patch (against version 2.1.15 of node_modules/requirejs/bin/r.js) :
Save in a file called disableAutoExt.diff or whatever and open a terminal
cd path/to/node_modules/
patch -p1 < path/to/disableAutoExt.diff
add disableAutoExt: true, to your requirejs.config: requirejs.config({disableAutoExt: true,});
Now we can do require(["test/index.njs", ...] ... and get back to work.
Save this patch in disableAutoExt.diff :
--- mod/node_modules/requirejs/bin/r.js 2014-09-07 20:54:07.000000000 -0400
+++ node_modules/requirejs/bin/r.js 2014-12-11 09:33:21.000000000 -0500
## -1884,6 +1884,10 ##
//Delegates to req.load. Broken out as a separate function to
//allow overriding in the optimizer.
load: function (id, url) {
+ if (config.disableAutoExt && url.match(/\..*\.js$/)) {
+ url = url.replace(/\.js$/, '');
+ }
+
req.load(context, id, url);
},
The patch simply adds the following around line 1887 to node_modules/requirejs/bin/r.js:
if (config.disableAutoExt && url.match(/\..*\.js$/)) {
url = url.replace(/\.js$/, '');
}
UPDATE: Improved patch by moving url change deeper in the code so it no longer causes a hang after calling undef on a module. Needed undef because:
To disable caching of modules when developing with node.js add this to your main app file:
requirejs.onResourceLoad = function(context, map)
{
requirejs.undef(map.name);
};