Javascript ES6 modules not working - javascript

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");
}
}

Related

deploying front end website with ES6 modules

I just deployed a landing page on GitHub and I'm using html, CSS and JS with modules:
index.html uses script of type module:
index.html
<html lang="en">
<head>
...
<script type="module" src="main.js"></script>
</head>
<body>
...
</body>
</html>
main.js imports changeLanguage function and uses it:
main.js
import { changeLanguage } from "./modules/changeLanguage":
...
changeDate();
changeTheme();
changeLanguage();
in changeLanguage.js exporting the necessary function:
modules/changeLanguage.js
export const changeLanguage = ()=>{
...
}
however, when deployed it gaves me an error Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'interest-cohort'.
and Failed to load resource: the server responded with a status of 404 () /alarabiya/modules/changeLanguage:1
how to fix it ?
the issue was that i have to add .js extension to the end of the file like this:
import { changeLanguage } from "./modules/changeLanguage.js";

Problem using import/export in Javascript "Uncaught SyntaxError: Cannot use import statement outside a module"

I'm learning Javascript and I have a problem using import/export to modularize my code. I tried to learn this by reading this and this in MDN Web Docs (Mozilla), but failed. I know this has already been asked here, but I couldn't fix the problem.
The error I get in the web browser terminal is: Uncaught SyntaxError: Cannot use import statement outside a module
I'll insert a small example of how I tried to use import/export:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<h1 class="title">Example</h1>
<button class="title-button">Change title</button>
<!--
I tried adding this line but nothing has changed:
<script type="module" src="module.js"></script>
--->
<script src='main.js'></script>
</body>
</html>
module.js:
const changeTitle = newTitle => {
const title = document.querySelector(".title");
title.innerHTML = newTitle;
}
export { changeTitle };
main.js:
import { changeTitle } from "./module";
const titleButton = document.querySelector(".title-button");
titleButton.addEventListener("click", () => {
let newTitle = prompt("Enter new title:");
changeTitle(newTitle);
});
Note: all three files are in the same folder.
Thank you for your time. Sorry if I made a mistake in this post.
The type="module" attribute must be added in the script that uses the import statement (in this case, main.js). My mistake was trying to add type="module" in module.js instead of main.js

Problem making nested .js module files work

I seem to be going in circles trying to get a simple nested .js files to work. I start with these 2 files and it works as expected:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="module" src="./scripts/file1.js"></script>
<title>Hello World Page</title>
</head>
<body >
<div>
Some prompt: <input id="Xxx" onkeyup="file1Go('index.html calling file1Go()')"/><br />
</div>
</body>
</html>
file1.js
function file1Go(msg) {
alert('In file1.js - ' + msg);
}
Then I create a new file2.js and modify file1.js to import it. I also modify it to export the function that is used. I then also modify the index.html file's script tag to tell it that file1.js is now a module like this (to avoid the 'Cannot use import outside of a module' error):
<script type="module" src="./scripts/file1.js"></script>
Modified file1.js
import { file2Go } from "./file2.js"
export function file1Go(msg) {
alert('In file1.js - ' + msg);
file2Go(msg);
}
New file2.js
export function file2Go(msg) {
alert('In file2.js - ' + msg);
}
This results in the html page loading and both .js files downloading without error, but at runtime it fails to find the exported function in file1.js:
(index):11 Uncaught ReferenceError: file1Go is not defined at HTMLInputElement.onkeyup ((index):11)
That's it. What stupid thing am I doing wrong or what am I missing?
And thanks in advance for taking the time.
Afterthought: Putting similar .js files in a folder and executing with node.js appears to work.
More Info:
I've discovered that the following <script> tag does import and execute the function. I can also set HTML event handlers there. It's just that functions are apparently not visible outside of the scope of the <script> tag which to my little brain appears to be unduly restrictive and unuseful.
<script type="module">
import { file1Go } from "./scripts/file1.js";
file1Go("logging on start in <head> tag..."); // works
document.getElementById('Xxx').onkeyup = file1Go; // also works
</script>
Note: My endgame here is to use TypeScript which would have many files. I removed TypeScript from my repro for simplicity and to target the root cause of my issue. Once I understand the scoping issue I'll move on to TypeScript.

Cannot use console.log() in a module

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

How to use Traceur with nested directory structure?

I want to use ES6 for my next project and I'm using Traceur as transpiler for the purpose. I got it working the way described in the Getting Started guide. However I would like to compile all my source files into single minified file in a way they describe it on the Compiling Offline page. But I cannot get it to work with multiple source files organized in a nested directory structure.
Here's a sample project to explain the problem. It has index.html in root folder and two .js files under src.
<project-root>
/index.html
/src/one.js
/src/two.js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="traceur.js" type="text/javascript"></script>
<script src="bootstrap.js" type="text/javascript"></script>
<script type="module" src="src/two.js"></script>
<script type="module">
import Two from 'src/two.js';
let t = new Two();
console.log(t);
</script>
<title>Title</title>
</head>
<body>
</body>
</html>
src/one.js
export default class One {
constructor() {
console.log("One constructor");
}
}
src/two.js
import One from 'src/one.js';
export default class Two extends One {
constructor () {
console.log("Two constructor");
super();
}
}
As I said, if I open index.html in browser, it will correctly work, printing the instance of Two to console.
But when I try to compile this offline, I get following error
PS D:\code\flattraceur> traceur.cmd src/two.js --out out\two.js
[Error: Error: ENOENT: no such file or directory, open 'D:\code\flattraceur\out\src\one.js'
Specified as src/one.js.
Imported by ../src/two.js.
Normalizes to src/one.js
locate resolved against base 'D:/code/flattraceur/out/'
]
As you can see, while compiling src/two.js, traceur looks for src/one.js under the output directory. I couldn't find any options on traceur that would let me customize the root of its search for referenced modules. I tried the --dir option too, but it fails too.
PS D:\code\flattraceur> traceur.cmd --dir src out
Error: At least one input file is needed
Any suggestions?

Categories