Using Modules in the Browser (without WebPack) - javascript

I'm grokking my way through ES6 and I ran into Modules (nice!) and in learning, I am trying to see if I can use them in the browser without WebPack (which I haven't learned yet).
So, I have the following files/folder structure in my JS directory
js
- lib (for complied es6 via Babel)
- mods (compiled modules)
- module.js (compiled via Babel)
- app.js (imports modules, attached to index.html)
- src (for "raw" es6)
- mods (es6 modules)
- module.js (es6 module)
- app.js (imports modules)
In js/src/mods/module.js, I have the following code....
export const topTime = 1.5;
export const subTime = 0.75;
Which is imported by js/src/app.js ...
import { topTime, subTime } from './mods/modules';
console.log(topTime);
console.log(subTime);
I then compiled all es6 files to es5 (which placed the files in the lib dir.)
npm run babel
Now I can run the main file (js/lib/app.js) inside my editor (vscode/output tab)
[Running] node "/home/me/www/es6.local/js/lib/app.js"
1.5
0.75
...but I think that is only because it's running in node.
It breaks when I call my index.html file (with js/lib/app.js) in the browser (FF) as I get the following error...
ReferenceError: require is not defined
So I see that babel compiled this...
import { topTime, subTime } from './mods/modules';
into this...
var _modules = require('./mods/modules');
...But I thought this was valid es5? ...no? So HOW was this done BEFORE webpack? Please advise.
Here is my package.json (in case it helps)...
{
"name": "es6.local",
"version": "0.0.1",
"description": "JavaScript ES6 Testing Sandbox",
"main": "index.html",
"scripts": {
"babel": "babel js/src --out-dir js/lib --source-maps"
},
"author": "Student",
"license": "ISC",
"devDependencies": {
"eslint": "^4.16.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.6.0",
"eslint-config-airbnb": "^16.1.0",
"babel-cli": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1"
},
"babel": {
"presets": [
[
"env",
{
"targets": {
"browsers": [
"last 2 versions",
"safari >= 7"
]
}
}
]
]
}
}

I've been stuck with this for a while and after playing around I found a solution.
You don't need any libraries or webpack to do this and I'm not sure this works outside of chrome.
You need to run this code on a webserver or else it won't work (in other words, it has to be on localhost, NOT file://)
Make a folder called jsmodule
create a file called index.html with the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Js module</title>
</head>
<body>
<h1>JS module test</h1>
<script type="module" src="script.js"></script>
</body>
</html>
Create a file in same folder called script.js with the following code:
import Person from './Person.js';
import Book from './Book.js';
let person1 = new Person();
let someBook = new Book();
create a file in same folder called Person.js with the following code:
export default class Person{
constructor(){
alert("hallo from person");
}
}
create a file in same folder called Book.js with the following code:
export default class Book{
constructor(){
alert("Hallo from book");
}
}
Run the index.html on you webserver (localhost)

In the HTML
script src="/my-script.js" type="module">
In the script
import axios from './axios.js';
The script tag in the HTML needs to have the type of module, else the parser will not understand what import is.
The import statement needs to have the full path to the JS file you’re importing (relative paths should be fine): you cannot do import axios from 'axios' because that’s just a string — the browser has no idea if that’s even a file or where that file is.
The browser has no idea what NPM is. It’s a package manager for Node, it’s not connected to JavaScript in general. You need the actual file (which you could use NPM to add to your project, then the path will be something like ./node_modules/axios/dist/axios.js
but even using this could create some problem as it some internal dependency over some packages or libraries in node_modules folder
I would recommend using webpack or any blunder tool
which auto-magically use NPM modules then bundle everything up into a single output file.

It's a pain.
exports and require are part of the CommonJS spec. If I remember correctly, webpack implements it internally. You need the same functionality, because it's not part of ES5.
Try RequireJS, or something similar to load your modules.

Related

Uncaught SyntaxError: Cannot use import statement outside a module in Redux [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

How do I create an object in Javascript if it's of type Interface? [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

I am getting "Uncaught SyntaxError: Cannot use import statement outside a module" although i have script type="module" in my html file [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

Cannot use import statement outside a module javascript error [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

React: SyntaxError: Cannot use import statement outside a module [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

Categories