I'm new to ES6 (ECMAScript 6), and I'd like to use its module system in the browser. I read ES6 is supported by Firefox and Chrome, but I'm getting the following error using export
Uncaught SyntaxError: Unexpected token import
I have a test.html file
<html>
<script src="test.js"></script>
<body>
</body>
</html>
and a test.js file
'use strict';
class Test {
static hello() {
console.log("hello world");
}
}
export Test;
Why?
Many modern browsers now support ES6 modules. As long as you import your scripts (including the entrypoint to your application) using <script type="module" src="..."> it will work.
Take a look at caniuse.com for more details:
https://caniuse.com/#feat=es6-module
You can try ES6 Modules in Google Chrome Beta (61) / Chrome Canary.
Reference Implementation of ToDo MVC by Paul Irish - https://paulirish.github.io/es-modules-todomvc/
I've basic demo -
//app.js
import {sum} from './calc.js'
console.log(sum(2,3));
//calc.js
let sum = (a,b) => { return a + b; }
export {sum};
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>ES6</h1>
<script src="app.js" type="module"></script>
</body>
</html>
Hope it helps!
Unfortunately, modules aren't supported by many browsers right now.
This feature is only just beginning to be implemented in browsers natively at this time. It is implemented in many transpilers, such as TypeScript and Babel, and bundlers such as Rollup and Webpack.
Found on MDN
it worked for me adding type="module" to the script importing my mjs:
<script type="module">
import * as module from 'https://rawgit.com/abernier/7ce9df53ac9ec00419634ca3f9e3f772/raw/eec68248454e1343e111f464e666afd722a65fe2/mymod.mjs'
console.log(module.default()) // Prints: Hi from the default export!
</script>
See demo: https://codepen.io/abernier/pen/wExQaa
It could be that you changed an existing script to a module and forgot to remove the original script tag. This is what happened to me and how I got directed to this page. I had originally had this:
<script src="app.js" defer></script>
Then I changed my main script tag to import it as a module and it was working, but I still received the error. I couldn't figure out how it could be working and throwing an error, but I had forgotten to remove the original script tag.
Related
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
I'm trying to import the custom geometry "OutlinesGeometry.js" from https://plnkr.co/edit/uEYo6L3pgbIaYXXzVzXd?preview
I'm trying to import following way:
<script type="module" src="./three/build/three.module.js"></script>
<script type="module" src="./three/examples/jsm/controls/OrbitControls.js"></script>
<script type="module" src="./three/examples/jsm/libs/dat.gui.min.js"></script>
<script type="module" src="./OutlinesGeometry.js"></script>
This gives me following errors:
First I did not import three, OrbitControls and dat.gui as modules, as everything worked fine (see imports below). But as soon I'm importing the OutlinesGeometry I received following error: Uncaught TypeError: class constructors must be invoked with 'new'. Because of that I'm importing the modules.
<script src="./three/build/three.js"></script>
<script src="./three/examples/js/controls/OrbitControls.js"></script>
<script src="./three/examples/js/libs/dat.gui.min.js"></script>
<script src="./OutlinesGeometry.js"></script>
How should the imports be done correctly?
The runtime error happens because you are deriving from a ES6 class via ES5 syntax.
In newer releases BufferGeometry is a ES6 class. When creating a custom geometry generator, the following code is invalid:
THREE.BufferGeometry.call( this );
You can only solve this issue by migrating OutlinesGeometry to an ES6 class as well.
BTW: When working with modules, you just have a single <script type="module"></script> tag and use inside of the tag ES6 import syntax. Meaning:
<script type="module">
import * as THREE from './three/build/three.module.js';
import OrbitControls from './three/examples/jsm/controls/OrbitControls.js';
I suggest you study the official three.js example for more details.
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.
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?
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");
}
}