Search code examples
javascriptnode.jsnode-modulespm2

Node Error: Cannot use import statement outside a module even though I'm not


I am using Pm2 and this is the error:

SyntaxError: Cannot use import statement outside a module

Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

The issue is, the package.json is already set to "type": "module".

Also, everything used to work fine until I restart the server.

Here is the actual .js file:

const http = require('http');
const url = require('url');
const querystring = require('querystring');
    
const hostname = 'localhost';
const port = 8080;
    
import captureWebsite from 'capture-website';


const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
    
    ....
});

Solution

  • If the require calls are not throwing an error, the "actual .js file" creating the http server in the post is being treated as CommonJS. But CommonJS code can't use import statements and needs to use import expressions instead (see node and MDN docs).

    If you use dynamic imports ( which are asynchronous) you would also need to use the imported module after an await statement (inside an async function), or in a success handler provided in a then method:

    // ....
    
    import('capture_website')
    .then( capture_website => {
          // code requiring existence of `capture_website`
     })
    .catch( err=> console.error("Import of capture_website failed", err));
    

    However you can import CommonJS modules using an import statement in ES6 files (Node doc).

    Hence a better solution may be to rename the main js file posted to give it a .mjs extension, and replace all the require statements in the file with import statements:

    import http from 'http';
    import url from 'url';
    import querystring from 'querystring';
    

    This gets rid of the Cannot use import statement outside a module syntax error. Imported modules that are CommonJS should still be able to require modules using the require function.