Cannot use console.log() in a module - javascript

I'm trying to understand how to use modules in javascript.
But it seems that if I import a module, then I cannot log anything to console.
Here's my code:
index.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="js/scene.js" type="module"></script>
<script src="js/main.js" type="module"></script>
</body>
</html>
scene.js:
class Scene {
constructor() {
console.log("Scene created");
}
}
export default Scene;
main.js:
import { Scene } from './js/scene.js';
var scene = new Scene();
console.log("Hello World");
The Expected Result:
Scene created
Hello World
The Result I Get:
Nothing (No Result)
What is wrong with my code and how can I properly use a module?

I see 3 mistakes
in index.html the first script tag is useless.
import is relative to script file, not html.
Scene.js export a default value not a variable named Scene.
solutions:
import Scene from './scene.js';
or
remove default in Scene.js, and import {Scene} from './scene.js';

In your scenario, I believe that line 1 of main.js is throwing an error. In your index.html file, you're suggesting that you have a folder named js with both javascript modules in it; however, in the main.js file, you're suggesting that scene.js is at path js/js/scene.js.
You probably meant import { Scene } from './scene.js';.
You should open your browser's console to view any errors.
For example, if you are using Google Chrome, becoming familiar with the Chrome Devtools will be invaluable in allowing you to resolve bugs like this one by yourself in the future.
The Chrome Devtools console will allow you to view errors in your website, which will give you an immediate answer on what is wrong. In addition, setting breakpoints will allow you to step-through each line of code and trace the flow of executed lines of code and the value of variables at each point in time.
Learn more here: https://developers.google.com/web/tools/chrome-devtools/javascript

Related

Importing JS function to another file

I'm trying to add an import to one of my JS files (both JS are in the same directory) but it seems to break with the following error:
"SyntaxError: import declarations may only appear at top level of a module"
<--HTML-->
click me
<---main_file.js--->
import { new_func } from "./new_file.js";
function run_my_func(){
...
}
<---new_file.js--->
export { new_func };
function new_func(){
....
}
I tried to read other questions on this topic but couldn't find a proper solution.
I've tried also changing the ahref to script type="module" but it didn't work either.
any suggestions?
EDIT:
So I managed to fix it, and it might not be the best practice but it works for my scenario as I want to use a specific function is several JS files -
in the HTML script that loads the function I want to export (new_file.js) I added type="module".
<script type="module" src="js/new_file.js"></script>
made new_func a global variable by adding it to window:
window.new_func = function() {
...
}
now I used new_func normally in every JS file that was imported after new_file

Imported three.js module OrbitControls "not defined"

Javascript and HTML newbie here:
I'm trying to display a 3D model (.gltf file) in a website with controls (pan, zoom, etc.), using the javascript three.js OrbitControls module. In spite of using <script type="module"> tags in the HTML to load OrbitControls, when I try to load the page, I get Uncaught ReferenceError: OrbitControls is not defined from firefox. I can successfully render the image if I do not include the statement defining the controls, but do include the import tag.
Brief code:
--HTML:
<head>
<!-- Imports for three.js and GLTFLoader.js, both seem to be working -->
<script type="module">
import { OrbitControls } from "https://unpkg.com/three/examples/jsm/controls/OrbitControls.js";
</script>
<script src="script.js" defer="defer"></script>
</head>
--Javascript (from script.js):
"use strict";
function main() {
//Create render and camera objects; both work when not using controls
const controls = new OrbitControls( camera, renderer.domElement );
// create scene, GLTFLoader, run animate function
}
const obj_returned = main();
I've tried a few different styles of the script command:
<script type="module"> import { OrbitControls } from "https://unpkg.com/three/examples/jsm/controls/OrbitControls.js"; </script>
This gives the Uncaught ReferenceError: OrbitControls is not defined error,
<script type="module" src="https://unpkg.com/three/examples/jsm/controls/OrbitControls.js">
produces the same error, and
<script src="https://unpkg.com/three/examples/jsm/controls/OrbitControls.js"></script>
This actually gives the same error plus Uncaught SyntaxError: import declarations may only appear at top level of a module, I think due to the missing type="module" flag.
All local files are in the same directory.
I've looked at several other examples of this sort of thing to see what I'm missing (like here, here, here, the three.js documentation, the OrbitControls source code, and several others).
I'm very new to JS and HTML, so 1) it's likely something very obvious and 2) if it's not trivial / a typo, I would appreciate a little explanation as to why this doesn't work so I can avoid similar mistakes in the future. Thanks!

