Jest Ionic test fails - unexpected token import - angularjs

I am not sure why importing GA into my unit test fails. How can I fix this?
Maybe the JEST error should point me into the right direction, but unfortunately it does not:
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
....
/Users/me/app/node_modules/#ionic-native/google-analytics/index.js:20
import { Injectable } from '#angular/core';
^^^^^^
SyntaxError: Unexpected token import
2 | import { Http } from '#angular/http';
3 | import { Events } from 'ionic-angular';
> 4 | import { GoogleAnalytics } from '#ionic-native/google-analytics';
By instruction I extended my package.json with
"transformIgnorePatterns": [
"<rootDir>/node_modules"
],
but it still fails with the same error

I think I have found a solution to this problem,
Do not run npm run eject in your code base,
You can pass the flag in your package.json test command as given below,
--env=jsdom --transformIgnorePatterns 'node_modules/(?!(#ionic|<other-package-need-to-transform>)/)
this solution is common for ionic/react and ionic/angular

Related

Error inside node_modules while trying to run unit tests with jest

Edit:
Same error happens when I try to import highcharts directly into a test, commenting out any other setupFile
TypeError: Cannot set properties of undefined (setting 'highcharts')
1 | import * as React from 'react';
2 | // import Home from './Home';
> 3 | import highcharts from 'highcharts';
| ^
4 | import { render } from '#testing-library/react';
5 | // import { render } from 'jest-utils';
6 |
at node_modules/highcharts/highcharts.src.js:2499:9
at apply (node_modules/highcharts/highcharts.src.js:29:25)
at _registerModule (node_modules/highcharts/highcharts.src.js:108:5)
at factory (node_modules/highcharts/highcharts.src.js:13:13)
at Object.<anonymous> (node_modules/highcharts/highcharts.src.js:9:2)
at Object.<anonymous> (src/scripts/components/Home/Home.spec.js:3:1)
Currently, I'm trying to integrate react-testing-library (with jest, babel, webpack) to an old React project, I've updated React to 17.0.2 (latest possible version without crashing the whole project), and now I'm stuck at a weird error. Basically, when importing highcharts from one of my setup files, an error inside the node_modules pointing at the library happens.
TypeError: Cannot set properties of undefined (setting 'highcharts')
1 | import toastr from 'toastr';
> 2 | import Highcharts from 'highcharts';
| ^
3 | import exporting from 'highcharts/modules/exporting';
4 | import i18next from './i18n';
5 | import networkgraph from 'highcharts/modules/networkgraph';
at node_modules/highcharts/highcharts.src.js:2499:9
at fn (node_modules/highcharts/highcharts.src.js:29:25)
at _registerModule (node_modules/highcharts/highcharts.src.js:108:5)
at factory (node_modules/highcharts/highcharts.src.js:13:13)
at Object.<anonymous> (node_modules/highcharts/highcharts.src.js:9:2)
at Object.<anonymous> (src/scripts/vendor.js:2:1)
at Object.<anonymous> (src/scripts/i18n.js:14:1)
at Object.<anonymous> (src/scripts/ErrorHandlers/utils/GetErrorMessage.js:5:1)
at Object.<anonymous> (src/scripts/stores/UserStore/UserStore.js:15:1)
at Object.<anonymous> (src/scripts/Request.js:4:1)
at Object.<anonymous> (src/scripts/components/ReleaseNotes/ReleaseNotesStore.js:4:1)
at Object.<anonymous> (src/scripts/components/ReleaseNotes/ReleaseNotes.js:6:1)
at Object.<anonymous> (src/scripts/components/Home/Home.spec.js:2:1)
The last file that is traceable is the vendos.js that just imports the highchart like it's showing in the error preview.
This is the Jest config: https://pastebin.com/jt2L8ijQ
The project is running/compiling with no problem.
I tried to add highcharts to transformIgnorePatterns like so:
transformIgnorePatterns: ['node_modules/(?!(highcharts)/)'],
// or adding to moduleNameMapper
moduleNameMapper: {
highcharts: require.resolve('highcharts'),
...
}
But those changes had no difference, same result as before.
Tried updating highcharts too, but it ended up breaking some stuff.
I'm lost, don't really know what to do, if anyone needs extra info, ask away.
Thanks.
Ok.
I found why the error was happening.
In this project the highchart is using JQuery, and I was setting it incorretly, instead of setting up a setupFile.js, and adding to it like this:
import $ from 'jquery';
global.$ = $;
global.jQuery = $;
I was wrongly defining it inside my jest.config.js like so:
{
...
globals: {
"jQuery": require("jquery")
}
...
}
And these errors:
at node_modules/highcharts/highcharts.src.js:2499:9
at apply (node_modules/highcharts/highcharts.src.js:29:25)
It was guiding me to the wrong file, the actual file where the Type Error was happening was a highcharts build where it was trying to get a highcharts from the jQuery, this part in particular:
B.jQuery.fn.highcharts=function()
After all this weird debugging, I got it to run.

