Jest and Create-react-app: Cannot use import statement outside a module - javascript

I have a React Native application where I have some files with some methods that calls certain endpoints. When I try to run Jest is throwing me an error at a local file that is imported.
I have the next package.json:
{
"name": "appName",
"version": "1.0.0",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"#babel/core": "^7.14.2",
"#react-native-community/async-storage": "^1.12.1",
"#react-native-community/netinfo": "^6.0.0",
"isomorphic-fetch": "^3.0.0",
"jest": "^26.6.3",
"jest-fetch-mock": "^3.0.3"
},
"jest": {
"automock": false,
"setupFiles": [
"./jest.setup.js"
]
}
}
And the jest.setup.js file is the following:
import mockRNCNetInfo from '#react-native-community/netinfo/jest/netinfo-mock.js'
jest.mock('#react-native-community/netinfo', () => mockRNCNetInfo)
For the moment, this content is commented, otherwise will throw the same error like in the picture.
I tried to test the same stuff in another project where this #react-native-community/netinfo package wasn't saved in devDependencies but in dependencies and it worked but I am not sure if this is the problem. In this specific project I can't let this package as a dependency, it should be in devDependencies.
I found a lot of issues on this but none of them worked on this case, I don't know what to do anymore. Thank you for your time!

I got this error when I was creating tests with Create-react-app Typescript Jest Axios. Perhaps the following entry in package.json might help.
"jest": {
"transform": {
"^.+\\.[t|j]sx?$": "babel-jest"
},
{ "transformIgnorePatterns": [
"node_modules/(?!#shotgunjed)/"
]
},

I found this answer on internet and it worked for me with some small add-ons but I will post it here maybe will help someone in future:
install babel-jest, babel-preset-env, #babel/runtime and react (the last one might be possible to be necessary only if some other package requires it)
create .babelrc file in root directory and add:
{
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Run your code and should be good to go

Related

Babel-loader not transpiling JSX component. ModuleParseError

I'm trying to build a standalone component as a package. I'm using webpack to transpile all the CSS and JS/JSX files into JS. I'm able to build the package and pack it into a .tgz file using npm pack. However, when I install the package in another project and try using the component from the installed package. I'm getting this error:
ModuleParseError: Module parse failed: Unexpected token (34:8)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
And, in the terminal of the running project, I get this:
error - SyntaxError: Cannot use import statement outside a module
webpack.config.js
const path = require('path')
module.exports = {
mode:'production',
entry:'./src/components/StandaloneComponent.js',
output:{
path:path.join(__dirname,'dist'),
filename:'StandaloneComponent.js',
libraryTarget:"commonjs2"
},
module:{
rules:[
{
test:/\.js|jsx$/,
exclude:/(node_modules)/,
use:'babel-loader'
},
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
}
]
},
resolve:{
alias:{
'react':path.resolve(__dirname,'./node_modules/react'),
'react-dom':path.resolve(__dirname,'./node_modules/react-dom'),
'next':path.resolve(__dirname,'./node_modules/next')
}
},
externals:{
react:{
commonjs:"react",
commonjs2:"react",
amd:"React",
root:"React"
},
"react-dom":{
commonjs:"react-dom",
commonjs2:"react-dom",
amd:"ReactDOM",
root:"ReactDOM"
},
next:{
commonjs:"next",
commonjs2:"next",
amd:"Next",
root:"Next"
}
}
}
package.json
{
"name": "testcomponent",
"version": "1.0.3",
"description": "A lightweight and easy to use package.",
"main": "./src/components/StandaloneComponent.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [
"NextJS",
"react"
],
"peerDependencies": {
"next": "^12.0.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"prop-types": "^15.7.2"
},
"devDependencies": {
"#babel/core": "^7.16.0",
"#babel/preset-env": "^7.16.4",
"#babel/preset-react": "^7.16.0",
"#babel/preset-stage-0": "^7.8.3",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"next": "^12.0.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"style-loader": "^3.3.1",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1"
}
}
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
I further installed this package in another project like this:
npm install path/to/tgz/testcomponent-1.0.3.tgz
And then imported the component as:
import StandaloneComponent from 'testcomponent'
As a possible workaround, I tried changing the extension of the component file from .js to .jsx and rebuilt the .tgz, but got the same result.
Looking at the error, I feel that babel-loader is unable to convert JSX into JS, which further is causing the import error, but I'm not entirely sure about it.
What could be causing this error?
Any help is appreciated.
Thanks.
The regex rule that you are using to load the JS and JSX file i.e. test:/\.js|jsx$/ seems incorrect in this case. You can fix it in following two ways:
Using capture groups: So when using or you need to capture the both the character sets as /\.(js|jsx)$/. This will consider both js and jsx extension. The earlier version just doesnt match the regex properly because of missing character set.
Using ? occurrence: You can also modify your regex to use the x as an zero or one occurrence using ? matcher. So the other option will be /\.jsx?$/
I believe you need to include the package you installed under include otherwise it looks like Webpack is configured to ignore your node_modules folder:
exclude: /(node_modules)/,
So make sure to let Webpack know what folders in node_modules that you do want to compile
include: [
path.resolve(__dirname, 'node_modules/testcomponent'
]

Unable to run JEST test

I'm facing an issue when I try to import something using require() function in jest test file.
script2.test.js
const fetch = require('node-fetch');
it('test function', () => {
expect(4).toEqual(4);
});
Package.json
{
"name": "jest-test",
"version": "1.0.0",
"description": "",
"type": "module",
"scripts": {
"test": "jest --watchAll"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/cli": "^7.15.7",
"#babel/core": "^7.15.8",
"#babel/plugin-transform-async-to-generator": "^7.14.5",
"#babel/preset-env": "^7.15.8",
"jest": "^27.3.1"
},
"dependencies": {
"node-fetch": "^3.0.0"
},
"jest": {
"transform": {
"^.+\\.(js|jsx)$": "babel-jest"
}
}
}
babel.config.cjs
module.exports = {presets: ['#babel/preset-env']}
I'm getting following errors when I run the test using npm test
FAIL ./script2.test.js
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
Details:
C:\work\jest-udemy\node_modules\node-fetch\src\index.js:9
import http from 'http';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | const fetch = require('node-fetch');
| ^
I'm new to JEST, any help is much appreciated.
My Node version is 14.17.3
Thanks you.
It seems that one still needs to jump through the hoops to make jest work with ESM.
In package.json change your script to:
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll"
And in script2.test.js use import:
import fetch from 'node-fetch';
P.S. This was tested with node 14.15.1

Duplicate ReactJS import issue when using npm link to test component before publishing as npm package

I have a simple component like this.
import React, {useState} from 'react';
function MyComponentWithState(props) {
const [value, setValue] = useState(0);
return (
<p>My value is: {value}</p>
)
}
export default MyComponentWithState;
and I want to publish it on NPM as a separate package. so, to do that I prepared package.json and webpack.config.js like below.
package.json:
{
"name": "try-to-publish",
"version": "0.0.1",
"description": "Just a test",
"main": "build/index.js",
"scripts": {
"start": "webpack --watch",
"build": "webpack"
},
"author": {
"name": "Behnam Azimi"
},
"license": "ISC",
"peerDependencies": {
"react": "16.9.0",
"react-dom": "16.9.0"
},
"dependencies": {
"react": "16.9.0",
"react-dom": "16.9.0",
"prop-types": "15.7.2",
"react-scripts": "3.1.1",
"webpack": "4.39.3"
},
"devDependencies": {
"#babel/core": "7.6.0",
"#babel/plugin-proposal-class-properties": "7.5.5",
"#babel/preset-env": "7.6.0",
"#babel/preset-react": "7.0.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-plugin-transform-react-jsx": "6.24.1",
"css-loader": "3.2.0",
"node-sass": "4.12.0",
"sass-loader": "8.0.0",
"style-loader": "1.0.0",
"webpack-cli": "3.3.8",
"webpack-external-react": "^1.1.2"
}
}
webpack.config.json:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.resolve(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
]
},
resolve: {
alias: {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
}
},
externals: {
'react': "commonjs react",
'react-dom': "commonjs react-dom"
},
};
and here is my .babelrc:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": ["#babel/plugin-proposal-class-properties"]
}
These configs work like charm when I publish my component to NPM and install it in my another ReactJs project with `npm install , but my point is the local test!
I want to test this component/lib before publish. To do this I use npm link feature to link my component with my main ReactJS project.
As you saw above, my component is functional and I used hooks too. So when I inject the locally linked lib to my main ReactJs project face this error,
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
My issue is related to the 3td reason. My project uses ReactJs and import it once and also my component will import React! I mean twice React import in one project!.
I also have externals config about react and react-dom in my Webpack config.
What should I do to solve that? Where is my mistake?
Update:
I also tried what #sung-m-kim and #eddie-cooro say but it not worked! Mean, I change the package.json and removed react and react-dom from dependencies and add them to devDpendencies.
I finally solved this problem by these steps.
run npm link inside
<your-library-package>/node_modules/react
also
run npm link inside
<your-library-package>/node_modules/react-dom
then run npm link react and npm link react-dom inside your application root directory
and dont forget to keep react and react-dom as externals in the library
// webpack.config.js
const externals = {
"react": "react",
"react-dom": "react-dom",
}
module.exports = {
.
.
.
externals
}
I solved my issue. I used RollupJS instead of Webpack for bundling as bundle tool.
Here is my rollup.config.js:
import {uglify} from 'rollup-plugin-uglify'
import babel from 'rollup-plugin-babel'
export default {
input: "./src/index.js",
external: ['react', 'react-dom'],
output: {
name: 'test-lib',
format: "cjs",
},
plugins: [
babel({
exclude: "node_modules/**"
}),
uglify(),
],
};
and my package.json:
{
"name": "test-lib",
"version": "1.0.0",
"main": "dist/test-lib.min.js",
"scripts": {
"build": "rollup -c -o dist/test-lib.min.js"
},
"author": "Behnam Azimi",
"license": "ISC",
"peerDependencies": {
"react": "^16.9.0",
"react-dom": "^16.9.0"
},
"devDependencies": {
"#babel/core": "^7.6.0",
"#babel/preset-env": "^7.6.0",
"#babel/preset-react": "^7.0.0",
"rollup": "^1.21.4",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-uglify": "^6.0.3"
}
}
After these changes, npm link worked truly in my ReactJS (Hooks) project.
Notice that it's just a simple Rollup config to show my solution and you can add many kinds of stuff like hot reloading, styles loaders, and many other plugins to the config.
Set the react and react-native packages only inside of the peerDependencies part of package.json, not the dependencies. Also for local development (When your package is not included in any other react projects and you want to to run it locally), you can use the devDependencies field.
I resolve this problem in a typescript react project.
probably, when use the npm link use the react from main app project and the component project.
So, in your package.json remove react from dependencies and/or devDependencies
Check the answer: https://stackoverflow.com/a/62807950/5183591

Trouble importing custom library from a repository into an Ember project as a dependency

I am developing a WebGL library that I would like to import into an EmberJS project as a dependency. Unless I'm mistaken, I believe that I can do this via the repository directly without having to make an npm package but I am having trouble getting it to work.
I have made a watered down library and ember project in a couple repos here and here respectively to demonstrate my problem.
If you clone the library and run npm run build it'll make a test bundle which can be called by the test html file packageTest.html. It should print out 'Hello World Test Member is: 5'.
In the Ember project I have a component in which I would like to import the 'HelloWorld' class from the library and call one of its member methods.
import Ember from 'ember';
//import HelloWorld from 'npm-package-test';
export default Ember.Component.extend({
isWide: false,
actions: {
toggleImageSize() {
// var h = new HelloWorld();
// console.log(h.print());
this.toggleProperty('isWide');
}
}
});
When I uncomment the import statement I get the console error
Error: Could not find module 'npm-package-test'
I'm still pretty new to npm packaging and how dependencies work (and know next to nothing about Ember) but from my limited understanding I feel like this method should work the way I currently have it.
For the library, I have the source files being babeled into ES5 in its lib folder. As you can see in the package.json for the library below I have the main set to the index file in the lib folder so that the Ember project can pull the babeled modules.
Library: package.json
{
"name": "npm-package-test",
"version": "1.0.0",
"description": "JibJab Render Library for eCards",
"main": "lib/index.js",
"scripts": {
"prepublishOnly": "npm run build",
"build-test": "browserify test.js > demo/testbundle.js",
"build": "babel ./src -d ./lib && npm run build-test",
"lint": "eslint ./src",
"test": "nyc mocha --require babel-core/register"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nhoughto5/NPM_PackageTest.git"
},
"author": "JibJab",
"license": "ISC",
"bugs": {
"url": "https://github.com/nhoughto5/NPM_PackageTest/issues"
},
"homepage": "https://github.com/nhoughto5/NPM_PackageTeste#readme",
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"eslint": "4.19.0",
"mocha": "5.0.4",
"nyc": "11.6.0"
},
"nyc": {
"reporter": [
"lcov",
"text"
]
},
"dependencies": {
"domready": "^1.0.8"
}
}
For reference, here is the lib/index.js which should be the entry point of my library:
Library: lib/index.js
'use strict';
module.exports = {
TestClass: require('./TestClass'),
HelloWorld: require('./HelloWorld')
};
In the ember project I have the library repository listed as a dependency:
Ember: package.json
{
"name": "test-ember-app",
"version": "0.0.0",
"description": "Small description for test-ember-app goes here",
"license": "MIT",
"author": "",
"directories": {
"doc": "doc",
"test": "tests"
},
"repository": "",
"scripts": {
"build": "ember build",
"start": "ember server",
"test": "ember test"
},
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-browserify": "1.2.1",
"ember-cli": "2.13.1",
"ember-cli-app-version": "^3.0.0",
"ember-cli-babel": "^6.0.0",
"ember-cli-dependency-checker": "^1.3.0",
"ember-cli-eslint": "^3.0.0",
"ember-cli-htmlbars": "^1.1.1",
"ember-cli-htmlbars-inline-precompile": "^0.4.0",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-mirage": "0.4.3",
"ember-cli-qunit": "^4.0.0",
"ember-cli-shims": "^1.1.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-tutorial-style": "2.0.0",
"ember-cli-uglify": "^1.2.0",
"ember-data": "^2.13.0",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-resolver": "^4.0.0",
"ember-source": "~2.13.0",
"ember-welcome-page": "^3.0.0",
"loader.js": "^4.2.3"
},
"engines": {
"node": ">= 4"
},
"private": true,
"dependencies": {
"npm-package-test": "git+https://github.com/nhoughto5/NPM_PackageTest.git"
}
}
When I run npm install in the ember project I can see that the folder structure from the library appears in the node_modules folder. To my limited experience, everything seems correct but for some reason I am still getting this undefined module error.
Is there a step I've missed or some crucial detail I'm missing?
Yes, there’s one step you are still missing. For Ember-CLI to understand that you want to include your npm package in your app’s vendor files, you’ll need to use app.import as outlined here: https://guides.emberjs.com/v3.0.0/addons-and-dependencies/managing-dependencies/
That approach with app.import has existed since Ember-CLI 2.15, but if you are on an older version you’ll need to upgrade first.

Browserify-shim Poltergeist/Phantom.JS strict mode issues

I'm making a Rails project using Browserify. Bootstrap Javascript is loaded via browserify-shim.
When I launch my project and look at it in Firefox, all is right. However, when I'm testing it via Poltergeist (or just starting it with PhantomJS 2.1.1), an error occurs:
Capybara::Poltergeist::JavascriptError:
One or more errors were raised in the Javascript code on the page. If you don't care about these errors, you can ignore them by setting js_errors: false in your Poltergeist configuration (see documentation for details).
ReferenceError: Strict mode forbids implicit creation of global property 'jQuery'
ReferenceError: Strict mode forbids implicit creation of global property 'jQuery'
at http://127.0.0.1:47269/assets/application-038b5f3da112b67153daa218adfed54030ee9e0085fd9586c0bb13fa320b830e.js:12
Here's the line in question:
;jQuery = global.jQuery = require("jquery");
Which, to me, looks like a shim line for jQuery (there's bootstrap.js code following it).
Here's my package.json:
{
"name": "billy-bones-rails",
"version": "0.0.1",
"description": "Billy-bones-rails asset package",
"main": "index.js",
"directories": {
"doc": "doc",
"test": "test"
},
"scripts": {
"bundle-js": "./node_modules/.bin/browserify app/assets/javascripts/index.js -o app/assets/javascripts/bundle.js",
"watch-js": "./node_modules/.bin/watchify app/assets/javascripts/index.js -o app/assets/javascripts/bundle.js -d -v"
},
"repository": {
"type": "git",
"url": "git+https://github.com/art-solopov/billy-bones-rails.git"
},
"author": "Artemiy Solopov",
"license": "MIT",
"bugs": {
"url": "https://github.com/art-solopov/billy-bones-rails/issues"
},
"homepage": "https://github.com/art-solopov/billy-bones-rails#readme",
"dependencies": {
"babel-cli": "^6.8.0",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.3.0",
"bootstrap": "^3.3.6",
"browserify": "^13.0.0",
"browserify-shim": "^3.8.12",
"jquery": "^2.2.2",
"normalize.css": "^4.0.0",
"watchify": "^3.7.0"
},
"browser": {
"bootstrap": "./node_modules/bootstrap/dist/js/bootstrap.js"
},
"browserify": {
"transform": [
"browserify-shim",
[
"babelify",
{
"presets": "es2015"
}
]
]
},
"browserify-shim": {
"bootstrap": {
"depends": [
"jquery:jQuery"
]
}
}
}
Can I do anything with this error outside of disabling Poltergeist error reports?
P. S. It should be noted that I'm only able to replicate this error using PhantomJS 2.1.1. Firefox (46 and 48), Chromium and PhantomJS 1.9.0 output no error.
Apparently, the issue was caused by a combination of babelify misconfiguration and browserify-shim. I added this to my babelify config:
"ignore": "node_modules"
This got rid of the top-level strict mode in the Bootstrap module.

Categories