why are dev servers required for web based front end bundlers - javascript

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

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

React public folder scripts

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.

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

Including JS files in Derby.js

I am trying to learn Derby.js and I am having a lot of trouble. I know I can include packages such as jQuery through npm and add it to the node_modules folder, but this isn't quite what I want to do. I want to be able to include these files like I do in normal HTML.
So I want to do something like <Head:> <script src="js/jquery.js"></script>. This does not work though because it cannot find the js directory. I expect this has something to do with the way node.js runs an app and that the app itself will not hold the js directory.
Any help would be appreciated!
Derby offers the Script: tag:
<Scripts:>
<script type="text/javascript" src="/components/jquery/jquery.js"></script>
The components directory is because of the usage of bower. Put the components directory into the public directory. According to the express FAQ, the static routes search below the given directory (which is public in derby's example application). Configure bower to put the files under public/components (Choose bower install directory).
The public directory is configured at lib/server/index.js: .use(gzippo.staticGzip(publicPath, {maxAge: ONE_YEAR})), where publicPath is configured above to path.join(root, 'public').
Be aware that the "idea behind the inline script is that it runs immediately, before any of the external scripts are loaded. This should only be used in rare cases where the script should run before the page is displayed in the browser, such as sizing something to the window or autofuocusing an element in browsers that don't support the "autofocus" attribute." Nate Smith in the derby google group.
Inline scripts should be placed in inline.js, located in the same directory as the application's index.js.
If you require jQuery to do something on the loaded page, following code snipped worked at my side (Firefox, Chrome) in inline.js:
window.onload = function() {
alert($(this));
}

Adding external JavaScript library to Eclipse Project?

When adding an external JavaScript library to an Eclipse project should I be adding the .js file (d3.v2.js), or the tarballed master pulled from Github?
Google tells me to Google it. Subsequent Googles remind me of the need to Google it.
Directory tree:
.
|-build
|---classes
|-src
|-WebContent
|---foo.html
|---META-INF
|---WEB-INF
|-----lib
|---d3
|-----d3.v2.js
Relative path from foo.html to d3.v2.js should be: "../d3/d3.v2.js"
But, maybe it's not. I don't know.
Whenever I reference d3.v2.js from foo.html nothing happens. By nothing happens, I mean nothing visually appears in the browser which suggests that d3.js even exists.
To 'add' d3.v2.js to Eclipse I took the following steps:
Foo -> New -> JavaScript Source File -> Advanced -> Link to File in Filesystem -> /home/tyler/workspace/foo/d3/d3.v2.js
Tried 5 different paths. None of them worked (do you have to use relative, absolute?)
src="/home/tyler/workspace/Foo/d3/d3.v2.js"
src="../d3/d3.v2.js"
src="/Foo/d3/d3.v2.js"
src="d3.v2.js"
So, I deleted the reference to d3.v2.js in Eclipse and attempted to add as a library.
Foo -> JavaScript Resources -> Add JavaScript Library -> User Library - Configure User Libraries -> New -> "D3" -> Add .js file -> d3.v2.js (location: /home/tyler/workspace/Snotra/d3
Tried a bunch of paths.
src="d3.v2.js"
src="../d3/d3.v2.js"
src="/Foo/d3/d3.v2.js"
Rinse, repeat.
Any ideas? I know that this is really easy, but I just don't understand the fundamentals of adding JavaScript libraries to Eclipse.
foo.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8" />
<title>Tyler J. Fisher</title>
<link rel="stylesheet" href="master.css" />
<script type="text/javascript" src="../d3/d3.v2.js"></script>
</head>
<body>
<section id="foo_view">
<script type="text/javascript">
document.write("test"); <!--Works-->
var dataset[1,2,3,4,5];
d3.select("body").selectAll("p") <!--Doesn't work-->
.data(dataset)
.enter()
.append("p")
.text("RABBLE");
</script>
</section>
</body>
</html>
document.write("test"); works.
The d3.js code doesn't.
So (maybe):
The relative path must be off (or maybe I have to use absolute paths)
Tomcat6 isn't serving JavaScript properly (due to human error)
Eclipse isn't serving JavaScript properly (due to human error)
What Eclipse deploys to Tomcat is what is inside WebContent. If your JS files are not in WebContent, they won't be part of the deployed web app.
You need to understand that what Eclipse shows you is you development, source folders. What is deployed is not this folder, but a directory structure conforming the Java EE specs:
Everything in WebContent is part of the deployed archive
The Java source files are compiled and stored in the WEB-INF/classes of the deployed archive
The non-Java files under a source directory ar copied to the WEB-INF/classes of the deployed archive
All the other files are not part of the deployed archive.

Categories