Cannot use import statement outside a module ошибка

I’ve got an ApolloServer project that’s giving me trouble, so I thought I might update it and ran into issues when using the latest Babel. My «index.js» is:

require('dotenv').config()
import {startServer} from './server'
startServer()

And when I run it I get the error

SyntaxError: Cannot use import statement outside a module

First I tried doing things to convince TPTB* that this was a module (with no success). So I changed the «import» to a «require» and this worked.

But now I have about two dozen «imports» in other files giving me the same error.

*I’m sure the root of my problem is that I’m not even sure what’s complaining about the issue. I sort of assumed it was Babel 7 (since I’m coming from Babel 6 and I had to change the presets) but I’m not 100% sure.

Most of what I’ve found for solutions don’t seem to apply to straight Node. Like this one here:

ES6 module Import giving «Uncaught SyntaxError: Unexpected identifier»

Says it was resolved by adding «type=module» but this would typically go in the HTML, of which I have none. I’ve also tried using my project’s old presets:

"presets": ["es2015", "stage-2"],
"plugins": []

But that gets me another error: «Error: Plugin/Preset files are not allowed to export objects, only functions.»

Here are the dependencies I started with:

"dependencies": {
  "@babel/polyfill": "^7.6.0",
  "apollo-link-error": "^1.1.12",
  "apollo-link-http": "^1.5.16",
  "apollo-server": "^2.9.6",
  "babel-preset-es2015": "^6.24.1",

Moritz Ringler's user avatar

asked Oct 14, 2019 at 21:17

user3810626's user avatar

11

Verify that you have the latest version of Node.js installed (or, at least 13.2.0+). Then do one of the following, as described in the documentation:

Option 1

In the nearest parent package.json file, add the top-level "type" field with a value of "module". This will ensure that all .js and .mjs files are interpreted as ES modules. You can interpret individual files as CommonJS by using the .cjs extension.

// package.json
{
  "type": "module"
}

Option 2

Explicitly name files with the .mjs extension. All other files, such as .js will be interpreted as CommonJS, which is the default if type is not defined in package.json.

Moritz Ringler's user avatar

answered Dec 18, 2019 at 20:43

jabacchetta's user avatar

jabacchettajabacchetta

43.8k8 gold badges61 silver badges75 bronze badges

13

If anyone is running into this issue with TypeScript, the key to solving it for me was changing

    "target": "esnext",
    "module": "esnext",

to

    "target": "esnext",
    "module": "commonjs",

In my tsconfig.json. I was under the impression «esnext» was the «best», but that was just a mistake.

Moritz Ringler's user avatar

answered Jul 10, 2020 at 15:03

Dr-Bracket's user avatar

Dr-BracketDr-Bracket

4,0863 gold badges18 silver badges26 bronze badges

8

For those who were as confused as I was when reading the answers, in your package.json file, add
"type": "module"
in the upper level as show below:

{
  "name": "my-app",
  "version": "0.0.0",
  "type": "module",
  "scripts": { ...
  },
  ...
}

riQQ's user avatar

riQQ

9,2475 gold badges45 silver badges64 bronze badges

answered Jun 12, 2020 at 9:03

L. Theodore Obonye's user avatar

3

According to the official documentation:

import statements are permitted only in ES modules. For similar functionality in CommonJS, see import().

To make Node.js treat your file as an ES module, you need to (Enabling):

  • add «type»: «module» to package.json
  • add «—experimental-modules» flag to the Node.js call

Liam's user avatar

Liam

27.2k28 gold badges125 silver badges187 bronze badges

answered Nov 21, 2019 at 14:13

Konstantin Gatilin's user avatar

7

I ran into the same issue and it’s even worse: I needed both «import» and «require»

  1. Some newer ES6 modules works only with import.
  2. Some CommonJS works with require.

Here is what worked for me:

  1. Turn your js file into .mjs as suggested in other answers

  2. «require» is not defined with the ES6 module, so you can define it this way:

    import { createRequire } from 'module'
    const require = createRequire(import.meta.url);
    

    Now ‘require’ can be used in the usual way.

  3. Use import for ES6 modules and require for CommonJS.

Some useful links: Node.js’s own documentation. difference between import and require. Mozilla has some nice documentation about import

Peter Mortensen's user avatar

answered May 22, 2020 at 4:26

us_david's user avatar

us_davidus_david

4,34535 silver badges28 bronze badges

1

I had the same issue and the following has fixed it (using Node.js 12.13.1):

  • Change .js files extension to .mjs
  • Add --experimental-modules flag upon running your app.
  • Optional: add "type": "module" in your package.json

More information: https://nodejs.org/api/esm.html

Peter Mortensen's user avatar

answered Nov 25, 2019 at 9:49

iseenoob's user avatar

iseenoobiseenoob

3211 silver badge8 bronze badges

I Tried with all the methods, but nothing worked.

I got one reference from GitHub.

To use TypeScript imports with Node.js, I installed the below packages.

1. npm i typescript --save-dev

2. npm i ts-node --save-dev

Won’t require type: module in package.json

For example,

{
  "name": "my-app",
  "version": "0.0.1",
  "description": "",
  "scripts": {

  },
  "dependencies": {
    "knex": "^0.16.3",
    "pg": "^7.9.0",
    "ts-node": "^8.1.0",
    "typescript": "^3.3.4000"
  }
}

Moritz Ringler's user avatar

answered Nov 4, 2020 at 11:51

Rohit Parte's user avatar

Rohit ParteRohit Parte

3,23925 silver badges25 bronze badges

2

First we’ll install @babel/cli, @babel/core and @babel/preset-env:

npm install --save-dev @babel/cli @babel/core @babel/preset-env

Then we’ll create a .babelrc file for configuring Babel:

touch .babelrc

This will host any options we might want to configure Babel with:

{
  "presets": ["@babel/preset-env"]
}

With recent changes to Babel, you will need to transpile your ES6 before Node.js can run it.

So, we’ll add our first script, build, in file package.json.

"scripts": {
  "build": "babel index.js -d dist"
}

Then we’ll add our start script in file package.json.

"scripts": {
  "build": "babel index.js -d dist", // replace index.js with your filename
  "start": "npm run build && node dist/index.js"
}

Now let’s start our server.

npm start

Moritz Ringler's user avatar

answered Aug 19, 2020 at 11:50

Roque Orts's user avatar

Roque OrtsRoque Orts

3002 silver badges11 bronze badges

1

I found the 2020 update to the answer in this link helpful to answering this question as well as telling you WHY it does this:

Using Node.js require vs. ES6 import/export

Here’s an excerpt:

«Update 2020

Since Node v12, support for ES modules is enabled by default, but it’s still experimental at the time of writing this. Files including node modules must either end in .mjs or the nearest package.json file must contain «type»: «module». The Node documentation has a ton more information, also about interop between CommonJS and ES modules.»

answered Jul 21, 2021 at 20:41

David S's user avatar

David SDavid S

3734 silver badges6 bronze badges

5

Step 1

yarn add esm

or

npm i esm --save

Step 2

package.json

"scripts": {
  "start": "node -r esm src/index.js",
}

Step 3

nodemon --exec npm start

Moritz Ringler's user avatar

answered Jul 31, 2020 at 6:22

Abhishek Kumar's user avatar

1

Node v14.16.0
For those who’ve tried .mjs and got:

Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.mjs
file:///mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.mjs:3
import fetch from "node-fetch";
       ^^^^^
    
SyntaxError: Unexpected identifier

and who’ve tried import fetch from "node-fetch";
and who’ve tried const fetch = require('node-fetch');

Aviator@AW:/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex$ node just_js.js
(node:4899) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/mnt/c/Users/Adrian/Desktop/Programming/nodejs_ex/just_js.js:3
import fetch from "node-fetch";
^^^^^^

SyntaxError: Cannot use import statement outside a module  

and who’ve tried "type": "module" to package.json, yet continue seeing the error,

{
  "name": "test",
  "version": "1.0.0",
  "description": "to get fetch working",
  "main": "just_js.js",
  "type": "module",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "MIT"
}

I was able to switch to axios without a problem.

import axios from 'axios'; <— put at top of file.
Example:

axios.get('https://www.w3schools.com/xml/note.xml').then(resp => {
    console.log(resp.data);
});

Moritz Ringler's user avatar

answered Sep 27, 2021 at 19:10

Adrian's user avatar

AdrianAdrian

3311 gold badge3 silver badges11 bronze badges

1

I’m new to Node.js, and I got the same issue for the AWS Lambda function (using Node.js) while fixing it.

I found some of the differences between CommonJS and ES6 JavaScript:

ES6:

  • Add «type»:»module» in the package.json file

  • Use «import» to use from lib.

    Example: import jwt_decode from jwt-decode

  • Lambda handler method code should be define like this

    «exports.handler = async (event) => { }»

CommonJS:

  • Don’t add «type»:»module» in the package.json file

  • Use «require» to use from lib.

    Example: const jwt_decode = require(«jwt-decode»);

  • The lambda handler method code should be defines like this:

    «export const handler = async (event) => { }»

Peter Mortensen's user avatar

answered Aug 26, 2022 at 13:20

Gowtham's user avatar

GowthamGowtham

4695 silver badges9 bronze badges

If you are using ES6 JavaScript imports:

  1. install cross-env
  2. in package.json change "test": "jest" to "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  3. more in package.json, add these:
    ...,
    "jest": {
        "transform": {}
    },
    "type": "module"

Explanation:

cross-env allows to change environment variables without changing the npm command. Next, in file package.json you change your npm command to enable experimental ES6 support for Jest, and configure Jest to do it.

Moritz Ringler's user avatar

answered Jun 24, 2022 at 16:17

Luca C.'s user avatar

Luca C.Luca C.

11.4k1 gold badge86 silver badges77 bronze badges

In my case. I think the problem is in the standard node executable. node target.ts

I replaced it with nodemon and surprisingly it worked!

The way using the standard executable (runner):

node target.ts

The way using the nodemon executable (runner):

nodemon target.ts

Do not forget to install nodemon with npm install nodemon ;P

Note: this works amazing for development. But, for runtime, you may execute node with the compiled js file!

Update:

The problem is that node does not accept typescript files.
Instead, ts-node might be the perfect replacement.

answered Nov 29, 2020 at 8:30

LSafer's user avatar

LSaferLSafer

3243 silver badges7 bronze badges

1

To use import, do one of the following.

  1. Rename the .js file to .mjs
  2. In package.json file, add {type:module}

answered Feb 2, 2022 at 16:01

Vidya Sagar H J's user avatar

1

This error also comes when you run the command

node filename.ts

and not

node filename.js

Simply put, with the node command we will have to run the JavaScript file (filename.js) and not the TypeScript file unless we are using a package like ts-node.

Peter Mortensen's user avatar

answered Sep 15, 2020 at 4:06

Jitender Kumar's user avatar

Jitender KumarJitender Kumar

2,3494 gold badges29 silver badges42 bronze badges

If you want to use BABEL, I have a simple solution for that!

Remember this is for nodejs example: like an expressJS server!

If you are going to use react or another framework, look in the babel documentation!

First, install (do not install unnecessary things that will only trash your project!)

npm install --save-dev @babel/core @babel/node

Just 2 WAO

then config your babel file in your repo!

example for express server node js and babel

file name:

babel.config.json

{
    "presets": ["@babel/preset-env"]
}


if you don’t want to use the babel file, use:

Run in your console, and script.js is your entry point!

npx babel-node --presets @babel/preset-env -- script.js

example babel without file

the full information is here; https://babeljs.io/docs/en/babel-node

answered Dec 30, 2021 at 23:52

Daniel's user avatar

DanielDaniel

3634 silver badges10 bronze badges

I had this error in my NX workspace after upgrading manually. The following change in each jest.config.js fixed it:

transform: {
  '^.+\.(ts|js|html)$': 'jest-preset-angular',
},

to

transform: {
  '^.+\.(ts|mjs|js|html)$': 'jest-preset-angular',
},

answered Dec 30, 2021 at 13:35

Pieterjan's user avatar

PieterjanPieterjan

2,6804 gold badges26 silver badges52 bronze badges

1

I had this issue when I was running migration

Its es5 vs es6 issue

Here is how I solved it

I run

npm install @babel/register

and add

require("@babel/register")

at the top of my .sequelizerc file my

and go ahead to run my sequelize migrate.
This is applicable to other things apart from sequelize

babel does the transpiling

answered Dec 1, 2020 at 10:58

Ahmed Adewale's user avatar

Just add --presets '@babel/preset-env'.

For example,

babel-node --trace-deprecation --presets '@babel/preset-env' ./yourscript.js

Or

in babel.config.js

module.exports = {
  presets: ['@babel/preset-env'],
};

Peter Mortensen's user avatar

answered Jun 18, 2020 at 14:08

srghma's user avatar

srghmasrghma

4,7002 gold badges38 silver badges54 bronze badges

0

To make your import work and avoid other issues, like modules not working in Node.js, just note that:

With ES6 modules you can not yet import directories. Your import should look like this:

import fs from './../node_modules/file-system/file-system.js'

Peter Mortensen's user avatar

answered Oct 27, 2020 at 13:59

DINA TAKLIT's user avatar

DINA TAKLITDINA TAKLIT

6,7459 gold badges69 silver badges73 bronze badges

The documentation is confusing. I use Node.js to perform some local task in my computer.

Let’s suppose my old script was test.js. Within it, if I want to use

import something from "./mylocalECMAmodule";

it will throw an error like this:

(node:16012) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
SyntaxError: Cannot use import statement outside a module
...

This is not a module error, but a Node.js error. Forbid loading anything outside a ‘module’.

To fix this, just rename your old script test.js into test.mjs.

That’s all.

Peter Mortensen's user avatar

answered Sep 23, 2022 at 8:15

yo3hcv's user avatar

yo3hcvyo3hcv

1,4972 gold badges17 silver badges26 bronze badges

My solution was to include babel-node path while running nodemon as follows:

nodemon node_modules/.bin/babel-node index.js

You can add in your package.json script as:

debug: nodemon node_modules/.bin/babel-node index.js

NOTE: My entry file is index.js. Replace it with your entry file (many have app.js/server.js).

Peter Mortensen's user avatar

answered Feb 5, 2020 at 5:57

ishab acharya's user avatar

  1. I had the same problem when I started to use Babel… But later, I
    had a solution… I haven’t had the problem any more so far…
    Currently, Node.js v12.14.1, «@babel/node»: «^7.8.4», I use babel-node and nodemon to execute (Node.js is fine as well..)
  2. package.json: «start»: «nodemon —exec babel-node server.js «debug»: «babel-node debug server.js»!! Note: server.js is my entry
    file, and you can use yours.
  3. launch.json. When you debug, you also need to configure your launch.json file «runtimeExecutable»:
    «${workspaceRoot}/node_modules/.bin/babel-node»!! Note: plus
    runtimeExecutable into the configuration.
  4. Of course, with babel-node, you also normally need and edit another file, such as the babel.config.js/.babelrc file

Peter Mortensen's user avatar

answered Feb 12, 2020 at 16:48

MrLetmein's user avatar

In case you’re running nodemon for the Node.js version 12, use this command.

server.js is the «main» inside package.json file, replace it with the relevant file inside your package.json file:

nodemon --experimental-modules server.js

Peter Mortensen's user avatar

answered Sep 27, 2020 at 13:30

harika 's user avatar

harika harika

213 bronze badges

1

If you are using node, you should refer to this document. Just setup babel in your node app it will work and It worked for me.

npm install --save-dev @babel/cli @babel/core @babel/preset-env

answered Sep 20, 2021 at 21:37

ncutixavier's user avatar

ncutixavierncutixavier

3713 silver badges4 bronze badges

1

When I used sequelize migrations with npx sequelize db:migrate, I got this error, so my solution for this was adding the line require('@babel/register'); into the .sequelizerc file as the following image shows:

Enter image description here

Be aware you must install Babel and Babel register.

Peter Mortensen's user avatar

answered Apr 20, 2022 at 18:31

DariusV's user avatar

DariusVDariusV

2,61714 silver badges21 bronze badges

1

Wrong MIME-Type for JavaScript Module Files

The common source of the problem is the MIME-type for «Module» type JavaScript files is not recognized as a «module» type by the server, the client, or the ECMAScript engine that process or deliver these files.

The problem is the developers of Module JavaScript files incorrectly associated Modules with a new «.mjs» (.js) extension, but then assigned it a MIME-type server type of «text/javascript». This means both .js and .mjs types are the same. In fact the new type for .js JavaScript files has also changed to «application/javascript», further confusing the issue. So Module JavaScript files are not being recognized by any of these systems, regardless of Node.js or Babel file processing systems in development.

The main problem is this new «module» subtype of JavaScript is yet known to most servers or clients (modern HTML5 browsers). In other words, they have no way to know what a Module file type truly is apart from a JavaScript type!

So, you get the response you posted, where the JavaScript engine is saying it needs to know if the file is a Module type of JavaScript file.

The only solution, for server or client, is to change your server or browser to deliver a new Mime-type that trigger ES6 support of Module files, which have an .mjs extension. Right now, the only way to do that is to either create a HTTP content-type on the server of «module» for any file with a .mjs extension and change your file extension on module JavaScript files to «.mjs», or have an HTML script tag with type="module" added to any external <script> element you use that downloads your external .js JavaScript module file.

Once you fool the browser or JavaScript engines into accepting the new Module file type, they will start doing their scripting circus tricks in the JS engines or Node.js systems you use.

answered Dec 25, 2022 at 2:06

Stokely's user avatar

StokelyStokely

11.7k2 gold badges33 silver badges24 bronze badges

I recently had the issue. The fix which worked for me was to add this to file babel.config.json in the plugins section:

["@babel/plugin-transform-modules-commonjs", {
    "allowTopLevelThis": true,
    "loose": true,
    "lazy": true
  }],

I had some imported module with // and the error «cannot use import outside a module».

Moritz Ringler's user avatar

answered Oct 2, 2020 at 8:43

Chalom.E's user avatar

Chalom.EChalom.E

6175 silver badges20 bronze badges

Table of Contents

Hide

  1. What is SyntaxError: cannot use import statement outside a module?
  2. How to fix SyntaxError: cannot use import statement outside a module?
    1. Solution 1 – Add “type”: “module” to package.json 
    2. Solution 2 – Add type=”module” attribute to the script tag
    3. Solution 3 – Use import and require to load the modules
  3. Configuration Issue in ORM’s
  4. Conclusion

The Uncaught SyntaxError: cannot use import statement outside a module mainly occurs when developers use the import statement on the CommonJS instead of require statement.

What is SyntaxError: cannot use import statement outside a module?

There are several reasons behind this error. First, let us look at each scenario and solution with examples.

  • If you are using an older Node version < 13
  • If you are using a browser or interface that doesn’t support ES6
  • If you have missed the type=”module” while loading the script tag
  • If you missed out on the “type”: “module” inside the package.json while working on Node projects

Many interfaces till now do not understand ES6 Javascript features. Hence we need to compile ES6 to ES5 whenever we need to use that in the project.

The other possible reason is that you are using the file that is written in the ES6 module directly inside your code. It means you are loading the src file/directory instead of referring to the dist directory, which leads to a SyntaxError.

Usually, we use a bundled or dist file that is compiled to ES5/Javascript file and then import the modules in our code.

How to fix SyntaxError: cannot use import statement outside a module?

There are 3 ways to solve this error. Let us take a look at each of these solutions.

Solution 1 – Add “type”: “module” to package.json 

If you are working on Node.js or react applications and using import statements instead of require to load the modules, then ensure your package.json has a property "type": "module" as shown below.

Adding “type”: “module” to package.json will tell Node you are using ES6 modules(es modules), which should get solve the error. 

If you would like to use the ES6 module imports in Node.js, set the type property to the module in the package.json file.

   {
        // ...
        "type": "module",
        // ...
    }

If you are using TypeScript, we need to edit the tsconfig.json file and change the module property to “commonjs“, as shown below.

ts.config file

Change the ts.config file as shown below to resolve the Uncaught SyntaxError: cannot use import statement outside a module error.

    "target": "esnext",
    "module": "esnext",

to

    "target": "esnext",
    "module": "commonjs",

If this error mainly occurs in the TypeScript project, ensure that you are using a ts-node to transpile into Javascript before running the .ts file. Node.js can throw an error if you directly run the typescript file without transpiling.

Note: If your project does not have a package.json file, initialize it by using the npm init -y command in the root directory of your project.

Solution 2 – Add type=”module” attribute to the script tag

Another reason we get this error is if we are loading the script from the src directory instead of the built file inside the dist directory. 

It can happen if the src file is written in ES6 and not compiled into an ES5 (standard js file). The dist files usually will have the bundled and compiled files, and hence it is recommended to use the dist folder instead of src.

We can solve this error by adding a simple attribute type="module" to the script, as shown below.

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

Solution 3 – Use import and require to load the modules

In some cases, we may have to use both import and require statements to load the module properly.

For Example – 

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

Note: When using modules, if you get ReferenceError: require is not defined, you’ll need to use the import syntax instead of require.

Configuration Issue in ORM’s

Another possible issue is when you are using ORM’s such as typeORM and the configuration you have set the entities to refer to the source folder instead of the dist folder.

The src folder would be of TypeScript file and referring the entities to .ts files will lead to cannot use import statement outside a module error.

Change the ormconfig.js to refer to dist files instead of src files as shown below.

 "entities": [
      "src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
   ],

to

  "entities": [
      "dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
   ],

Conclusion

The Uncaught SyntaxError: cannot use import statement outside a module occurs if you have forgotten to add type="module" attribute while loading the script or if you are loading the src files instead of bundled files from the dist folder.

We can resolve the issue by setting the “type”: “module” inside the package.json while working on Node projects. If we are loading the Javascript file then we need to add the attribute type="module" to the script tag.

Related Tags
  • import,
  • require,
  • SyntaxError

Sign Up for Our Newsletters

Get notified on the latest articles

By checking this box, you confirm that you have read and are agreeing to our terms of use regarding the storage of the data submitted through this form.

Introduction

Ever started a project or followed an online tutorial and everything is going fine until you hit this error:

SyntaxError Cannot Use Import Statement Outside a Module

The error “SyntaxError Cannot Use Import Statement Outside a Module”, is caused by you trying to use a library that is written as ECMAScript modules (ESM).

Ok? So what does this mean exactly?

In JavaScript there are usually 3 ways to use external libraries:

  1. If you are in the browser, you can use external libraries with a <script> tag.

For example, using jquery library can be done as:

  1. Using the import statement as part ECMAScript modules. This is the more modern way of importing libraries and you will see this in more online tutorials.

Consider having a math.js file

  

export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

Now if we want to use the math.js function, with ECMAScript modules, we can use the import keyword:

  
import { add, subtract } from './math.js';

console.log(add(1, 2)); // 3
console.log(subtract(5, 3)); // 2
  1. Using the CommonJs require() method. This method is the more older way to managing libraries and was created before agreement on the import statement!

So the error message “SyntaxError Cannot Use Import Statement Outside a Module” just means that you are trying to mix and match the different ways of using a JavaScript library.

There are three ways to fix this issue:

  1. Update your script tag to have the type=module attribute
  2. Update your package.json if your application is a Node application
  3. Convert import statements to CommonJS require() equivalent
  4. Use a transpiler like Babel to convert your import statements

1. Update your script tag to have the type=module attribute

If you are running your JavaScript in the browser, you can change the offending library to become a module like so:

  

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

You can also use it as a internal script like:

Tip: Check your file paths

Make sure that you are referencing the correct file path. As an example for relative paths, you MUST have the dot forward slash («./»)

If you import without the (‘./’) it will not work — eg this will not work: import {a} from "module.js";

2. Update your package.json if your application is a Node application

With the latest version of Node, it uses two types of module loaders — CommonJs and ECMAScript modules. We can tell Node to use ECMAScript modules and our import statements by updating the package.json.

As an example, lets say we are trying to use the cloudinary library like import cloudinary from 'cloudinary'.

However when running the code, we get the following error:

  

  (node:29424) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
c:Users...perspectivecloud.js:1
import cloudinary from 'cloudinary';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1018:16)
    at Module._compile (node:internal/modules/cjs/loader:1066:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1131:10)
    at Module.load (node:internal/modules/cjs/loader:967:32)
    at Function.Module._load (node:internal/modules/cjs/loader:807:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47

[Done] exited with code=1 in 0.183 seconds

To fix this, we need to go to our package.json file and add the type:module setting.
(Make sure that this setting is on the top level)

  

{
    // ... other package.json stuff
    "type": "module"
    // ... other package.json stuff
}

3. Convert import statements to CommonJS require() equivalent

A common way to fix this issue is to use only one way to load modules. Generally, you cannot mix between CommonJs and ECMAScript modules.
Just stick with one way of importing — eg either use require() from CommonJS or import keyword from ES6 modules.

As an example, lets say we are trying to use node-html-parser as a ES6 module with the import keyword:

import { parse } from 'node-html-parser';

Now this can give us the error: SyntaxError Cannot Use Import Statement Outside a Module.

To fix this, we can convert it to use CommonJS with the require() method like so:

const parse = require('node-html-parser');

Tip: Check library support for ES6 modules or CommonJS

In some cases, libraries may be only written in ES6 modules, so you cannot use the CommonJS require() method. The reverse can also occur aswell, the library is only written in CommonJS modules and therefore cannot be used with the import keyword.

In cases like this, consider changing your whole Node application to ES6 modules or wait for the author of the library to support your import method (or createa PR yourself)

4. Use a transpiler like Babel to convert your import statements

One way to make sure that all of code will be able to use ES6 Modules to to use a transpiler like Babel.

To do so we can follow the below steps:

  1. First we’ll install @babel/cli, @babel/core and @babel/preset-env:

npm install --save-dev @babel/cli @babel/core @babel/preset-env

  1. Then we’ll create a .babelrc file for configuring Babel:

touch .babelrc
This will host any options we might want to configure Babel with:

{
“presets”: [«@babel/preset-env»]
}

We then need to transpile our script first before handing over to Node to run. So on build, we pass the script to babel to transpile it for ES6 and put the code into the dist folder:

In file package.json.

  

"scripts": {
  "build": "babel index.js -d dist"
}

Now, in our “start” commamd, we will run the code from the dist folder intead of the src. So our package.json file will look like:

  

"scripts": {
  "build": "babel index.js -d dist", // replace index.js with your filename
  "start": "npm run build && node dist/index.js"
}

Now let’s start our server:

npm start

Jest error: SyntaxError: Cannot use import statement outside a module

When you are using a testing framework like Jest, you can come across this error also:

  

 FAIL  src/configuration/notifications.test.js
  ● Test suite failed to run

    /var/www/management/node/src/configuration/notifications.test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import notifications from './notifications';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

The reason for this is usually due to Jest not supporting ES modules yet.
We can see our code working in Node, but not Jest when testing is due to Node supporting ESM from versions from v16+. However as of the time of writing Jest does not support ESM.

To get around this we have a few options:

  1. Don’t use the esm syntax (import / export) and use CommonJs with the require() method

  2. Ensure you either disable code transforms by passing transform: {} or otherwise configure your transformer to emit ESM rather than the default CommonJS (CJS).

  3. Execute node with –experimental-vm-modules, e.g. node –experimental-vm-modules node_modules/jest/bin/jest.js or NODE_OPTIONS=–experimental-vm-modules npx jest etc..

  4. Consider using babel-jest in your project. (Note: newer versions of Jest should have babel-jest installed already. This applies for older projects/ versions)

Open up your terminal and install babel-jest as follows:

npm install --save-dev babel-jest

Make sure we have updated the package.json:

  

{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\.[t|j]sx?$": "babel-jest"
    }
  }
}