Jest "cannot use import statement outside a module" error when testing Go JS PackedLayout in react app

I'm building a react app and was planning to using Go JS as a part of the app. However, I get this error when running the default yarn test that comes with create react app:
/path/frontend/node_modules/gojs/extensionsJSM/PackedLayout.js:11
import * as go from '../release/go-module.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import * as go from 'gojs'
> 2 | import { PackedLayout } from 'gojs/extensionsJSM/PackedLayout'
| ^
3 | import { ReactDiagram } from 'gojs-react'
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/components/Grid.tsx:2:1)
at Object.<anonymous> (src/App.tsx:6:1)
at Object.<anonymous> (src/App.test.tsx:4:1)
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:404:19)
I believe the bug appears because of the line import * as go from '../release/go-module.js'; in the Go JS PackedLayout file. I'm not quite sure as to how I am supposed to fix this. I assume that I'd have to somehow tell Jest to allow the import in the that particular file which is in node_modules.
I've tried adding transformIgnorePatterns: ['/node_modules/(?!gojs)'] to my jest.config.ts file but it did not fix the issue.
As documented at:
https://gojs.net/latest/intro/extensions.html
and at:
https://gojs.net/latest/api/symbols/PackedLayout.html,
you should copy the extension file into your project and update its import statement to refer to the same GoJS library file.

NextJS & CSS SyntaxError: Unexpected token

I'm trying to unit test but the only way I can stop the error throwing is to comment out the import './styles.css line.
As soon as I put it back in I get:
Jest encountered an unexpected token
...
SyntaxError: Unexpected token.
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
> 3 | import './styles.css';
| ^
4 |
5 |
I have webpack, babel, jest, enzyme all configured but googling tells me there's a difference between running the app (via webpack) and using .css files vs running tests that can read .css files, which would need to be configured separately.
For love nor money, I cannot find an example where import './styles.css is successfully imported & the tests pass.
Can anyone help?
Managed to get this working by hitting up https://github.com/eddyerburgh/jest-transform-stub
My jest.config.js now looks like this:
module.exports = {
setupFiles: ['<rootDir>/jest.setup.js'], // links to normal "configure({ adapter: new Adapter() })" stuff.
testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'], // ignores test files in .next(js) & node modules
transform: {
"^.+\\.js$": "babel-jest", // anything .js is babel'd for jest to consume
"^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub" // anything style related is ignored and mapped to jest-transform-stub module
},
moduleNameMapper: {
'\\.css$': '<rootDir>/EmptyModule.js' // <-- had to pop this in the following day to get any separetly imported .css files mapped to an empty module / object. So if i try to do import 'react-style-module/styles/my-styles.css' it would fail, though 'import './styles.css' worked. Now with this mapped correctly also, everything is imported/mapped/passing successfully.
}
}
If anyone else has other neater solutions, please let me know. x
In your package.json file set 'type' property to 'module'
{
"type":"module"
}
I think you declare like this:
import css from './styles.css'
<div className={css.test}>
</div>
Reference: https://github.com/zeit/next-plugins/tree/master/packages/next-css

