Adding external javascript script to React - javascript

I'd like to include & run some js file in the React using Helmet component. Here is the simple code:
index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Helmet } from "react-helmet";
import "./styles.css";
function App() {
console.log("op");
return (
<div className="App">
<Helmet>
<script src="hello.js" type="text/jsx" />
</Helmet>
<h1>Hellok CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
and ultra simple js script to include & run:
hello.js:
console.log("opl882...")
document.body.style.backgroundColor = "red";
But the script seems NOT to work! - i have no console output and/or background color changed. What's odd when I use the js code as an inline code like:
<Helmet>
<script type="text/javascript">
console.log("opl882..."); document.body.style.backgroundColor = "red"
</script>
</Helmet>
it works!
Why doesn't the external js file work?

I usually do not implement .js files in react using a script tag. Instead you should import it at the top like this (assuming './hello.js' is the route to the file):
import './hello.js'
That file must also be located inside the src folder.

I think the core issue you're probably seeing here is that hello.js is not accessible to the browser at the given URL. The src attribute in the <script> tag gives the URL for the browser to load the script from. Verify that you can directly access the script at the URL: it should just load as text in your browser to read if it's accessible.
The specifics of making a file directly accessible vary depending on your setup, but for a standard Create-React-App project (and a lot of others) there is a folder called public and you can put files you need to directly access by URL in there. To verify it's working, add your file there, then try to access it from the root of your app. If your app is running at localhost:3000 for instance, you can verify the file is accessible by navigating your browser to localhost:3000/hello.js. The file contents should appear in your browser as plain text. (Also, minor nitpick, I would use /hello.js as the src location, that feels like a less ambiguous URL to me.)
Once that's working, check out this StackOverflow over here to see about loading and running a vanilla JS file within React: Adding script tag to React/JSX .
In your case, you're already using Helmet, so I think the code you already posted is mostly good to work, but the answers in that link should help troubleshoot. Although I think you want to change the type to text/javascript or just omit it entirely.
Finally, the reason the in-line JS works but not the referenced file is why I think it's about your browser not being able to find/access hello.js. The in-line JS just runs as it is because the JS is baked in. But to run it from a src, it has to find the source first, so if it can't find it at the URL you've given, it won't run. As for the other answer by Bilal here, that would work too, but it's depending on some sort of webpack magic or something to see it's a Javascript file, then pack it in such a way so that it runs. Nothing wrong with that necessarily, but you're basically offloading the creation of the <script> tag to whatever process interprets the import. (Also, note that if you're able to do import './hello.js', then your hello.js file must live in your overall src folder, so it's not publicly accessible, which means the script src is invisible from the browser's POV.)

useEffect(()=>{require('./paywell.js')},[])

Related

Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”)

Apologies if this is a repetitive question however I have looked all over and found no suitable solution for my particular issue.
I am attempting to build a simple JavaScript game but am having issues with importing images.
For reference, here is my relevant code:
index.html
<canvas id="gameScreen" width="1420" height="965"></canvas>
<script src="src/index.js" type="module"></script>
And from my index.js file:
import platform from "../assets/platform.png";
I am receiving the following error when trying to import this image:
Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”).
I have tried changing the 'type' specified in the script tag, to no avail.
Also, I should note I am using the Live Server extension.
Any help is much appreciated.
In JavaScript, the ES6 import statement can't be used to import anything except JavaScript modules.
Tools like Webpack — which pre-process import statements to convert JS programs using ES6 modules into a format that browsers which doesn't support modules can use — can do things with non-JS resources.
They aren't executing the JavaScript, so the rules for them are different.
At the simple end of the scale, this involves copying the non-JS file to the build directory and replacing the import with a variable declaration and assigning a URL (in a string) to that variable.
Since you aren't using a bundler, you need to do that yourself.
Replace:
import platform from "../assets/platform.png";
with something like
const platform = "/path/to/platform.png";

Ignore cache import modules es6

I'm working with the webcomponents standard, but in reality, the same thing happens with any import of es6 modules.
When I update a web component and upload it to the server, since these are imported with es6 modules, users do not see the update until they force to refresh the browser's cache.
This is a problem when it is a hotfix or when the update requires a component that the user already has in cache, but this component has had some update in the code necessary for the operation of the new component.
I've been looking, but haven't found anything that really works for me to force the browser to request the javascript modules from the server. Not even by uncaching the .htaccess, the browser keeps caching a copy and serving it from the cache itself.
I used to use the trick of putting the version in the src attribute of the script tag.
<script src="https://example.com/src/js/myscriptfile.js?v=1.1.2"></script>
But when importing with an import statement inside the javascript file this is no longer an option.
Any ideas that work?
I used the following import statement for a file that is transpiled by Babel & minified by Webpack, and it is also served directly as a <script type="module"....
This technique causes Chrome v102 to download the file each time the "v" value changes (i.e., cache the imported file until I change tye hard-coded URL query parameter that I used in the import statement), which I change when I update the file so that the new file will be downloaded by the browser.
import { myFunction } from './myFile.js?v=2022-06-17T12.48';
NOTE: There is a chain reaction, so you'll need to do the same thing for any files that are imported from within myFile.js, assuming you want to control the caching of those files also.