Create .babelrc configuration file

Create a babel.config.json config in your project root and enable some presets.

To start, you can use the env preset, which enables transforms for ES2015+

npm install @babel/preset-env --save-dev

In your babel.config.json file, enable the presets like this:

  

{
  "presets": ["@babel/preset-env"]
}

Summary

In this article, I went over step by step options to fix the error “SyntaxError Cannot Use Import Statement Outside a Module”. This error is caused by trying to use a library that is using ECMAScript modules (ESM) and we are not importing it correctly.

To fix this issue, we need to first determine where our JavaScript is running. If your JavaScript is in the browser, then update the <script> tag to have type="module". If the code is in the backend with Node — update the package.json to have "type": "module".

The final option is to convert all import keywords to CommonJs require(). Transpilers such as Babel can make this quicker and be part of the build process!

Cannot use import statement outside a module [React TypeScript Error Solved]

When building a web application, you may encounter the SyntaxError: Cannot use import statement outside a module error.

This error might be raised when using either JavaScript or TypeScript in the back-end. So you could be working on the client side with React, Vue, and so on, and still run into this error.

You can also encounter this error when working with JavaScript on the client side.

In this article, you’ll learn how to fix the SyntaxError: Cannot use import statement outside a module error when using TypeScript or JavaScript with Node.

