.flat is not a function only with jest - jestjs

When running my tests with jest, I had the above error;
Error: Uncaught [TypeError: array.map(...).flat is not a function]
Following the solution from that issue, https://github.com/kulshekhar/ts-jest/issues/828
I've installed core-js on dependencies and putting this in jest.config.js
setupFiles: ['core-js'],
I'd receive that another error;
Error: Uncaught [Error: Not supported]
And this is occurring only with jest, I'm using babel and webpack on my application and storybook without errors on flat.
My jest.config.js
const PATH = require('./path')
module.exports = {
setupFilesAfterEnv: ['./rtl.setup.js'],
moduleFileExtensions: ['js'],
verbose: true,
moduleNameMapper: {
'#components(.*)$': `${PATH.source}/components/$1`
},
transform: {
'^.+\\.js$': 'babel-jest'
}
}

per https://github.com/kulshekhar/ts-jest/issues/828#issuecomment-433976880
this problem can be solved by running
npm install --save-dev core-js
and adding core-js to your jest config's setupFiles
"setupFiles": ["core-js"]

I installed core-js (#3.4.1) and it worked for me.
Also had to add import 'core-js'; at the top of my test file's imports.
Edit: Using it in a create-react-app project that is not ejected, so I don't access webpack files and I don't have a custom config for jest (nor jest-ts).

This error happens if your node version is old. Try to update it to the latest version.

Searching more about core-js, since it's substituting #babel/polyfill, that config has worked to me.
[
"#babel/preset-env",
{
"targets": {
"node": 4
},
"useBuiltIns": "usage",
"corejs": 3
}
]
And core-js#3 being installed as a dependency.

Related

Error while loading config - You appear to be using a native ECMAScript module configuration file (Jest)

UPDATED.
This error is coming up when I am making a pull request. There is a github workflow audit that runs checks on the pull request and it loads the test file from another repository.
- name: Run Audits
run: npx jest audits/ch-2 --json --outputFile=audits/ch-2.json --noStackTrace
Test suite failed to run
/Users/frankukachukwu/StudioProjects/covid-19-estimator-tksilicon-js/babel.config.js: Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.
How do I solve this issue?
SOLVED: For anyone who encounters this problem. This has got to do with Babel settings. The use of .mjs, cjs or js extension for the babel.config.extension. In my case where I was running LTE Node 12.6.2. I needed this configuration at the root of my directory babel.config.cjs. cjs is what is applicable for Nodejs when using "type"="module". See more about it here on babel docs.
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
And jest.config.cjs at the root too.
In addition to "cjs" solution, I was able to resolve this issue by converting babel.config.js to babel.config.json:
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"#babel/preset-typescript"
]
}

Using #babel/register for a React app in Node v13

I have an app built using create-react-app and it has an entrypoint that used something like this —
require('babel-register')({
ignore: [/(node_modules)/],
presets: ['es2015', 'react-app'],
plugins: [
'syntax-dynamic-import',
'dynamic-import-node',
'react-loadable/babel'
]
});
require('./index');
I'm in the process of upgrading Node (from v8 to v13.5) and decided to upgrade Babel too. Using Babel 7, the above piece of code was rewritten as —
require('#babel/register')({
ignore: [/(node_modules)/],
presets: ['#babel/preset-env', 'react-app'],
plugins: [
'#babel/plugin-syntax-dynamic-import',
'dynamic-import-node',
'react-loadable/babel'
],
});
require('./index');
Now when I run this, I get the error —
internal/modules/cjs/loader.js:1160
throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
^
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /my-app/node_modules/babel-preset-react-app/node_modules/#babel/runtime/helpers/esm/asyncToGenerator.js
require() of ES modules is not supported.
require() of /my-app/node_modules/babel-preset-react-app/node_modules/#babel/runtime/helpers/esm/asyncToGenerator.js from /my-app/server/controllers/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename asyncToGenerator.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /my-app/node_modules/babel-preset-react-app/node_modules/#babel/runtime/helpers/esm/package.json.
I'm guessing this is because preset-env is using modules support as it is detecting it in my version of Node (v13.6.0). If that's how I can fix this issue, how do I force it to use the es2015 preset? They've long been deprecated in favor of preset-env.
I stumbled upon this comment on the Babel project's issue tracker that says BABEL_ENV should be set to test to transpile modules.
The relevant code from the linked comment is here —
[
isEnvTest && [
// ES features necessary for user's Node version
require('#babel/preset-env').default,
{
targets: {
node: 'current',
},
},
],
(isEnvProduction || isEnvDevelopment) && [
// Latest stable ECMAScript features
require('#babel/preset-env').default,
{
// Allow importing core-js in entrypoint and use browserlist to select polyfills
useBuiltIns: 'entry',
// Set the corejs version we are using to avoid warnings in console
// This will need to change once we upgrade to corejs#3
corejs: 3,
// Do not transform modules to CJS
modules: false,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
},
]
]
Setting BABEL_ENV to test fixes my issue.
You can either downgrade to Node v10 or add this to the existing one
"start": "node --experimental-modules src/index.mjs "
If you are using geolib library. Please try upgrading your geolib dependency to 3.2.x. The "type": "module" flag has been removed from 3.1.x -> 3.2.x
or try changing he node version to 12.11.1, 12.12.0
Refer the discussion here https://github.com/manuelbieh/geolib/issues/208