Create-react-app doesn't allow import component.js from node_modules?

I received error when try to import { PrimaryButton } from 'my-npm-modules/src/button' ( which is a flowtype src jsx file with extension .js)?
Is it because the create-react-app have config to NOT do flowtype processing for files in node_modules?
Module parse failed: /Users/me/live-demo/node_modules/my-npm-modules/src/button.js Unexpected token (2:35)
You may need an appropriate loader to handle this file type.
| //#flow
| import React from 'react';
| export function PrimaryButton(props: {
| text: string;
| onClick: ()=>void
When I put the button.js inside the live-demo project, it works fine.
It seems it did exclude the node_modules folder for performance reason.
So I endup compile the flow-typed jsx --> normal js files, and provided js.flow at the same output folder for sake of consumer flowtype support.

Importing self-created libraries in reactjs

I'm using React and ES6 using babel and webpack. I am very new to this ecosystem.
I am trying to import some common utility functions into my jsx file but react is unable to find the file
homepage.jsx
var pathToRoot = './../..';
import path from 'path';
import React from 'react';
import ReactDOM from 'react-dom';
var nextWrappedIndex = require(path.join(pathToRoot,'/lib/utils.js')).nextWrappedIndex;
//some react/JSX code
utils.js
var nextWrappedIndex = function(dataArray) {
//some plain js code
return newIndex;
}
exports.nextWrappedIndex = nextWrappedIndex;
Directory structure is as follows:
src
|--app.js
|--components
| |--homepage
| |--homepage.jsx
|
|--lib
| |--utils.js
I am on a windows 10 machine and was facing issues during compilation providing the path by any other means. Using path.join solved compilation issue but the browser while rendering throws this error
Uncaught Error: Cannot find module '../../lib/utils.js'.
How do I accomplish this?
Also, is this the best way to do it(if altogether it is way it is supposed to be done in such ecosystem)?
One of the best and easiest way I have found in such a setup is to use Webpack aliases.
Webpack aliases will simply associate an absolute path to a name that you can use to import the aliased module from anywhere. No need to count "../" anymore.
How to create an alias?
Let's imagine that your Webpack config is in the parent folder of your src folder.
You would add the following resolve section in your config.
const SRC_FOLDER = path.join(__dirname, 'src')
resolve: {
alias: {
'my-utils': path.join(SRC_FOLDER, 'lib', 'utils')
}
}
Now, anywhere in your app, in any of your modules or React component you can do the following:
import utils from 'my-utils'
class MyComponent extends React.component {
render () {
utils.doSomething()
}
}
Small note about this method. If you run unit tests with a tool like enzyme and you don't run the component tested through Webpack, you will need to use the babel-plugin-webpack-alias.
More info on Webpack website: Webpack aliases
I solved this by replacing
var nextWrappedIndex = require(path.join(pathToRoot,'/lib/utils.js')).nextWrappedIndex;
with
import nextWrappedIndex from './../../lib/utils.js';
I tried to reproduce your code and Webpack printed me the following error:
WARNING in ./app/components/homepage/homepage.jsx
Critical dependencies:
50:0-45 the request of a dependency is an expression
# ./app/components/homepage/homepage.jsx 50:0-45
It means that Webpack couldn't recognize your require() expression because it works only with static paths. So, it discourages the way you are doing.
If you would like to avoid long relative paths in your import, I'd recommend you to set up Webpack.
First, you can set up aliases per Amida's answer.
Also, you can set up an extra module root via resolve.modules to make webpack look into your src folder, when you are importing something absolute, like lib/utils.js

Resources