Jest or Mocha with Vue: SyntaxError: Cannot use import statement outside a module - javascript

Edit: This post got out of hand with edits, please follow this link to a new Stackoverflow post which is clearer:
SyntaxError: Cannot use import statement outside a module when following vue-test-utils official tutorial
There are thousands of posts and threads about this issue and I still can't fix my problem.
I followed the "Getting started" portions of Jest AND Mocha and get the same error both times:
SyntaxError: Cannot use import statement outside a module but their provided link doesn't help at all.
Theres a new edit at the bottom with steps for a clean new project with jest for you to follow along which results in an error.
"vue-jest": "^3.0.7",
"vue": "^2.6.12",
"#vue/test-utils": "^1.2.2"
package.json
"mocha": "mocha 'tests/Frontend/**/*.test.js'"
example.test.js:
import { mount } from "#vue/test-utils"
import Dashboard from "../../resources/js/views/Dashboard";
import * as assert from "assert";
describe('test example', () => {
it('should work', () => {
assert.equal([1, 2, 3].indexOf(4), -1); // doesn't matter what I do here
})
})
What I've tried:
Using the --require #babel/register flag with mocha
Setting "transformIgnorePatterns": [] and thus allowing all node_modules to be considered
Adding a .babelrc file with the following content: This resulted in following error on building the app though:
Error: Multiple configuration files found. Please remove one:
- package.json
- C:\Users\f.marchi\workspace\projects\sanctum-test\.babelrc
{
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Can someone confirm, that those docs are missing some very important steps? I really don't know what I'm doing wrong, I'm just following the tutorials.
Edit: jest.config.js:
module.exports = {
clearMocks: true,
collectCoverage: true,
coverageDirectory: "coverage",
moduleFileExtensions: [
"js",
"json",
"vue"
],
transform: {
".*\\.(vue)$": "vue-jest"
},
transformIgnorePatterns: []
};
Edit:
I just tried again, you can follow along if you want:
vue create jest-test
npm install --save-dev jest #vue/test-utils vue-jest
Added jest config to package.json:
{
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
".*\\.(vue)$": "vue-jest"
}
}
}
npm install --save-dev babel-jest #babel/core #babel/preset-env babel-core#^7.0.0-bridge.0
Adjusted jest config to:
{
"jest": {
"transform": {
// process `*.js` files with `babel-jest`
".*\\.(js)$": "babel-jest" //<-- changed this
}
}
}
Adjusted babel config to:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset',
'#babel/preset-env' //<-- added this
]
};

You should use vue-cli API.
In your package.json add to scripts this:
"test:unit": "vue-cli-service test:unit"
You have vue-cli and test-utils installed so it should now work.

Related

Jest fails when rendering React component with 'No element indexed by'

