The error message “Cannot use import statement outside a module” occurs when the import
keyword is encountered in an improperly configured JavaScript or TypeScript module.
In a JavaScript server-side runtime environment, this error usually results from the use of import
syntax for modules written in ECMAScript (ES) when Node.js is expecting the require
keyword used by CommonJS module system.
TypeScript supports different module formats, but coding errors that confuse the ES and CommonJS approaches to importing modules also result in this error.
On the browser side, the error typically occurs when you don’t use a bundler for your JavaScript code files.
This article explores these three error sources and details a solution for each environment.
How to resolve the error in server-side JavaScript
This section demonstrates how to solve the error in server-side JavaScript environments.
Background
Node.js uses the CommonJS system’s require
keyword by default. Therefore, you’ll receive the familiar error unless you configure Node.js to support ES module syntax. Similarly, Node.js requires the .mjs extension to recognize and work with ES modules.
Solution
As an alternative to using .mjs, you can make older versions of Node.js compatible with the current ES module by using bundlers or running Node.js with the --experimental-modules
flag. Otherwise, you could set the type
field in the package.json file to module
as follows:
{
"name": "test-package",
"version": "1.0.0",
"type": "module",
"main": "app.js",
"dependencies": { }
}
(Note: You should include the type
property in the package.json file in all packages. This practice makes it easier to identify the module system in use and ensure consistency among your libraries.)
Another way to avoid the error is to ensure that the import
and export
syntaxes are correct and load properly. It’s critical to always use relative file paths, named exports, file extensions for exports, and avoid default exports.
Here’s an example:
//module import
import { sampleFunction } from './sampleModule.js';
// function export
export function sampleFunction() {
// code goes here
}
Finally, you should ensure the compatibility of all third-party libraries with ES modules. For this information, refer to the library documentation for the package.json file. Alternatively, use a bundler to transpile the code so a JavaScript environment can understand it.
How to resolve the error in TypeScript environments
This section demonstrates how to solve the error message in TypeScript environments.
Background
With modules, you can reuse, organize, and share code among multiple files in a project. ES supports external modules for sharing code among various files using the import
and export
keywords.
This error usually occurs in TypeScript environments when using the ES module syntax without configuring TypeScript to use it. Since TypeScript is a superset of JavaScript, it defaults to using CommonJS syntax for imports, which uses require
instead of import
. In this case, the import
statement causes the error. Nevertheless, correctly configuring TypeScript is necessary for it to support ES modules.
You might also encounter this error if you use the incorrect file extension. For instance, when using TypeScript in a Node.js environment with ES module syntax, the module you want to import must have the .mjs file extension instead of the regular .js.
Another common source of the error is the improper configuration of the module
field in your tsconfig.json or package.json files when using bundlers like Webpack. H
owever, you can use bundlers for ES modules in TypeScript by setting the module
and target
fields in the tsconfig.json file to ECMAScript
. Then, Webpack will understand the target environment and use the correct file extensions when transpiling the code.
Solution
To load ES modules using a module loader like RequireJS or a bundler like Webpack, make the following additions to the tsconfig.json file:
{
"compilerOptions": {
"module": "es20215",
"target": "es20215",
"sourceMap": true
}
}
In the compilerOptions
portion of the code above, the module
and target
fields are set to use an es20215
module. With these additions, you can use the import
and export
statements in a TypeScript environment without causing the error.
As TypeScript uses CommonJS by default, failing to modify the tsconfig.json file accordingly will result in the error message.
Fortunately, once you’ve set the module
and target
fields to use an ECMAScript
module, you can use the export
statement to export a function or variable from a module and the import
statement to load another module into the current one’s scope. This process occurs in the code below:
// sum.ts
export function sum(a: number, b: number, c: number): number {
return a + b + c;
}
// main.ts
import { sum } from './sum';
console.log(add(4, 4, 9));
If you’re using an older version of Node.js, you can enable ES module support by running your code with the --experimental-modules
flag. You should also use a bundler like Webpack, Browserify, or Rollup to bundle all the ES code and output it to a single file. Ensure that it’s in a version that browsers and old Node.js versions can understand and set up a Webpack.config.js file in the root of your project that specifies the module type.
Here’s an example extracted from the Webpack documentation:
module.exports = {
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
extensions: ['.ts', '.js', '.mjs']
},
module: {
rules: [
{
test: /.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
experiments: {
outputModule: true
}
};
The compiled code is output to a bundle.js file in the dist directory of the project’s root directory.
You can also use polyfills like es-module-shims
to target older browsers that don’t support ES modules’ import
and export
statements.
How to resolve the error in browser-side JavaScript
This section shows you how to solve the error in browser-side JavaScript environments.
Background
Most modern browsers, including Chrome, Firefox, Edge, and Safari, support ES modules, so you won’t need to use browser polyfills, bundlers, or transpilers.
You also don’t need them if you use the React or Vue JavaScript-based frontend libraries because they support the ES imports
and exports
fields by default. However, older browsers don’t support ES syntax, so they require these tools for cross-platform compatibility.
The most prevalent reason for the error in an older browser is when a page’s HTML files do not contain the type="module"
attribute. In this scenario, the error occurs because JavaScript running on the web doesn’t include default support for ES module syntax. For JavaScript code sent across the wire, you might encounter a cross-origin resource-sharing error when attempting to load an ES module from a different domain.
Solution
To prevent the module error in an older browser, ensure that you’re using the correct script
tag attribute — type="module"
— in the root HTML file. Alternatively, you can use Webpack to transpile the code so that older browsers can understand it.
To use the type="module"
attribute, include the following line in your root HTML file:
<script type="module" src="app.js"></script>
It’s equally critical to ensure the import
file paths are valid and that you’re using the correct import
syntax.
Additionally, you can visit sites like Can I Use to confirm browser compatibility for ES modules.
Finally, since using the .js file extension is common practice, you can set the type
attribute in the module’s HTML file script
tag as a workaround. Setting this attribute to module
tells the browser to disregard the .js extension and treat the file as a module.
Summary
The “Cannot use import statement outside a module” error may appear for various reasons, depending on whether you’re in a browser-side or server-side JavaScript environment. Incorrect syntax, improper configurations, and unsupported file extensions remain a few of the most common sources of this error.
While most modern browsers support ES modules, you must ensure that older browsers are compatible. Bundlers like Webpack allow you to compile all source code with their dependencies to a single output that older browsers can understand.
Remember to add the type="module"
attribute in the HTML file to inform the browser that the module is an ES module. Finally, while using the .js extension for CommonJS is the default practice, you can use the .mjs extension to enable importing ES modules.
Do you have a JavaScript application you need to get online but don’t want to manage the servers yourself? Kinsta’s Application Hosting and Database Hosting platforms could be the answer. You might even combine those services with Kinsta’s Static Site Hosting to have the front end of your application served up for free.