Node.js supports ECMAScript modules to package reusable JavaScript codes. Modules are defined using multiple import
and export
statements.
You can include type="module"
attribute in your script tag to solve Uncaught SyntaxError: Cannot use import statement outside a module when importing ECMAScript 6.
Include type=’module’ inside script tag
You need to explicitly inform the browser about using the Javascript modules in your code.
Cause of Error
The error occurs when you work with ECMAScript modules; it is required to inform the browser or ECMAScript modules loader about module usage.
If meta information is not conveyed, it will end up in Uncaught SyntaxError: Cannot use import statement outside a module when importing ECMAScript 6.
Solution
You need to include information(type=" module"
) in the your script to make browser understand about the usage of modules.
Code
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="main.js"></script>
<title>html form</title>
</head>
<body>
<div class="subscribe-container">
<h1> Welcome To <b>TechMam</b></h1>
<h2> Happy Learning!!!</h2>
</div>
</body>
</html>
//main.js
import { getWelcomeText, message } from "./utils.js";
const welcomeText = getWelcomeText(message);
console.log(welcomeText);
//utils.js
export function getWelcomeText(name) {
return `Welcome to ${name}`;
}
export const message = "TechMam, ES6 Tutorial";
Below, Node.js code(index.js) is used to create a server for running ES6 module code.
//index.js
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.URL);
const __dirname = dirname(__filename);
const app = express();
app.use(express.static(__dirname));
app.get('/',function(request,response){
response.sendFile(__dirname + "/index.html");
});
app.listen(3000);
node index.js
Output
Uncaught SyntaxError: Cannot use import statement outside a module (at main.js:1:1)
You can see the above error in your browser console.
Include type =’module’ attribute in your script tag to make ECMAScript modules loader to handle the JS Modules.
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="main.js" type="module"></script>
<title>html form</title>
</head>
<body>
<div class="subscribe-container">
<h1> Welcome To <b>TechMam</b></h1>
<h2> Happy Learning!!!</h2>
</div>
</body>
</html>
Output
Welcome to TechMam, ES6 Tutorial
Include type:’module’ in package.json
In Node.js, When importing ECMAScript 6 modules, the author has to tell node.js to use the ECMAScript modules loader using the type
attribute in the package.json
.
If the configuration denotes ECMAScript 6 module usage, you will encounter SyntaxError: Cannot use import statement outside a module.
Code
//package.json
{
"name": "TechMam",
"version": "1.0.0",
"description": "TechMam Tutorials",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "sv"
}
//index.js
import * as os from 'os';
console.log("total free memory : ",os.freemem());
node .\index.js
Output
import * as os from 'os';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Code
//package.json
{
"name": "TechMam",
"version": "1.0.0",
"description": "TechMam Tutorials",
"main": "index.js",
"type" : "module",
"scripts": {
"start": "node index.js"
},
"author": "sv"
}
//index.js
import * as os from 'os';
console.log("total free memory : ",os.freemem());
Output
node .\index.js
total free memory : 1066844160
"type" : "module"
in your package.json then require('moduleName')
cant be used to include import modules inside your application.
If you try to use require()
after converting your application to ES6 format, you will get the below error,
const express = require('express');
^
ReferenceError: require is not defined in ES module scope; you can use import instead.
This file is being treated as an ES module because it has a '.js' file extension and 'C:\Node\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///C:/Node/index.js:5:17
at ModuleJob.run (node:internal/modules/ESM/module_job:185:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/ESM/loader:281:24)
at async loadESM (node:internal/process/esm_loader:88:5)
at async handleMainPromise (node:internal/modules/run_main:65:12)
Update ‘.js’ files extension to ‘.mjs’
You can also update the file extension( '.js' -> '.mjs'
) to Solve the Uncaught SyntaxError: Cannot use import statement outside a module” when importing ECMAScript 6.
Code
//index.js
import * as os from 'os';
console.log("total free memory : ",os.freemem());
node .\index.js
Output
import * as os from 'os';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Just updating the file extension like below can resolve the issue,
//index.mjs
import * as os from 'os';
console.log("total free memory : ",os.freemem());
node .\index.mjs
Output
node .\index.mjs
total free memory : 1500504064
If you use this file extension option, you are not required to include the type
attribute in the package.json
.
Also, using file extension, you can build a library that supports both import
and require
, allowing us to solve the incompatibility issues.
Pass Input Type Field as an argument
You can include flag --input-type=module
to the Strings passed in as an argument to –eval or –print or piped to node
via STDIN
.
Code
node --eval "import * as os from 'os';console.log('total free memory : ',os.freemem());"
Output
import * as os from 'os';console.log('total free memory : ',os.freemem());
^^^^^^
SyntaxError: Cannot use import statement outside a module
at new Script (node:vm:100:7)
at createScript (node:vm:257:10)
at Object.runInThisContext (node:vm:305:10)
at node:internal/process/execution:81:19
at [eval]-wrapper:6:22
at evalScript (node:internal/process/execution:80:60)
at node:internal/main/eval_string:27:3
You can include flag --input-type=module
to the String passed to use the ECMAScript modules loader.
Code
node --input-type=module --eval "import * as os from 'os';console.log('total free memory : ',os.freemem());"
Output
total free memory : 1446035456
Let us see another example for printing the output of a String passed as an argument.
Code
echo "import * as os from 'os';console.log('total free memory : ',os.freemem());" | node --input-type=module
Output
total free memory : 1446035456
Related Topics
- How To Fix npm ERR! Missing script: “start.” – Definitive Guide
- How To Fix npm WARN config global –global, –local are deprecated. Use –location=global instead – Detailed Guide
- How to solve npm error “npm ERR! code ELIFECYCLE” – Definitive Guide
- How To Solve Cannot find module error using Node.js – Definitive Guide