function in my javascript module is not defined - javascript

I'm writing JavaScript for the browser, my script.js has something like
import { foo, bar } from "./lib/sth.js"
function main() { ... }
Then I have this in my browser:
<script type=module src="./script.js"></script>
<body onload="main();"> ... </body>
But it's keep giving me this error:
Uncaught ReferenceError: main is not defined
at onload ((index):7)
Why is my main now defined? It works fine before I use type=module, but with the import statement, I believe it has to be type=module

Thanks for #HereticMonkey and #FelixKling!
window.onload = function() { ... }
does work for my problem. Yet I'm confused why import is designed like this. Suppose I just wanna use some library in my script so I import it, why this makes my script has to be a module as well?

Related

Exportin/importing javascript modules

Nooby question:
I've got file main.js with module let myModule = {}, defined there inside $(document).ready(function(). And I have another file summary.js where I would like to use it. I declare them all in the head of html file:
<script src="js/main.js"></script>
<script src="js/summary.js"></script>
I would like to use myModule module in the summary.js file and extend it. So I would like to be able to define: myModule.summary = {}. For now I receive the error myModule is undefined even though all js files are uploaded correctly (I can see them in debugger in dev console of the browser). I expect I have to export the mdrx module somehow but export default mdrx at the end of main.js does not do the job. How to do it correctly? I read the documentation but it seems like structural problem as I couldn't figure that out. Can that be that the myModule is not loaded yet before loding summary.js? If so how to prevent that?
You can use the type attribute to achieve this:
<script src="js/main.js" type="module"></script>
Then you can import the module in other JavaScript files:
import yourModule from './main.js'
The problem was that the whole myModule was defined inside function() (called within document.ready event). Moving it outside that solved the problem.

When I try type="module" get this Error ( Uncaught ReferenceError: loadFoods is not defined)

When I use type="application/javascript" everything is okay.
<script type="module" src="./assets/scripts/homepage.js></script>
<script>
loadFoods()
</script>
Variables inside modules are scoped to those modules.
They aren't designed to create global variables (although there are hacky ways to achieve that).
The <script> element should be the entry point to the program, not a means to load a dependency. That is what import is for.
Your approach should be something more along the lines of:
<script type="module">
import {loadFoods} from "./assets/scripts/homepage.js";
loadFoods();
</script>
Obviously the homepage module needs to explicitly export the loadFoods function.

Why Stats.min.js can only be imported by `script src=` but not `import`?

I have Javascript codes as below. When the importation is inside <script src="..."></script>, it works. However, if I moved the importation to import ...;, it doesn't work. The error message is: "Uncaught ReferenceError: Stats is not defined".
Why is that? Since I am working on a Jekyll site, I prefer to do the import ...; way to make sure other elements of the site work. Any idea how to do the import ...; way without error?
It works
<div id="stats"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script type="module">
const stats = new Stats()
stats.setMode(0)
document.getElementById('stats').appendChild(stats.domElement)
</script>
It doesn't work
<div id="stats"></div>
<script type="module">
import 'https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js';
const stats = new Stats()
stats.setMode(0)
document.getElementById('stats').appendChild(stats.domElement)
</script>
import allows you to import JavaScript modules which conform to the ES6 module format.
Stats.min.js does not. The code is obfuscated but appears to create a global and support the old CommonJS module format.

Why can't my HTML file find the javascript function from a sourced module?

some_file.js
console.log("!")
function hello(){
console.log("Hello!")
}
index.html
<script src="some_file.js" type="module"></script>
<script>
hello()
</script>
When hosting and looking at index.html, I recieve a ReferenceError telling me that hello is not found. Following the advice to this thread other similar ones, I've placed something like window.hello = hello in my javascript file to no avail. I've also attempted exporting the function (which I think I'd only need to do if I were importing it in another javascript file).
Why am I getting a ReferenceError? The script is certainly being loaded, because I see the ! print out in the console, but the function isn't being found.
Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
You have to export the function, then within a script tag with type module, import the module you want to use.
some_file.js
console.log("!")
export function hello(){
console.log("Hello!")
}
index.html
<script type='module'>
import {hello} from "./some_file.js"
hello()
</script>
Try this:
index.html
<script src="some_file.js" type="module">
hello()
</script>

'import' statement not working in script in rendered HTML

I'm developing a express application and Im trying to do the below thing and I keep getting the same error over and over - "GET http://localhost:3000/javascript/module2 net::ERR_ABORTED 404 (Not Found)"
Could someone please point out to me what mistake I am committing and point me in the right direction? Below is my code -
Module1.js
import theFunc from "./module2";
console.log("In module 1");
theFunc();
Module2.js
export default function theFunc() {
console.log("from module 2");
}
index.html
<html>
<body>
Should show the result in console.
<script type="module" src="./javascript/module1.js"></script>
</body>
</html>
Thanks a ton in advance! :)
The message points out the issue, but it's still pretty easy to miss.
GET http://localhost:3000/javascript/module2 net::ERR_ABORTED 404
is the issue, because instead of
http://localhost:3000/javascript/module2
the URL is actually
http://localhost:3000/javascript/module2.js
with a .js extension.
The issue is that
import theFunc from "./module2";
should be
import theFunc from "./module2.js";
The import and export statements belong to ES6 therfore you need to use a transpiler like Babel.
You second option is to use require which the equivalent in ES5:
First add this script to the head of your html:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
</head>
<body>
Change these lines:
import theFunc from "./module2";
becomes
var theFunc = require("./module2");
& this one too:
export default function theFunc() {
console.log("from module 2");
}
becomes:
function theFunc() {
console.log("from module 2");
}
module.exports = theFunc;

Categories