How to disable special handling of SVG imports in codesandbox?

I've created a simple app with create-react-app. This configures webpack loaders for svg files to copy the files and put a public file into the constant. So the following code
import mysvg from "./img/my.svg";
console.log(mysvg)
prints /static/media/my.svg. That's fine.
But when editing/running the same project in codesandbox it tries to read the svg file (e.g. printing errors about ReactComponent if it's not a proper svg), and makes the handling different. Obviously, I could use the "public" folder instead, but I'd like to use the hash feature of production builds etc.
So my question is, how can I allow to use the same mechanism to get a resolving url path (e.g. valid for img src) in codesandbox and use the default create-react-app configuration?
Answer from the codesandbox team: it is a known issue tracked on their github repository.
I did some digging, and I think this is definitely a bug with codesandbox.
When we use a .png image, the string path looks like this:
path: https://uploads.codesandbox.io/uploads/user/ff71cfab-643a-41c7-8358-d13e8ce686c9/U6zD-unsplash1.png
But when we use an SVG, things fail.
Some similar issues opened on their github repo: #1664, #3825.
The maintainer said that svg-react-loader is included in CRA v2 template, and you can import them as ReactComponent, I assume this is what you were talking about initially. I think this is what caused svg files to be treated differently by codesandbox.
For now, I guess you can do this hacky workaround:
import mysvg from "!raw-loader!./img/my.svg.txt";
// inside render
<span dangerouslySetInnerHTML={{ __html: mysvg }} />
sandbox here
You would need to add raw-loader as dependency and rename the file to .txt extension so that it doesn't get handled like an .svg.
Long term, I think the best we could do is to participate in #3825 and hope that this can get fixed by codesandbox.
If you're want to use svg images,only importing them as React Components, like this,import {ReactComponent as MySvg} from './img/my.svg' usually always works. There are other ways as well but I think this one is simplest.
Check out my solution -
myVersionOfCodesandbox

Vue.js - What happens to content inside script tag if you use src="script.js" in Vue files?

I'm using Intellij IDEA with Vue plugin to create an SPA. As most of my views are getting big, I decided to separate them in template/script/css files. But IDEA is having some problems in finding the components I'm declaring in the .js file, so I tried to do the following:
<script src="./component-name.js">
import ComponentName from './ComponentName';
export default {
components: {
ComponentName
}
}
</script>
With that, IDEA recognizes the components and offers autocomplete/go-to definitions and all the stuff it should. But I'm wondering if there are any downsides to that? I know having content inside a script tag when using src isn't recommended in pure HTML5, but is that a problem here? I'm guessing it's ignored by webpack as I haven't had any problem with my application.

Import from Adjacent Script Tag with ES6 Modules

With ES6 modules, is there a current method, or one in the pipeline, to import a module from a <script> tag already on the page? For example, if I have 2 <script> tags,
<script id="a">
export const a = 'a';
</script>
<script id="b">
import a from ?;
console.log(a);
</script>
what do I put into the import statement in the second <script> tag, in place of the question mark?
The id attribute is for identification purposes, as, obviously, there needs to be some way to identify the <script> tag you need. It could be done with classes or any other way, but IDs must be unique (though many browsers just use the last tag with an id), so I thought it was a good way to ensure you have the correct tag. It could also be done by getting the <script> tag by position in the document: for example, here you are getting the second script tag, so perhaps you could do something like
import a from window.scripts[1];
One more thing: if this could work across HTML imports, that would be great, too. My original purpose was to re-use React components across different pages of a site, where they may not be able to be imported with relative paths, and, at least with Webpack, absolute paths are not always relative to the server's root: sometimes they are relative to the computer's root, or at least the webserver's root.
How do I import values directly from another <script> tag on the page?
I know it's an old question and if my reputation was higher I probably would have added this as a comment...
The unsatisfactory way I hade to use in a similar case was to place every variable from the first module on the window
[I read something about using eval() but haven't tried to test it. as I detest the eval function.]
#T.J. Crowder: I have the following structure
/app
/modules
main.js
other.js
feature.js
/customer-page1
index.html
/data
data.js
/page2
index.html
/data
data.js
/Page3
index.html
/data
data.js
It's a kind of complicated quiz-app. We add new features and the customers update there index.html.
Questions are in the HTML an the data/data.js contain complex structured data.
We want/need modules as we load the feature.js dynamically.
The data.js sometimes needs to have evaluation function in addition to the raw data, which can differ from client to client, so a pure JSON isn't cutting it, and we still would have the path-problem, as main.js has to work on all pages
and is referenced as
<script type='module' src="/app/modules/main.js"></script>
while data is easily referenced as
<script type='module' src="data/data.js"></script>
from index.html
As we work with pure (no framework) Typescript we also need the modules is data for type-checking to see definitions in /app...
I would be very happy to find a more elegant solution though.

Categories

Resources