How do I use recent version Ava with express and babel? - node.js

I want to use Ava for my node.js project with express and babel.
It does not seem to be possible to use that combination with Ava version 4+ c.f. https://github.com/avajs/ava/issues/2955 (or maybe the bug is not blocking, but simply a matter of changing the recipe - but to what?).
So moving on to using version 3.15.0 instead:
npm install --save-dev #ava/babel
npm install --save-dev ava#3.15.0
I tried the following configuration in package.json:
"ava": {
"babel": true,
"files": [
"test/**/*"
],
"concurrency": 1,
"failFast": true,
"failWithoutAssertions": true
},
And I get the following error message:
✖ Internal error
TypeError: Cannot read properties of undefined (reading '1')
TypeError: Cannot read properties of undefined (reading '1')
at Plugin.manipulateOptions (/mypath/node_modules/babel-plugin-module-resolver/lib/index.js:88:9)
at normalizeOptions (/mypath/node_modules/#babel/core/lib/transformation/normalize-opts.js:56:16)
at run (/mypath/node_modules/#babel/core/lib/transformation/index.js:31:93)
at run.next (<anonymous>)
at Object.transform (/mypath/node_modules/#babel/core/lib/transform.js:25:41)
For the same node.js express setup I was able to use ava version 0.25.0 with the configuration below, but I would prefer using a more recent version ;o):
"ava": {
"source": "src/**/*.js",
"files": "test/**/*.js",
"tap": true,
"require": "babel-register",
"babel": "inherit"
},

Related

Jest moduleNameMapper and NPM package exports

I am developing fullstack NPM packages with multiple entrypoints (namely client, server and sometimes tests), using the exports property of package.json.
I also use a small hack to make TS work with exports until it's officially supported (see this Stack Overflow post, this hackish solution and this ticket).
The package.json ends up looking like this:
{
"name": "#vulcanjs/graphql",
"version": "0.4.7",
"main": "./dist/index.js",
"files": [
"dist/"
],
"exports": {
".": "./dist/index.js",
"./server": "./dist/server/index.js",
"./testing": "./dist/testing.js"
},
"types": "./dist/index.d.ts",
"typesVersions": {
"*": {
"server": [
"./dist/server/index.d.ts"
],
"testing": [
"./dist/testing.d.ts"
]
}
},
"description": "Vulcan graphQL schema generator",
...
You can then import using either #vulcanjs/graphql for shared code, and #vulcanjs/graphql/server for Node.js-only code.
It works perfect in my Next.js app. However, it seems to break Jest moduleNameMapper.
First, I had this:
moduleNameMapper: {
"#vulcanjs/(.*)": [
"<rootDir>/node_modules/#vulcanjs/$1",
],
},
The error is:
Configuration error:
Could not locate module #vulcanjs/graphql/server mapped as:
[
"/code/vulcan-next/node_modules/#vulcanjs/graphql/server",
].
The problem is that it tries to find a package named #vulcanjs/graphql/server: yet "server" is not a different package, it's an entrypoint of #vulcanjs/graphql.
I've also tried this:
moduleNameMapper: {
"#vulcanjs/(.*)/(.*)": [
"<rootDir>/node_modules/#vulcanjs/$1",
],
},
With this config, #vulcanjs/graphql/server is mapped to #vulcanjs/graphql. The problem is that now, server code is not found. I've checked and the problem is that this solution totally removes the /server: so #vulcanjs/graphql/server points to the main entrypoints instead of the server entrypoint.
Finally I did try to remove the moduleNameMapper, but then #vulcanjs/graphql/server package is not found by Jest. Note that I need the mapper for a use case I did not demonstrate here, so getting rid of it is possible but not the best solution.
The bug can be reproduced by installing the framework: https://github.com/VulcanJS/vulcan-next. You can clone, yarn install, unskip the test in src/models/tests/sampleModel.server.test.ts and run yarn run test:unit sampleModel. It will show the error.
Any idea how I could fix this?

babel-node doesn't transpile JSX in npm react script for Node version 14

I'm having a big problem with running my npm script using babel-node. This script generates static error pages from react components. With Node versions 10 and 12 it is running successfully, but when I have updated my node version to 14 babel-node seems to stop transpiling JSX. Now I get this error:
<MuiThemeProvider theme={theme}>
^
SyntaxError: Unexpected token '<'
at Loader.moduleStrategy (internal/modules/esm/translators.js:140:18)
at async link (internal/modules/esm/module_job.js:42:21)
My devDependencies in package.json file:
"devDependencies": {
"#babel/node": "^7.14.2",
"#babel/preset-env": "^7.14.2",
"babel-plugin-styled-components": "^1.12.0",
"prettier": "2.3.0"
}
and script in package.json:
"generate-error-pages": "babel-node scripts/generate-error-pages.js"
And this is my .babelrc file:
{
"presets": ["#babel/preset-env", "#babel/react"],
"plugins": [["styled-components", { "ssr": true }]]
}
I can't make it work with Node version 14 like it worked with version 10 and 12.
Creating new repository helped me find the problem. In previous versions of Node I had to add
"type": "module"
in package.json because without it there was an exception caused by using import in JS script. Now I observed that in Node 14 I don't need "type": "module" anymore. This was even the problem of described exception. After deleting this from package.json it is now working also in Node 14.

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

Why does ESLint throw an error while using export/import statement on Node.js 12.13.0?

I have a project built on Node.js, DynamoDB and other AWS services, deployed on Serverless architecture. I also have the ESLint package installed.
I am getting the following error:
ESLint: Import and export declarations are not supported yet on Node 8.0.0. (node/no-unsupported-features)
Following are the details of my project:
Node version: 12.13.0
NPM version: 6.12.0
Serverless version: 1.40.0
ESLint: 6.8.0
I have double verified by node version of my project and my local. Both are the same (12.13.0).
I am able to use async/await but whenever I try using import/export, it gives me the error.
Following is my .eslintrc file :
{
"extends" : [
"eslint:recommended",
"plugin:node/recommended"
],
"plugins": [
"promise",
"node"
],
"env" : {
"browser" : false,
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"impliedStrict": false
},
"globals" : {
},
"rules": {
"no-console": 0,
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false }],
"node/no-unpublished-require": [
"error",
{
"allowModules": [
"aws-sdk"
]
}
],
"node/no-unsupported-features": ["error", {
"version": 8,
"ignores": []
}]
}
}
`
Node.js by default uses Common.js style for import/export.
In the new versions of Node.js you can use different extensions or the --experimental-modules option in the command line.
*.mjs you use ES6 import/export
*.js or *.cjs you use commonjs
If you consider that ECMAScript modules import/export are still experimental, I would say that ESLint is quite correct.
You might want to override EsLint rules in order to make it work with that.
Firstly consider that the rule you mentioned is obsolete so you might want to use the new ones => https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-unsupported-features.md
Because those rules are obsolete I would suggest you to take a look at your eslint and its external rulesets version (if you use them) and try again.
In any case...
Check/create the .eslintrc.json file in the root of your project and override the project rules you might want to change.
Just stumpled upon a similiar error.
In my case i solved it by adding the engines definition to package.json
"engines": {
"node": ">=12.13.0"
}
I am not sure if this solves you problem but a quite similar issue can be found here.

.flat is not a function only with jest

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.

Resources