How do I get the ESModules working in node.js (import/export) with babel

So I've been adviced that I should use babel.js to transpile my code in order to use the import/export syntax. What I did is I followed the main setup guide that is at this link: https://babeljs.io/setup#installation
I created a .babelrc file after running npm install --save-dev babel-plugin-transform-es2015-modules-commonjs with this content:
{
"presets": ["#babel/preset-env"],
"plugins": [
["transform-es2015-modules-commonjs", {
"allowTopLevelThis": true
}]
]
}
Well, I still keep getting the same error regardless :
import {Config} from '../config/config';
SyntaxError: Unexpected token {
Here is my project structure :
I would really appreciate some help since I am out of ideas, thank you

async / await breaks my Webpack build for AWS Lambda; how can I migrate to Node 8.10?

Note: this is a Q&A on migrating AWS Lambda Webpack builds from v6.10 to v8.10 — no help is needed, but even better answers are of course always encouraged!
For a while now I have been a disciple of using Webpack to build my back-end Lambdas after reading James Long's excellent series entitled "Backend Apps with Webpack" (part 1, part2, and part3).
Up until recently, the only version of Node.js that Amazon Web Services offered was 6.10; you had to write your Lambda fn in the "callback" style. But on April 2, 2018 AWS announced that 8.10 was now supported, and with it the suggested pattern is async / await which is great! Until it immediately broke my Webpack build. After a bit of debugging, I can break my build just by adding one async fn to the Lambda handler (I don't even need to call it):
async function firstAsync() {
return true;
}
exports.handler = async (event) => {
// TODO implement
return 'Hello from Lambda!'
};
To be clear, doing this in the AWS Lambda console is perfectly fine, runs great. Webpack even builds it successfully, but upon uploading to AWS Lambda, I get the following error message: regeneratorRuntime is not defined. My code is below. What am I needing to do?
webpack.config.js
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack');
const config = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
library: 'index',
libraryTarget: 'commonjs2',
filename: 'index.js'
},
target: 'node', // building for a Node environment
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
module: {
rules: [{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}]
},
plugins: [
new UglifyJsPlugin()
]
};
module.exports = config;
package.json
{
"name": "lambda-webpack",
"version": "1.0.0",
"description": "An empty project scaffold to enable webpack builds in AWS Lambda",
"main": "index.js",
"scripts": {
"build": "webpack",
"upload": "upload.bat"
},
"author": "Geek Stocks®",
"license": "MIT",
"devDependencies": {
"aws-sdk": "^2.179.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"uglifyjs-webpack-plugin": "^1.1.6",
"webpack": "^3.10.0",
"webpack-node-externals": "^1.6.0"
}
}
Geek Stock's answer above is only necessary when using the Node v6.10 runtime. It allows you to use async/await syntax and babel-runtime/regenerator converts your async functions to ES6 generators which is supported on Node v4.3.2 and newer runtimes.
In Node v8.10 though, it is different. async/await is already supported so you don't need Babel to convert your async functions to generators. You just use it correctly and it works.
As for your specific situation, I assume you simply changed your Javascript code to use async/await code but you didn't tell Babel NOT to convert your async/await code to generators. That is why babel-runtime is complaining about a missing plugin.
If this is the case, you simply need to configure Babel to simply target Node v8.10. You can do it like this in your .babelrc...
{
"presets": [
[
"env",
{
"targets": {
"node": "8.10"
}
}
]
]
}
babel will then stop converting those async functions. And since it's not doing a conversion, it will not need the regenerator-runtime anymore.
In my case I'm using it with nodejs12.x. I'm receiving the error regeneratorRuntime is not defined.
I was using preset es2015 and stage-0 with a node12.x code. Also I'm using an older version of babel.
What I did, installed:
"#babel/cli": "^7.10.1",
"#babel/core": "^7.10.2",
"#babel/preset-env": "^7.10.2"
And then set this babel preset:
"presets": [
["#babel/preset-env", {"targets": { "node": "current" }}]
]
Thanks,
To begin using async / await in your Webpack-built code, you need a little help from Babel, specfically the babel-runtime and the babel-plugin-transform-runtime. Fortunately there is a really good writeup on the installation and use of both here on the Babel website. You need Babel to do the following for you:
Automatically requires babel-runtime/regenerator when you use
generators/async functions.
I won't repeat what has been written there, however, of particular note is HOW you need to install these, because while their writeup certainly works for most, there is a needed tweak for some AWS Lambda devs who have not needed runtime dependencies before now.
The first part is pretty normal, you need new devDependencies:
npm install --save-dev babel-plugin-transform-runtime
And also you need to tweak your .babelrc file like they describe:
{
"plugins": [
["transform-runtime", {
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}]
]
}
But here is the kicker, and this is new to the code above: the babel-runtime is a regular dependencies, not a devDependencies:
npm install --save babel-runtime
These 2 installs and the .babelrc tweaks do SOLVE the async / await problem described above, but it introduces a new problem to the build above: Cannot find module 'babel-runtime/regenerator'.
If you are at all concerned with keeping your Webpack built code small, you are likely also using webpack-node-externals like the above code does. For example, the aws-sdk for JavaScript in Node is very large and is already available in the Lambda environment, so its superfluous to bundle it again. The webpack-node-externals configuration above configures Webpack to ignore ALL the modules in node-modules by default, and there is the root of the new problem. The newly installed babel-runtime is a module that needs to be bundled in the build in order for Lambda to run correctly.
Understanding the problem then, the answer becomes simple: don't use the default configuration. Instead of passing in nothing to webpack-node-externals, configure it like this:
externals: [nodeExternals({
whitelist: [
'babel-runtime/regenerator',
'regenerator-runtime'
]
})], // ignore all modules in node_modules folder EXCEPT the whitelist
And that solves both the original async / await problem, and the (possible) new problem you may be encountering if you had no previous dependencies in your build. Hope that helps — happy Lambda awaiting!