You’ll also learn how to fix the error when working with JavaScript on the client side.

How to Fix the TypeScript SyntaxError: Cannot use import statement outside a module Error

In this section, we’ll work with a basic Node server using Express.

Note that if you’re using the latest version of TypeScript for your Node app, the tsconfig.json file has default rules that prevent the SyntaxError: Cannot use import statement outside a module error from being raised.

So you’re most likely not going to encounter the SyntaxError: Cannot use import statement outside a module error if you:

  • Install the latest version of TypeScript, and are using the default tsconfig.json file that is generated when you run tsc init with the latest version.
  • Setup TypeScript correctly for Node and install the necessary packages.

But let’s assume you’re not using the latest tsconfig.json file configurations.

Here’s an Express server that listens on port 3000 and logs «Hello World!» to the console:

import express from "express"

const app = express()

app.listen("3000", (): void => {
    console.log("Hello World!")
    // SyntaxError: Cannot use import statement outside a module
})

The code above looks as though it should run perfectly but the SyntaxError: Cannot use import statement outside a module is raised.

This is happening because we used the import keyword to import a module: import express from "express".

To fix this, head over to the tsconfig.json file and scroll to the modules section.

You should see a particular rule like this under the modules section:

/* Modules */
"module": "esnext" 

To fix the problem, change the value «esnext» to «commonjs».

