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!
I need to get all files from some require stack and this include all requires inside the required too.
Example:
file.js
require("./b");
require("./c");
//require("./d"); // this is a comment, need to prevent that
AST
[{
path: "absolute_dir/b.js",
name: "7saf7fs6asf7" // hash
},
...]
ouput (with the AST i can get all files by his name and put them in one single file, like a bundler)
require("7saf7fs6asf7");
require("sa8d78as8d7f");
I don't know how to do this in a modular logic. PLZ help me :)
Is it possible to add a local html file in the nativescript webview ?
If yes How can I do it using javascript ?
When I add online page it works , I can add www.google.com in the webview it works .But I want to add a local page but I don't find a way to do this .
Yes, it's possible. You need to consider that all NativeScript apps are build by default with Webpack and the default webpack.config.js will take care of certain files (like the ones in a fonts folder or like all images with *.png and *..jpg extensions). The webpack build will bundle all JavaScript files and in the case of the Angular flavor will also cognitively include the Angular related HTML files. However, the default webpack.config.js won't "know" about your custom HTML file.
The solution is to let Webpack know that it should copy the specific HTML file. This should be done via the CopyWebpackPlugin section in webpack.config.js file.
Example (assuming we have a file called test.html in the app directory)
new CopyWebpackPlugin([
{ from: { glob: "test.html" } }, // HERE
{ from: { glob: "fonts/**" } },
{ from: { glob: "**/*.jpg" } },
{ from: { glob: "**/*.png" } },
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
For real-life example see this config where this HTML file is the one we are targeting.
I've recently changed my library code to es6 using webpack, babel, and all of this family.
So my production is single file in the end.. compares to before that I had a lot of files that were being loaded dynamically by demand.
My problem is that I'm using another library that loads some of their class dynamically, and in order to customise them I need to provide URL to my custom objects/classes.
It was not a problem at first, because I had a lot of files, but now my code is bundled into a single file.
Is there a way js/es6/... to give some content/string and create a fake url to it, so the other library will 'load' it ?
for example:
My classes are
file ../myLib/CustomLayer2D.js
Class CustomLayer2D {
...
}
file ../myLib/CustomLayer3D.js
Class CustomLayer3D {
...
}
file ../myLib/CustomLayer.js
This is the use of the other library
Accessor.createSubClass([layer], {
viewModulePaths:{
"2d": "need to provide here a url to 2d layer file",
"3d": "need to provide here a url to 3d layer file"
}
});
file ../myLib/CustomLayer.js
Class CustomLayer2D {
...
}
Class CustomLayer3D {
...
}
Accessor.createSubClass([], {
viewModulePaths:{
"2d": "need to provide here a path to 2d layer",
"3d": "need to provide here a path to 3d layer"
}
});
I'd prefer finding a way and not exclude my custom classes from the bundle (my last resort).
Webpack can bundle all assets in one js file, but you can still use separate js files with Webpack or Webpack-dev-server.
You can use webpack-dev-server's config or just put your ../myLib/CustomLayer3D.js beside the webpack bundle file to dynamically load 2D or 3D.js file in you original way instead of require/import them in CustomLayer.js.
Besides what's your another library? maybe it has some other way to load a class dynamically.
Thanks for #Kaiido comment and a bit of more research I've came to a full solution.
In our webpack.config.js we are adding our files to run through the raw-loader - so instead of bundling the real code it will bundle the file as it is - Text file.
In our code we simply import our file/s and put it in <<The Code>>
URL.createObjectURL(new Blob([<<The Code>>], {type: 'text/plain'}));
It looks like this
webpack.config.js
under rules property
{
test: /myLib\\CustomLayer2D.js|myLib\\CustomLayer3D.js/,
loader: 'raw-loader',
}
file myLib/CustomLayer.js
import layer2DCode from './myLib/CustomLayer2D.js'
import layer3DCode from './myLib/CustomLayer3D.js'
Accessor.createSubClass([], {
viewModulePaths:{
"2d": URL.createObjectURL(new Blob([layer2DCode], {type: 'text/plain'})),
"3d": URL.createObjectURL(new Blob([layer3DCode], {type: 'text/plain'}))
}
});
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);
};