'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;

Javascript classes in ES6, how to import them within other js-files and in html files?

Obviously, I am a beginner and trying to figure out basic staff, so please bear with me!
I have all these files (index.html, app.js and calc.js) in the same folder and their content is shown below.
I have 2 issues:
1: why in file (app.js), importing class Calc and creating a new instance of it works, whereas in file (calc.js) similar process doesn't work with class Test?
2: how could I use the class "Calc" for example in the *.html file?
Note: I am using chrome (62.0.3202.94 (Official Build) (64-bit)) on mac OS 10.13
// app.js
import { Calc } from './calc.js';
class Test {
static hello() {
console.log("hello from class1");
}
}
let c = new Calc(); // this works!
console.log(c.sum(2, 3) + 1); // 6
export { Test };
and
// calc.js
import { Test } from "./app.js";
class Calc {
sum(a, b) {
return a + b;
}
}
let t = new Test(); // Uncaught ReferenceError: Test is not defined
t.hello();
export { Calc };
Finally the HTML file:
<html>
<head>
<meta charset="utf-8" />
<script src="./app.js" type="module"></script>
<script src="./calc.js" type="module"></script>
</head>
<body>
<h1>ES6</h1>
<script>
let c = new Calc();
// simulate input summation from two textboxes for example
console.log(c.sum(2, 1)); //Uncaught ReferenceError: Calc is not defined
</script>
</body>
</html>
Problem 1:
You have a circular dependency - app.js imports calc.js, but calc.js imports app.js.
Usually the module system will ensure all of a module's dependencies are executed before the module itself, but this is impossible when your dependency tree has cycles - it has to pick one of them to run first. In this case, calc.js is run first, at which point Test isn't yet defined!
There are ways to work around this if you're careful, but cyclic dependencies are pretty much always a sign that you're structuring your code wrong - the best solution is to reorganize it so you no longer have a cycle.
Problem 2:
ES2016 modules don't execute in the global scope. If you want to make something available to the window as a whole, you need to be explicit:
window.Calc = Calc;

Javascript ES6 modules not working

I can't figure this out. I have a small app setup with an index.html that includes a javascript file. On the same directory as that file is another file named myJsModule.js with the following code:
export default class{
doStuff()
{
console.log("calling goStuff() from external Module");
}
}
The main javascript file that is loaded from the html then does the import in this way:
import myJsModule from "myJsModule";
// TESTING MODULES
let myNewModule = new myJsModule();
myNewModule.doStuff();
I have a local web server running using Node, so I'm accesing this index.hmtl through my localhost: http://127.0.0.1:8080.
Im getting the following error: Uncaught SyntaxError: Unexpected identifier (referring to myJsModule on my main js file). I also tried using babel to transpile this into previous javascript. I had the same problem using the "require".
Shouldn't my local server figure this out? Or am I using this wrong?
As of Chrome 61, modules are natively supported. I was able to get your example working with the following HTML and JavaScript.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Native Module</title>
</head>
<body>
<p>Hello, world!</p>
<script type="module">
import MyJsModule from './MyJsModule.js';
let myJsModule = new MyJsModule();
myJsModule.doStuff();
</script>
</body>
</html>
MyJsModule.js:
export default class MyJsModule {
doStuff() {
console.log("calling doStuff() from external Module");
}
}

Categories