Angular 6 and karma 'Can not load "#angular-devkit/build-angular", it is not registered'

I had to migrate to the newest angular version. After that, karma tests stopped working and just keep crushing with an error log:
14 04 2018 14:17:00.453:ERROR [preprocess]: Can not load "#angular-devkit/build-angular", it is not registered!
Perhaps you are missing some plugin?
...\parkandrest-ui\node_modules\#angular-devkit\build-angular\src\angular-cli-files\plugins\packages\angular_devkit\build_angular\src\angular-cli-files\plugins\karma.ts:52
const options = config.buildWebpack.options;
^ TypeError: Cannot read property 'options' of undefined
at init (...\parkandrest-ui\node_modules\#angular-devkit\build-angular\src\angular-cli-files\plugins\packages\angular_devkit\build_angular\src\angular-cli-files\plugins\karma.ts:52:39)
at Array.invoke (...\parkandrest-ui\node_modules\di\lib\injector.js:75:15)
at Injector.get (...\parkandrest-ui\node_modules\di\lib\injector.js:48:43)
at E:\Workspace\Training\spring-boot-tutorial\parkandrest-ui\node_modules\karma\lib\server.js:166:20
at Array.forEach ()
at Server._start (...\parkandrest-ui\node_modules\karma\lib\server.js:165:21)
at Injector.invoke (...\parkandrest-ui\node_modules\di\lib\injector.js:75:15)
at Server.start (...\parkandrest-ui\node_modules\karma\lib\server.js:126:18)
at Object.
My karma.conf.js file looks like this:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['#angular-devkit/build-angular']
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
config: './angular.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
#angular-devkit\build-angular is of course installed. I appreciate any help.
EDIT:
I have a solution which actually combines most of the user answers to my question with my own. Firstly I updated my whole project to stable angular 6 release. Next, I generated empty project like #R.Richards suggested and then I replaced almost every configuration in my old project with the new one. Finally, I have encountered a problem #Suvendu warn me about. I used his solution to resolve it. Unfortunately, I still have one problem with my environment (Intellij IDEA 2017.3.4 Ultimate) which disallows me to start karma tests directly from my IDE ( I've got the same error #Suvendu mentions about), however, it is a topic for the next question.
My solution was a little different, as I had to move the karma.conf.js.
Update all dependencies and make sure the app itself works as intented
If not done already: Replacing every occurrence of #angular/cli with #angular-devkit/build-angular in the karma.conf.js
Removing the files and the preprocessor configs from the karma.conf.js completely. This is all defined in the angular.json and should be handled automatically by the #anguler-devkit karma plugin.
Could not find module "#angular-devkit/build-angular"
here is what worked for my project:
npm install -g #angular/cli
npm install #angular/cli
ng update #angular/cli --migrate-only --from=1.7.0
ng update #angular/core
npm install rxjs-compat
ng serve
I hope this works for you!
I followed this guide to do a clean migration of the project, which solved the same issue for me.
Try installing karma-webpack with npm and then add it to the plugins array -
plugins: [
...
require('karma-webpack'),
...
],
and replace the preprocessors with this -
preprocessors: {
'./src/test.ts': ['webpack']
},
This worked in my case and will also work for the below anticipated future error-
Error: The '#angular-devkit/build-angular/plugins/karma' karma plugin is meant to be used from within Angular CLI and will not work correctly outside of it.
Hope this helps.
The solution for me was that my NODE_ENV environmental variable was set to "production". While trying to upgrade to Angular 6 I did not realize that #angular-devkit/build-angular was listed in my devDependencies, which are not installed in a production environment.
Running "unset NODE_ENV" and removing NODE_ENV from /etc/environment fixed my problem. (Note: Be careful changing this variable in an actual production environment).
In your karma.conf.js add following library, in plugins section. This is done in Angular8.
require('#angular-devkit/build-angular/plugins/karma')

Resources