I am attempting to get Jest working for my React Native project and have run into a variety of problems, the most confusing of which is the following:
When I run any test that renders a component, it spits out the error No element indexed by 7.
Here is the full stack trace:
FAIL __tests__/App-test.tsx
● Test suite failed to run
No element indexed by 7
at ArraySet_at [as at] (node_modules/source-map-support/node_modules/source-map/lib/array-set.js:109:9)
at BasicSourceMapConsumer.SourceMapConsumer_originalPositionFor [as originalPositionFor] (node_modules/source-map-support/node_modules/source-map/lib/source-map-consumer.js:673:30)
at mapSourcePosition (node_modules/source-map-support/source-map-support.js:244:42)
at wrapCallSite (node_modules/source-map-support/source-map-support.js:397:20)
at Function.prepareStackTrace (node_modules/source-map-support/source-map-support.js:446:39)
at Function.write (node_modules/#jest/console/build/BufferedConsole.js:101:7)
at console._log (node_modules/#jest/console/build/BufferedConsole.js:117:21)
at console.error (node_modules/#jest/console/build/BufferedConsole.js:161:10)
This same error occurs with any component I attempt to render.
Regarding this issue which purports to solve a similar problem, I have tried installing babel (npm install --save-dev babel-jest #babel/core #babel/preset-env) and setting "coverageProvider" in the jest config to "v8". With or without the v8 preset I am still getting the same errors. It's definitely possible that I configured something else wrong. Here are some code snippets which may be of use:
App-test.tsx
/**
* #format
*/
import 'react-native';
import React from 'react';
import App from '../App';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
it('renders correctly', () => {
renderer.create(<App />);
});
package.json
// ...
"jest": {
"preset": "react-native",
"coverageProvider": "babel",
"transformIgnorePatterns": [
"node_modules/(?!(react-native|#react-native|react-native-video|react-native-reanimated|#miblanchard/react-native-slider|react-native-gesture-handler)/)"
],
"transform": {
"^.+\\.[t|j]sx?$": "babel-jest"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
}
babel.config.js
module.exports = {
presets: [
'module:metro-react-native-babel-preset',
['#babel/preset-typescript', {allowDeclareFields: true}],
],
plugins: [
"react-native-reanimated/plugin",
],
};
As an additional note, I have tried adding #babel/preset-env to the list of babel presets, but this only resulted in a different error related to a separate package added to the transformIgnorePatterns list. Adding source-map-support to said list also solves nothing.
Edited to note that these tests fail regardless of whether or not the --coverage argument is applied
In the end, I solved my error by uninstalling node_modules, re-running npm install --save-dev babel-jest #babel/core #babel/preset-env and adding
"setupFiles": [
"./node_modules/react-native-gesture-handler/jestSetup.js",
// ...
]
to my package.json

Why Jest failing on node-fetch giving syntax error on import

I'm trying to understand how to fix the following error using Jest in my unit tests in NodeJS.
The test run with this command "test": "NODE_ENV=test jest spec/* -i --coverage --passWithNoTests",
I'm also using babel and this is my config
{
"presets": [["#babel/env", { "targets": { "node": "current" } }]],
"plugins": [
"#babel/plugin-syntax-dynamic-import",
["babel-plugin-inline-import", { "extensions": [".gql"] }],
["#babel/plugin-proposal-decorators", { "legacy": true }]
]
}
In package.json I have this
"jest": {
"verbose": true,
"collectCoverageFrom": [
"spec/**/*.js"
]
},
I tried several guides online but cannot find a solution to this
You've got Jest successfully configured to transform your code, but it is not transforming modules that you're importing—in this case node-fetch, which has the import keyword in its source code (as seen in your error). This is because, by default, Jest is configured not to transform files in node_modules:
transformIgnorePatterns [array]
Default: ["/node_modules/", "\.pnp\.[^\/]+$"]
An array of regexp pattern strings that are matched against all source file paths before transformation. If the file path matches any of the patterns, it will not be transformed.
You can set transformIgnorePatterns to exclude certain packages in node_modules with a jest.config.js like this:
const esModules = [
'node-fetch',
'data-uri-to-buffer',
'fetch-blob',
'formdata-polyfill',
].join('|');
module.exports = {
transformIgnorePatterns: [
`/node_modules/(?!${esModules})`,
'\\.pnp\\.[^\\/]+$',
],
};
(see https://github.com/nrwl/nx/issues/812#issuecomment-429420861)
If you have .babelrc try to rename it to babel.config.js
Source:
https://babeljs.io/docs/en/configuration#whats-your-use-case
but also this (there's more in the discussion)
Jest won't transform the module - SyntaxError: Cannot use import statement outside a module

SyntaxError: Cannot use import statement outside a module when following vue-test-utils official tutorial

I can't get vue testing to work with vue-test-utils and jest. I created a clean new project with vue cli and added jest as follows, maybe someone can follow along and tell me what I'm doing wrong. (I'm following this installation guide: https://vue-test-utils.vuejs.org/installation/#semantic-versioning)
vue create jest-test
1.1. npm install
npm install --save-dev jest #vue/test-utils vue-jest
Added jest config to package.json:
{
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
".*\\.(vue)$": "vue-jest"
}
}
}
npm install --save-dev babel-jest #babel/core #babel/preset-env babel-core#^7.0.0-bridge.0
Adjusted jest config to:
{
"jest": {
"transform": {
// process `*.js` files with `babel-jest`
".*\\.(js)$": "babel-jest" //<-- changed this
}
}
}
Adjusted babel config to:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset',
'#babel/preset-env' //<-- added this
]
};
Created example.test.js in a tests directory under the project root (jest-test/tests)
Added the following to this file:
import { mount } from '#vue/test-utils'
import HelloWorld from "#/components/HelloWorld";
test('displays message', () => {
const wrapper = mount(HelloWorld)
expect(wrapper.text()).toContain('Welcome to Your Vue.js App')
})
Added the following to the package.json scripts:
"jest": "jest"
npm run jest
Get the following error:
C:\Users\xxx\jest-test\tests\example.test.js:1
import { mount } from '#vue/test-utils'
^^^^^^
SyntaxError: Cannot use import statement outside a module
Same happens with Mocha or if I try it in an existing project. Is this a bug? I can't get it working, no matter what I do.
Edit: If I do it with Vue CLI, it works
https://vue-test-utils.vuejs.org/installation/#installation-with-vue-cli-recommended
You need to transform both *.vue files and *.js files.
I tried your setup and could reproduce the issue. But after altering jest.config.js to the following, the tests will run fine:
module.exports = {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
transform: {
'.*\\.js$':'babel-jest',
".*\\.(vue)$": "vue-jest"
},
moduleNameMapper: {
"#/(.*)": "<rootDir>/src/$1",
},
testEnvironment: 'jsdom'
}

Parsing Error The Keyword import is Reserved (SublimeLinter-contrib-eslint)

I have a problem with eslint, it gives me [Parsing Error The keyword import is reserve] this is only occur in sublime, in atom editor work well. I have eslint
.eslintrc.js
module.exports = {
"extends": "airbnb",
"plugins": [
"react"
]
};
package.json
{
"name": "paint",
"version": "0.0.0",
"description": "paint on the browser",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"paint",
"javascript"
],
"author": "",
"license": "ISC",
"devDependencies": {
"browserify": "^11.2.0",
"eslint": "^2.2.0",
"eslint-config-airbnb": "^2.1.1",
"eslint-plugin-react": "^3.11.2",
"gulp-babel": "^5.2.1",
"gulp-clean": "^0.3.1",
"gulp-stylus": "^2.2.0",
"vinyl-source-stream": "^1.1.0"
}
}
Add this to the root of your .eslintrc.json (formerly .eslintrc)
"parser": "babel-eslint"
and make sure to run:
npm install babel-eslint --save-dev
The eslint option that solves the "The keyword import is reserved" error is parserOptions.sourceType. Setting it to "module" allows the import keyword to be used.
.eslintrc
{
"parserOptions": {
"sourceType": "module"
}
}
Docs: https://eslint.org/docs/user-guide/configuring#specifying-parser-options
This is old answer - 2020 year
Not sure if this is still relevant as of now.
===
Spent 30 mins - trying all solutions but dint work, so sharing this one.
The issue is seen with new react app, and in Visual Studio Code, even at this time - Apr 2020.
Create a file .eslintrc.js in the root folder (beside package.json, or beside /src/ directory)
Paste below contents in .eslintrc.js
Restart your editor, like VS Code.
Now I can see real errors, instead of those fake import/export errors.
.eslintrc.js file contents:
module.exports = {
env: {
commonjs: true,
node: true,
browser: true,
es6: true,
jest: true,
},
extends: ["eslint:recommended", "plugin:react/recommended"],
globals: {},
parser: "babel-eslint",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: "module",
},
plugins: ["react", "import", "react-hooks"],
ignorePatterns: ["node_modules/"],
rules: {},
settings: {
react: {
version: "latest", // "detect" automatically picks the version you have installed.
},
},
};
Hope that helps.
The problem was i had installed eslint globally and locally, causing inconsistencies in SublimeLinter-contrib-eslint. I uninstalled eslint globally and SublimeLinter is working.
Closing VS code and re-open it does the trick for me...
Not sure about it but try to rename your file to .eslintrc and just use
{
"extends": "airbnb",
"plugins": ["react"]
};
Also be sure you have the required packages installed.
github.com/airbnb/javascript
The accepted answer works, however, is no longer under maintenance and the newly suggested approach is to use the version from the mono repo instead.
Installation
$ npm install eslint #babel/core #babel/eslint-parser --save-dev
# or
$ yarn add eslint #babel/core #babel/eslint-parser -D
.eslintrc.js
module.exports = {
parser: "#babel/eslint-parser",
};
Reference
i also got this error in a meteor project and i could solved it setting sourceType to "module"
more details can be found in Eslint docs:
http://eslint.org/docs/user-guide/configuring#specifying-parser-options
This config worked for me. (I am using create-react-app but applicable to any eslint project)
.eslintrc (create file in root if it doesnt exist)
{
"rules": {
"jsx-a11y/anchor-is-valid": [ "error", {
"components": [ "Link" ],
"specialLink": [ "to" ]
}]
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2015
}
}
The same issue occurred when creating js files within a typescript react-native project while eslint is enabled.
Changing the file type from js to ts resolved the issue.
Also, adding the .eslintrc.js file as mentioned in previous answers resolved the issue without changing the file type from js to ts.
module.exports = {
parser: "#babel/eslint-parser",
};
The issue is seen with the new react app, and in Visual Studio Code, even at this time - August 2022
Create a file .eslintrc.js in the root folder
Paste the below contents in .eslintrc.js
Restart your editor, like VS Code.
Now I can see real errors, instead of those fake import/export errors.
.eslintrc.js file contents:
export const parser = "#babel/eslint-parser";
The accepted answer works, however, the newly suggested approach is to use the version from ES6.
Adding ecmaVersion to .eslintrc.json fixed the issue
{
"ecmaVersion": 2015,
"extends": [
"eslint:recommended",
"plugin:react/recommended"
]
}
I found this issue while creating the vue project (Used Editor: Visual Code)
Install babel-eslint package
npm install babel-eslint
Create the .eslintrc.js file and add below code
module.exports = {
root: true,
parserOptions: {
'sourceType': 'module',
parser: 'babel-eslint'
}
}
npm run serve, that error will be resolved like magic.

How to use ESLint with Jest

I'm attempting to use the ESLint linter with the Jest testing framework.
Jest tests run with some globals like jest, which I'll need to tell the linter about; but the tricky thing is the directory structure, with Jest the tests are embedded with the source code in __tests__ folders, so the directory structure looks something like:
src
foo
foo.js
__tests__
fooTest.js
bar
bar.js
__tests__
barTest.js
Normally, I'd have all my tests under a single dir, and I could just add an .eslintrc file there to add the globals... but I certainly don't want to add a .eslintrc file to every single __test__ dir.
For now, I've just added the test globals to the global .eslintrc file, but since that means I could now reference jest in non-testing code, that doesn't seem like the "right" solution.
Is there a way to get eslint to apply rules based on some pattern based on the directory name, or something like that?
The docs show you are now able to add:
"env": {
"jest/globals": true
}
To your .eslintrc which will add all the jest related things to your environment, eliminating the linter errors/warnings.
You may need to include plugins: ["jest"] to your esconfig, and add the eslint-plugin-jest plugin if it still isn't working.
ESLint supports this as of version >= 4:
/*
.eslintrc.js
*/
const ERROR = 2;
const WARN = 1;
module.exports = {
extends: "eslint:recommended",
env: {
es6: true
},
overrides: [
{
files: [
"**/*.test.js"
],
env: {
jest: true // now **/*.test.js files' env has both es6 *and* jest
},
// Can't extend in overrides: https://github.com/eslint/eslint/issues/8813
// "extends": ["plugin:jest/recommended"]
plugins: ["jest"],
rules: {
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error"
}
}
],
};
Here is a workaround (from another answer on here, vote it up!) for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
You can also set the test env in your test file as follows:
/* eslint-env jest */
describe(() => {
/* ... */
})
To complete Zachary's answer, here is a workaround for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
As of 2021, I think the correct way or at least the one that works is to install #types/jest and eslint-plugin-jest:
npm i -D eslint-plugin-jest #types/jest
And adding the Jest plugin into .eslintrc.js with the overrides instruction mentioned by #Loren:
module.exports = {
...
plugins: ["jest"],
...
overrides: [
{
files: ["**/*.test.js"],
env: { "jest/globals": true },
plugins: ["jest"],
extends: ["plugin:jest/recommended"],
},
],
...
};
This way you get linting errors in your source files as well as in test files, but in test files you don't get linting errors for test and other Jest's functions, but you will get them in your source files as they will appear as undefined there.
I solved the problem REF
Run
# For Yarn
yarn add eslint-plugin-jest -D
# For NPM
npm i eslint-plugin-jest -D
And then add in your .eslintrc file
{
"extends": ["airbnb","plugin:jest/recommended"],
}
some of the answers assume you have eslint-plugin-jest installed, however without needing to do that, you can simply do this in your .eslintrc file, add:
"globals": {
"jest": true,
}
First install eslint-plugin-jest
Running:
yarn add eslint-plugin-jest or npm install eslint-plugin-jest
Then edit .eslintrc.json
{
"env":{
"jest": true
}
}
As of ESLint V 6 (released in late 2019), you can use extends in the glob based config as follows:
"overrides": [
{
"files": ["*.test.js"],
"env": {
"jest": true
},
"plugins": ["jest"],
"extends": ["plugin:jest/recommended"]
}
]
Add environment only for __tests__ folder
You could add a .eslintrc.yml file in your __tests__ folders, that extends you basic configuration:
extends: <relative_path to .eslintrc>
env:
jest: true
If you have only one __tests__folder, this solution is the best since it scope jest environment only where it is needed.
Dealing with many test folders
If you have more test folders (OPs case), I'd still suggest to add those files. And if you have tons of those folders can add them with a simple zsh script:
#!/usr/bin/env zsh
for folder in **/__tests__/ ;do
count=$(($(tr -cd '/' <<< $folder | wc -c)))
echo $folder : $count
cat <<EOF > $folder.eslintrc.yml
extends: $(printf '../%.0s' {1..$count}).eslintrc
env:
jest: true
EOF
done
This script will look for __tests__ folders and add a .eslintrc.yml file with to configuration shown above. This script has to be launched within the folder containing your parent .eslintrc.
Pattern based configs are scheduled for 2.0.0 release of ESLint. For now, however, you will have to create two separate tasks (as mentioned in the comments). One for tests and one for the rest of the code and run both of them, while providing different .eslintrc files.
P.S. There's a jest environment coming in the next release of ESLint, it will register all of the necessary globals.
I got it running after spending some time trying out different options. Hope this helps anyone else getting stuck.
.eslintrc.json (in root project folder):
{
"env": {
"browser": true,
"es2021": true,
"jest/globals": true
},
"extends": [
"standard",
"plugin:jest/all"
],
"parser": "#babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"jest/no-hooks": [
"error",
{
"allow": [
"afterEach",
"beforeEach"
]
}
]
},
"plugins": [
"jest"
]
}
Empty .babelrc (in root project folder):
{}
.package.json (in root project folder):
{
"scripts": {
"test": "jest",
"lint": "npx eslint --format=table .",
"lintfix": "npx eslint --fix ."
},
"devDependencies": {
"#babel/core": "^7.15.0",
"#babel/eslint-parser": "^7.15.0",
"aws-sdk-mock": "^5.2.1",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.24.0",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"jest": "^27.0.6"
}
}
VS Code settings.xml (editor configuration: enables auto fix on save + babel parser):
"eslint.alwaysShowStatus": true,
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"eslint.options": {
"parser": "#babel/eslint-parser"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript"
]
In your .eslintignore file add the following value:
**/__tests__/
This should ignore all instances of the __tests__ directory and their children.

Categories