Jerry Chen
Jerry Chen

Reputation: 13857

"Uncaught SyntaxError: Cannot use import statement outside a module" when importing ECMAScript 6

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

Upvotes: 1333

Views: 4490350

Answers (30)

KyleMit
KyleMit

Reputation: 30287

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.

Upvotes: 857

Fran&#231;ois Petitit
Fran&#231;ois Petitit

Reputation: 409

If you're using NextJS, maybe your code should be use on the client (brower) side only. Try replace the component in the Page by a dynamic import with "ssr: false" like this in '/pages/my-page':

[...]
const MyClientSideOnlyComponent = dynamic(() => import('../components/Component'), {ssr: false});
    
return   <MyClientSideOnlyComponent/>
[...]

instead of

return <Component/>

Upvotes: 1

Siva
Siva

Reputation: 143

If you are facing the same issue in the Cucumber TypeScript framework then the below fix is working.

In the cucumber.json file, mention as below. Install the ts-node.

{
    "default":{
        "requireModule":[
            "ts-node/register"
        ]
    }
}

Upvotes: 0

IggyBar
IggyBar

Reputation: 138

I've added this in the tsconfig.json file and it fixed it. I was having this issue when trying to run the mockttp!

"ts-node": {
    "compilerOptions": {
        "module": "commonjs"
    }
}

Upvotes: -2

loopassembly
loopassembly

Reputation: 3893

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>

This is the most recommended way to fix the issue
By adding the type="module" attribute, you are telling the browser that the script should be treated as an ECMAScript module, and it should use the appropriate rules for resolving dependencies and executing the code.


2. The second: In node.js, into your package.json file

{
  "type": "module",
}

Restart the project npm start


3. The third: replace import by require()

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

Upvotes: 103

sandeep talabathula
sandeep talabathula

Reputation: 3308

try add .babelrc

{
"presets": [
  [
    "@babel/env",
    {
      "targets": {
        "node": "12"
      },
      "modules": "commonjs"
    }
  ]
] }

Upvotes: 1

uppu
uppu

Reputation: 83

Following worked, inline export gave issue but export at the end of fn following worked. const xxx = async(....)

module.exports = { xxx, };

Upvotes: 0

nik s
nik s

Reputation: 1321

I resolved my case by replacing import with require:

// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');

Upvotes: 123

Emmanuel
Emmanuel

Reputation: 8662

I got this error because I forgot the type="module" inside the script tag:

<script type="module" src="whatever.js"></script>

Upvotes: 663

Anurag Phadnis
Anurag Phadnis

Reputation: 867

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.

Upvotes: 62

Anu
Anu

Reputation: 3450

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();

Upvotes: 0

McDude
McDude

Reputation: 29

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

Upvotes: 0

gg-dev-05
gg-dev-05

Reputation: 407

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.

Upvotes: 2

Moses Ejim
Moses Ejim

Reputation: 37

Use

<script type="module" src="/src/moduleA.js"></script>

instead of

<script>System.import("/src/moduleA.js")</script>

Upvotes: -2

Kavindu Dissanayake
Kavindu Dissanayake

Reputation: 895

Add "type": "module", to your package.json file.

And restart your application:

npm start

Then your problem is solved.

Upvotes: 15

somil007
somil007

Reputation: 7

This error occurs when it fails in Babel transpile.

Upvotes: -8

Luke McKela
Luke McKela

Reputation: 302

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

Upvotes: 5

K Lee
K Lee

Reputation: 493

I have faced the same error by EXPO.

Mainly the solution is that to add "type": "module", in the package.json file.

my files, you can find two package.json

Code Image

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",

Upvotes: 5

Anusionwu Chikeluba
Anusionwu Chikeluba

Reputation: 455

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

Upvotes: 25

Sarthak Raval
Sarthak Raval

Reputation: 1291

I got this error in React and fixed it with the following steps:

  1. Go to the project root directory, and open the Package.json file for editing.

  2. Add "type":"module";

  3. Save it and restart the server.

Upvotes: 16

Devesh Shirsath
Devesh Shirsath

Reputation: 1

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>

Upvotes: -6

A-S
A-S

Reputation: 3153

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)
   ],

Upvotes: 22

Elizabeth
Elizabeth

Reputation: 196

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.

Upvotes: 12

ISS
ISS

Reputation: 416

In my case, I updated

"lib": [
      "es2020",
      "dom"
    ]

with

"lib": [
  "es2016",
  "dom"
]

in my tsconfig.json file.

Upvotes: 2

John Samuel J
John Samuel J

Reputation: 1

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.

Upvotes: -1

Alalade Samuel
Alalade Samuel

Reputation: 672

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>`

Upvotes: 12

Alalade Samuel
Alalade Samuel

Reputation: 672

I ran into this error while trying to use import Express.js.

Instead of   import express from 'express';

I used   const express = require('express');

Upvotes: 4

Goaul
Goaul

Reputation: 1570

For me this helped:

  1. In the .ts file I used: import prompts from "prompts";
  2. And used "module": "commonjs" in file tsconfig.json

Upvotes: 9

HamidReza
HamidReza

Reputation: 1934

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>

Upvotes: 3

skele
skele

Reputation: 93

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.

Upvotes: 1

Related Questions