Resolving "Cannot use import statement outside a module" with Axios in Jest Tests
Problem Statement
When testing Vue.js applications with Jest, importing Axios (v1.0.0 or newer) can trigger the error: Cannot use import statement outside a module
. This occurs because:
- Axios switched to ECMAScript Modules (ESM) in version 1.x.x
- Jest runs in a Node.js environment that expects CommonJS modules
- Test runners ignore
node_modules
during transformation by default - The issue manifests when tests try to load Axios's ESM files in a CommonJS environment
The problem often appears when upgrading Axios or configuring tests in projects using Vue CLI, React, or similar frameworks.
Root Cause Analysis
Axios 1.x.x changed its module type from CommonJS to ECMAScript modules:
Axios 0.x.x (CommonJS):
module.exports = require('./lib/axios');
Axios 1.x.x (ESM):
import axios from './lib/axios.js';
export default axios;
Jest runs in a Node.js environment that uses CommonJS modules. Since Jest doesn't transform node_modules
by default, it fails to parse the ESM syntax in Axios.
Recommended Solutions
1. Configure Jest to Transform Axios (Preferred Solution)
Force Jest to transform Axios modules despite their location in node_modules
:
In jest.config.js
:
module.exports = {
transformIgnorePatterns: ["/node_modules/(?!axios)/"]
};
In package.json
:
{
"jest": {
"transformIgnorePatterns": ["/node_modules/(?!axios)/"]
}
}
Explanation:
This regex tells Jest to include Axios when transforming modules while excluding others. The pattern node_modules/(?!axios)
means: "Ignore all modules in node_modules
except those in axios
."
Why This Works
Jest typically ignores node_modules
during transformation. This override ensures Axios gets transpiled to CommonJS format before execution.
2. Use Axios's CommonJS Bundle Directly
Point module resolution to Axios's CommonJS build:
In jest.config.js
:
module.exports = {
moduleNameMapper: {
"^axios$": "axios/dist/node/axios.cjs"
}
};
In package.json
:
{
"jest": {
"moduleNameMapper": {
"^axios$": "axios/dist/node/axios.cjs"
}
}
}
Mock Compatibility
If you use libraries like axios-mock-adapter
, this approach might cause compatibility issues. Use Solution 1 instead if you encounter mocking problems.
3. Update Test Script in package.json
For Create React App projects, modify the test command directly:
{
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\""
}
}
4. Clear Jest Cache (Troubleshooting Step)
If configuration changes don't take effect:
npm test -- --clearCache
Additional Considerations
Solution Comparison
Approach | Best For | Notes |
---|---|---|
transformIgnorePatterns | Most projects | Compatible with mocking libraries |
moduleNameMapper | Simple setups | May break axios-mock-adapter |
Script modification | Create React App | Temporary solution |
When Using Mocking Libraries
If you work with axios-mock-adapter
, prefer Solution 1 to avoid mock.onGet is not a function
errors:
{
"jest": {
"transformIgnorePatterns": ["/node_modules/(?!(axios|your-other-lib)/)"]
}
}
Jest Version Compatibility
Ensure you're using compatible Jest and ts-jest versions (if using TypeScript):
{
"devDependencies": {
"jest": "^29.0.0",
"ts-jest": "^29.0.0"
}
}
Avoid Anti-Patterns
- Don't use ESM config files (
vue.config.js
→vue.config.cjs
) as this often creates new errors - Don't switch to
require
syntax - Axios internals still use ESM - Avoid replacing Axios with Fetch - this circumvents the actual issue
Conclusion
The most reliable solutions are:
Enable transformation for Axios using
transformIgnorePatterns
(Best for most projects, maintains full functionality)Directly import CommonJS bundle via
moduleNameMapper
(Simpler setup but may break mocking libraries)
For most Vue.js and React projects, adding transformIgnorePatterns
to your Jest configuration resolves this issue while maintaining compatibility with testing utilities and libraries.