React public folder scripts - javascript

Calling on the react experts haha.
I am trying to import/include some external javascript files into my React project, these js files cannot be changed or edit as per instructions from my company, as this is a base for many application that uses them.
For reasons i wont be putting the real filenames and folders.
There is a folder in my public folder called "testModules", so path is public/testModules/
all the files / 3 files that i need to include is in there.
What i have tried so far.
In my index.html file at the bottom i have tried the following
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test1.js"></script>
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test2.js"></script>
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test3.js"></script>
and
<script type="text/JavaScript" src="./testModules/test1.js"></script>
<script type="text/JavaScript" src="./testModules/test2.js"></script>
<script type="text/JavaScript" src="./testModules/test3.js"></script>
and
<script type="application/javascript" src="./testModules/test1.js"></script>
<script type="application/javascript" src="./testModules/test2.js"></script>
<script type="application/javascript" src="./testModules/test3.js"></script>
and
Then i have also tried using the ScriptTag plugin "react-script-tag"
with the same examples as above, but instead of %PUBLIC_URL% i used process.env.PUBLIC_URL
When i try any of the above it works on my local development env. For example running npm run start and opening on localhost
But as soon as i move to application to a live server i get the following err
Refused to execute script from 'https://test.com/testModules/test.js'
because its MIME type ('text/html') is not executable, and strict MIME
type checking is enabled.
For all the files i added.
Now i open up my dev console and i can see the scripts are appended/included in the body at the bottom.
What is going on and how can i fix it.
Thanks You

If you wouldn't like to make any improvements to your deployment architecture, then you should pretty much talk to "your backend devs" so that they configure the web server so that this particular route would emit a different MIME type while serving this particular static file.
Alternatively, if possible, you could use Webpack to statically link the third-party code base to your React project so that they are distributed together. This way, if you use any implementation of Javascript modules, you will eliminate this crutch of your library being visible at the scope of the HTML host and this might bring improvement to your codebase.

Related

Spring Boot Web with Thymeleaf: HTML template can't find the given JS file

I just set up a very basic Spring Boot Web Application with Thymeleaf, but I can't access my external JS file from the corresponding HTML file of my template and can't figure out why.
My resource folder structure is as follows:
static/
index.html
css/
graph.css
js/
createGraph.js
templates/
visualizeGraph.html
Within my visualizeGraph.html I try to call the createGraph.js using following snippet within the <body> element:
<script th:src="#{/js/createGraph.js}" type="text/javascript" >
</script>
In the <head> element of visualizeGraph.html, I added my stylesheet using following snippet:
<link rel="stylesheet" type="text/css" media="all"
href="/css/graph.css" th:href="#{/css/graph.css}" />
My Spring Boot Web Container runs on Port :8082, so I access my webapplication from localhost:8082 and access the visualizeGraph template from localhost:8082/visualizeGraph
When I check the Developer Console (F12), it throws a 404 for the createGraph.js file, but not for the graph.css file -> it can find the css successfully.
I can even access the css through localhost:8082/css/graph.css but CAN'T access the js-file using localhost:8082/js/createGraph.js (throws a 404 - as expected)
I can't figure, what's the cause for this phenomenon as my application.properties also has no additional parameters for modifying the resource source folder etc.
Okay, this was VERY weird. I found the solution, but I am not sure, whether it's IntelliJ, which was responsible for this problem or something else.
What I did was to edit my <script> element in my HTML file to the following:
<script src="/js/createGraph.js" type="text/javascript" >
</script>
and my intention was solely to try out, whether it would change anything. Somehow, IntelliJ told me, that it was not able to find the path (neither the js folder, nor the createGraph.js file within it) so what it suggested was to create the folder and the file (so I did, using ALT+Enter). What I did afterwards is to just copy the content of my old createGraph.js to the new file and to delete the (very strangely the same named) old folder and file and voila, everything works as expected... Very weird.
You can call your JS files present in resources/static folder like below:
<script type="text/javascript" src="js/script.js"></script>
No need to give the forward slash before the js folder.
below I am attaching screenshot for my code:
Here, I was having images folder inside the static folder so we can directly call that folder.
If you have any further doubts please feel free to visit my github amisham96

why are dev servers required for web based front end bundlers

