How To Solve Uncaught SyntaxError: Cannot use import statement outside a module when importing ECMAScript 6 – Definitive Guide

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

After you include "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

Leave a Comment