That is:

/* Modules */
"module": "commonjs"

How to Fix the JavaScript SyntaxError: Cannot use import statement outside a module Error

Fixing the SyntaxError: Cannot use import statement outside a module error when using vanilla JS is a bit different from TypeScript.

Here’s our server:

import express from "express";

const app = express();

app.listen(3000, () => {
    console.log("Hello World!");
    // SyntaxError: Cannot use import statement outside a module
});

We’re getting the SyntaxError: Cannot use import statement outside a module error for the same reason — we used the import keyword to import a module.

To fix this, go to the package.json file and add "type": "module",. That is:

{
  "name": "js",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "type": "module",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Now you can use the import keyword without getting an error.

To fix this error when working with JavaScript on the client side (without any frameworks), simply add the attribute type="module" to the script tag of the file you want to import as a module. That is:

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

Summary

In this article, we talked about the SyntaxError: Cannot use import statement outside a module error in TypeScript and JavaScript.

This error mainly occurs when you use the import keyword to import a module in Node.js. Or when you omit the type="module" attribute in a script tag.

We saw code examples that raised the error and how to fix them when working with TypeScript and JavaScript.

Happy coding!



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

На чтение 3 мин Просмотров 1.3к. Опубликовано 05 марта 2023

Ошибка “SyntaxError: Cannot use import statement outside a module” возникает, когда интерпретатор JavaScript встречает оператор import вне модуля.

В JavaScript модуль – это код, выполняемый в своей собственной области видимости, отдельной от глобальной области видимости. Операторы импорта могут использоваться только внутри модуля, но не в глобальной области видимости.

Эта ошибка может возникнуть в любой среде JavaScript, в том числе и в Node.js. Однако более вероятно ее появление в средах, которые не поддерживают использование операторов импорта в глобальной области видимости, например, в старых JavaScript-движках или браузерах.

Содержание

  1. Исправление для HTML
  2. Исправление для Node.js
  3. Исправление для TypeScript

Исправление для HTML

Чтобы устранить проблему для HTML-скриптов, необходимо установить атрибут type элемента <script>, чтобы указать тип скрипта, включенного в элемент.

Если атрибут type имеет значение “module”, браузер будет знать, что сценарий является модулем JavaScript, и будет выполнять его как таковой.

Это позволит вам использовать операторы импорта внутри сценария.

Вот пример:

<!-- when loading raw JS -->

<script type="module"></script>

<!-- when loading external files -->

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

В качестве альтернативы вы можете использовать такой инструмент, как Babel, для транспонирования вашего кода, который преобразует утверждения импорта в более старый синтаксис, который можно использовать в глобальной области видимости. Затем вы можете включить транспонированный код в свой HTML-документ.

Исправление для Node.js

Чтобы использовать импорт модулей ES6 в Node.js, вы можете установить поле type в файле package.json вашего проекта, чтобы указать, что ваш проект использует модули ES6.

Вот пример:

{
  "name": "my-project",
  "type": "module",
  ...
}

После добавления поля type в файл package.json вы можете использовать оператор import в JavaScript-файлах вашего проекта без необходимости использования специальных флагов.

import myModule from './my-module';

// keep in mind that for local files, you have to append the .js extension to the module, like so:

import myModule from './my-module.js';

// if not you'll get the error: "[ERR_MODULE_NOT_FOUND]: Cannot find module".

Этот подход имеет несколько преимуществ. Во-первых, он не требует использования специальных флагов при запуске интерпретатора Node.js, что делает его более удобным. Во-вторых, он позволяет другим инструментам, таким как бандлеры и линтеры, распознать, что в вашем проекте используются модули ES6, что упрощает использование этих инструментов в вашем проекте.

Исправление для TypeScript

Чтобы использовать систему модулей CommonJS в проекте TypeScript, вам нужно включить опции компилятора allowSyntheticDefaultImports и esModuleInterop в конфиге TypeScript.

Эти опции позволяют TypeScript рассматривать импортируемые значения так, как будто они имеют экспорт по умолчанию, даже если они его не имеют, и использовать синтаксис импорта с модулями CommonJS.

tsconfig.json:
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    ...
  }
}

Эти параметры поддерживаются только в TypeScript 3.8 и более поздних версиях.

Другая возможность заключается в том, что вы пытаетесь запустить свои файлы TypeScript с помощью команды node, а не с помощью такого инструмента, как ts-node, для транспонирования и запуска.

В этом случае вы можете использовать ts-node для транспонирования и запуска ваших файлов, чтобы исправить ошибку.

Если у вас появились вопросы про то, как устранить ошибку “SyntaxError: Cannot use import statement outside a module”, мы будем рады ответить вам в комментариях ниже.

Понравилась статья? Поделить с друзьями:
  • Cannot set allocations ошибка
  • Cannot run in this locale ошибка
  • Cannot resolve symbol string java ошибка
  • Cannot resolve symbol java intellij idea ошибка
  • Candy ошибка 303