I never really thought about it until I switched from webpack to brunch where I saw the following lines in index.html:
<script type="text/javascript">
require('main');
</script>
When you try to simply open up a local html page (even after everything's been built in webpack), it produces errors (SCRIPT5009: SCRIPT5009: 'require' is not defined) and doesn't render correctly, but when you open the page through a dev server it renders correctly.
Why are dev servers required for bundlers? What are the dev servers doing behind the scenes to allow the browser to properly render pages with bundles? Isn't the rendering capability built into the browser itself?
Originally I thought it was putting up a node server to help translate commands such as require(), but the above shows that the line was passed through to the browser. Why does the browser choke on that command when you just open the html file versus when it's delivered via a server?
On a side note everything works fine when the page is delivered via apache as well. If it is some sort of node translation, then how does apache not choke on it?
edit:
The files that show delivered are:
logo.png (just a vue logo)
app.js (the bundled javascript file)
the html file, which looks like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-webpack-brunch</title>
</head>
<body>
<div id="app"></div>
<script src="/app.js"></script>
<script type="text/javascript">
require('main');
</script>
</body>
</html>
Everything is delivered exactly like that, and that's the extent of the project. If the javascript bundle were including requirejs then it should also work if you just open the file locally as well
Edit 2:
typing require in the console produces the following:
(t,r){null==r&&(r="/");var i=l(t);if(o.call(n,i))return n[i].exports;if(o.call(e,i))return u(i,e[i]);throw new Error("Cannot find module '"+t+"' from '"+r+"'")}:
<script src="/app.js"></script>
You are loading /app.js which will define your require function.
The URL starts with a /.
If you load it from a webserver, the / refers to the root of the site.
If you load it from your local file system, then the / refers to the root of your filesystem (or disk if you are Windows). This will be the wrong place because webpack will not generate it there (you would not want c:\app.js created for every application you built with webpack).
The require keyword is giving errors because it's a made up way to require external files. If you used import, the standard native implementation, it would work out of the box on newer browsers. Bundlers aren't required.
Require came from https://requirejs.org/
They're looking for that word require and, essentially, injecting code at that source path into a built file. It'd be like if I made a injectFile keyword for my InjectFileJS project.
<script type="text/javascript">
injectFile('main');
</script>
That would produce the same error, injectFile is undefined. You would need to run my made up file loader on your web server to parse and transpile the files for that function to exist.
However, if you use import you can get away with not having a bundler as a requirement on new browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

How to include external libraries via CDN asynchronously in Webpack

Prior to posting this question, I consulted the following threads on this topic:
How to include external CDN link into webpack project
Webpack and external libraries
how to use webpack to load CDN or external vendor javascript lib in js file, not in html file
How to include jQuery CDN in Webpack?
Webpack externals documentation
Based on all the above, it appears that in order to load a third-party library via a CDN, the standard method would be to use webpack externals, which produces the following script tag in the index.html file (per Webpack docs).
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous">
</script>
While this solution works if you have one or two libraries, how are you supposed to load 10 libraries (for arguments sake) via CDNs asynchronously (to maximise pageload performance) using externals in Webpack?
My current solution to this problem is to manually include the following script tags in my index.html file with relevant "async" and "defer" tags; however, I need to update the index.html file in my dist folder every time I include a new library, which leads me to believe I'm doing this completely wrong. Below is what my index.html file currently looks like, which is also replicated in the dist folder.
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<link rel="stylesheet" href="https://afeld.github.io/emoji-css/emoji.css">
</head>
<body>
<div id="app"></div>
</body>
<script src="https://cdn.jsdelivr.net/npm/moment#2.20.1/moment.min.js" async defer></script>
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.4/lodash.min.js" async defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.0/math.min.js" async defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" async defer></script>
<script src="https://widget.cloudinary.com/global/all.js" async defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js" async defer></script>
<script src="/dist/build.js" async defer></script>
</html>
While I'm sure there's a "hack-ey" way of achieving my goal (which I'm open to seeing), my question is whether I can accomplish the above through an officially supported method (like through externals). If not, how does most of the web development world use libraries given that CDNs are known to almost always improve pageload performance?
EDIT: For some context, I'm using Webpack because I'm using vue-loader to build my VueJS SPA (as a learning project).
EDIT 2: This question was asked using incorrect assumptions about Webpack and how web development works. The conclusion is that you shouldn't be using CDNs as liberally as I have if you're using Webpack. Refer to the comment section for clarification.

Run Web app with Bokeh plots in an offline mode? Where to dl Required Bokeh files

I have a web application with python controllers, where output plots are plotted by Bokeh. In my master template.html file I load bokeh-0.9.2.min.css and bokeh-0.9.2.min.js as shown below.
My question is "If I run my web app as a browser app in offline mode, Is it possible to download these two files into my static/jss folder and run it offline?"
<link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.2.min.css" type="text/css" />
<script type="text/javascript" src="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.2.min.js"></script>
For anyone who stumbles upon this question, there is now a convenient way to load the Bokeh JS and CSS files inline instead of via CDN. This can be done by setting the mode argument to inline in the io.output_file function:
output_file('plot.html', title='Bokeh Plot', autosave=False, mode='inline', root_dir=None)
Yes - you should be able to download the js and css files from the cdn (using wget or similar) into static/js and static/css files. Then you just have to change the href/src paths to your local directories to load the statics.
I examined the head on an html file produced by a bokeh python script bokeh.plotting.output_file and noticed a reference to lib/site-packages/bokeh/server/static/js/bokeh.min.js

Not able to include js files in html file on standalone java application

Hi I am working on standalone java application running on some port number.
I am trying create UI with HTML where it includes some external js files.
I have included those files in header tag as below.
<script type="text/javascript" charset="utf-8" src="js/jquery.json-2.2.min.js"></script>
<script type="text/javascript" charset="utf-8">
But it always gives the error message as "Filed to load resource:the server responded with status code of 404.
Any ideas?
Seems like a pathing issue to me.
What is the relative location of your "js" directory from the calling page in your file system?

Categories