Unable to use Babel 7 with Jest - node.js

So, I've tried following Jest's documentation on setting up Babel, including installing babel-core: 7.0.0-bridge.0 and such, but I've had no luck in getting it to work.
I've tried to dig through their issues on GitHub but many of the solutions there don't work for me, primarily because they are using a babelrc file where as I'm using babel.config.js, and due to Babel's incredibly hard to read documentation, I cannot for the life figure out how to convert what they are doing in rc files into the js equivalent.
Hopefully someone can provide a solution!
My configuration files are below as well as the error message I'm getting;
babel.config.js
module.exports = api => {
api.cache(true);
const presets = [
[
'#babel/preset-env',
{
targets: {
node: true,
},
},
],
];
return {
presets,
};
};
jest.config.js
module.exports = {
testEnvironment: 'node',
collectCoverage: true,
verbose: true,
};
Error Msg:
Test suite failed to run
tests/integration/mytest.test.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import request from 'supertest';
^^^^^^^
SyntaxError: Unexpected identifier
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

Related

Nestjs Jest Unit Test: Basic test failure - Jest configuration

I have a simple Jest test for my Nest JS project.
The Jest looks like:
import { Test, TestingModule } from '#nestjs/testing';
import { IbmVpcController } from './ibm.vpc.controller';
import { IbmVpcServiceMock } from './ibm.vpc.service.mock';
import { ModuleMocker, MockFunctionMetadata } from 'jest-mock';
import { MOCKED_VPC } from '../../repository/ibm/mock.vpc.data';
const moduleMocker = new ModuleMocker(global);
describe('IbmVpcController', () => {
let controller: IbmVpcController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [IbmVpcController],
providers: [IbmVpcServiceMock]
})
.useMocker((token) => {
if (token === IbmVpcServiceMock) {
return {
list: jest.fn().mockResolvedValue(MOCKED_VPC.VPCs),
get: jest.fn().mockResolvedValue(MOCKED_VPC.VPCs[0]),
create: jest.fn().mockResolvedValue(MOCKED_VPC.VPCs[0]),
update: jest.fn().mockResolvedValue(MOCKED_VPC.VPCs[0]),
};
}
if (typeof token === 'function') {
const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
const Mock = moduleMocker.generateFromMetadata(mockMetadata);
return new Mock();
}
})
.compile();
controller = module.get<IbmVpcController>(IbmVpcController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
My jest.config.js looks like:
module.exports = {
verbose: true,
preset: "ts-jest",
testEnvironment: "node",
roots: ["./src"],
transform: { "\\.ts$": ["ts-jest"] },
testRegex: "(/__test__/.*|(\\.|/)(spec))\\.ts?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
transformIgnorePatterns: [
'<rootDir>/node_modules/',
],
globals: {
"ts-jest": {
tsconfig: {
// allow js in typescript
allowJs: true,
},
},
},
};
However it is failing with the following error:
FAIL apps/protocols/src/ibm/vpc/ibm.vpc.controller.spec.ts
● Test suite failed to run
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".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
C:\Users\pradipm\clients\CloudManager\cm_6\occm\client-infra\nest-services\node_modules\axios\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import axios from './lib/axios.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (../../node_modules/retry-axios/src/index.ts:124:1)
Now able to get it what I am missing in my typescript Nest's Jest configuration.
Basically I tried out some more options also:
I tried out specifying the transformIgnorePatterns as only '/node_modules/'.
Tried out excluding the lodash-es', 'axios'
Tried out transformIgnorePattens as '/lib/' (where axois is there)
Added allowJs: true in the tsconfig.app.json compileOptions.
Any help to get trough my first basic test would be helpful.
With axios version 1.1.2 there's a bug with jest. You can resolve it by adding moduleNameMapper: { '^axios$': require.resovle('axios') } to your jest configuration

" Preset solid-jest not found." error when using jest

I would like to use jest and solid-jest to test one of my solid-js components. For this I created a configuration so that jest works solid-js. But, whenever I run the npm test command, I get the following error:
● Validation Error:
Preset solid-jest not found.
I searched for solutions on the Internet, but nothing about it. Here is the content of my jest.config.js file :
module.exports = async () => {
return {
verbose: true,
};
};
module.exports = {
preset: 'solid-jest',
testEnvironment: 'node',
transform: {
'^.+\\.jsx?$': 'solid-jest',
},
transformIgnorePatterns: ['./node_modules/'],
};
I don't know what's the problem.

Webpack using perf_hooks for node/browser module

I'm making a module that I would like to be available in the browser and Node. It relies on performance, which is giving me trouble with Webpack and the perf_hooks module in Node. No matter what I do I can only get it where it works in one or the other, but not both.
Below are most of the things I've tried. My question is, how do I configure Webpack to require perf_hooks in node, but use the built in performance global when in the browser?
Here is my base Webpack config:
const path = require('path');
module.exports = {
entry: './src/UpdateLoop.js',
mode: 'development',
output: {
library: 'UpdateLoop',
libraryTarget: 'umd',
path: path.resolve(__dirname, 'dist'),
filename: 'updateloop.js',
globalObject: 'this',
},
};
Code thats giving me trouble:
const { performance } = require('perf_hooks');
This errors in webpack with:
Field 'browser' doesn't contain a valid alias configuration
resolve as module
C:\Users\joe.jankowiak\projects\update-loop\src\node_modules doesn't exist or is not a directory
I've seen suggestions for 'fs' to do the following:
// configuration.node has an unknown property 'perf_hooks'
node: {
perf_hooks: false,
},
// configuration has an unknown property 'browser'.
browser: {
perf_hooks: false,
},
I then saw people recommending using 'resolve':
// Compiles, but complains performance doesn't exist in node or browser.
resolve: {
fallback: {
perf_hooks: false,
}
},
// Works in browser but doesn't work in node. Node complains about using performance before its defined:
performance = performance || require('perf_hooks').performance;
// Doesn't work in either
const performance = performance || require('perf_hooks').performance;
// Trying to check if its node, but with resolve its making perf_hooks null in node
if(typeof __webpack_require__ === 'function') {
global.performance = require('perf_hooks').performance;
}
I ended up doing this out of laziness because I still don't quite understand how to use NodeJS functions with Webpack:
function portableMsecTimer () {
if (process.hrtime) {
return Number(process.hrtime.bigint()) / 1e6;
} else {
return window.performance.now();
}
}

How can I debug this Webpack error - ERROR in bundle.js from Terser

I am trying to use webpack to bundle up a Node JS project, for the benefits it offers in terms of minimising the size of the code etc. and bundling together all of the dependencies.
My webpack job is failing with the following error:
ERROR in bundle.js from Terser
Invalid function parameter [bundle.js:186393,23]
This is my webpack.config file:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
target: "node",
mode: "production",
entry: {
app: ["./src/vitaq_client.js"]
},
// https://webpack.js.org/configuration/node/
// node: {
// global: false,
// __filename: true,
// __dirname: true,
// },
module: {
// https://github.com/ivan-aksamentov/reactlandia-bolerplate-lite/issues/5#issuecomment-413306341
exprContextCritical: false,
rules: [
{
test: /\.node$/,
use: 'node-loader'
},
{
test: /coffee/,
use: 'node-loader'
},
{
test: /\.coffee$/,
use: [ 'coffee-loader' ]
},
// {
// test: /\.map$/,
// use: ["source-map-loader"],
// enforce: "pre"
// },
]
},
plugins: [
new CleanWebpackPlugin(),
],
output: {
path: path.resolve(__dirname, "./build"),
filename: "bundle.js"
},
};
and this is the command I am using to run it:
webpack --config webpack.config.js
From the searching I have done it seems that there is a Terser plugin for code minification, but as you can see from my config file I am not loading that plugin, so does webpack use that plugin by default? If not how could I be getting an error from Terser ?
If I set the mode to "development" in the config file, then I do not get the problem, but I suspect that is because development code would not get minified.
I am a bit stuck as to how I set about debugging this problem - are there ways of getting more output from Webpack. I have tried using the --json > compilation-stats.json command line argument when I invoke webpack, but I get a huge output file (43Mb) and I can't find anything in all of that to help.
Any suggestions would be gratefully received.
This is an error with assignment where you have an invalid function parameter at the given line of bundle.js.
You can solve this by not minimizing the webpack build:
optimization: {
minimize: false
}
Then finding the assignment error line from the error output, in the non minified bundle.
Invalid function parameter [bundle.js:186393,23]
Hope this helps someone else.

SyntaxError: Cannot find name 'setImmediate'

In my .netcore app I upgraded my Typescript version from 2.4.1 to 3.2.4 and now I am receiving the error Cannot find name 'setImmediate' at compile time. The implementation I have below is basically straight from the Microsoft guide on pre-rendering.
export default createServerRenderer(params => {
const providers = [
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
];
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
const state = moduleRef.injector.get(PlatformState);
const zone = moduleRef.injector.get(NgZone);
return new Promise<RenderResult>((resolve, reject) => {
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
appRef.isStable.pipe(first(isStable => isStable)).subscribe(() => {
setImmediate(() => { // <!-- error here
resolve({
html: state.renderToString(),
globals: {
}
});
moduleRef.destroy();
});
});
});
});
});
I saw that there was a bug raised for this, however it is marked as resolved and merged. I also tried installing the setImmediate package and importing that, however that didn't work either. Anyone know how to resolve this ?
Non webpack:
Installing npm install --save-dev #types/node and then importing import '#types/node'; at the start of the file resolved this issue for me.
Webpack:
If you are using webpack then this will not work. Instead npm install --save-dev #types/node node then you will have to:
Go into your .tsconfig and add 'node':
{
"compilerOptions": {
"types": [..., "node" ],
...
}
}
do not import '#types/node'; this is for the reasons stated here:
#types packages are stored in the #types directory but they must never be manually imported. Rather, you need to import the dependency they correspond to from where that dependency is installed. #types packages provide the type declarations for dependencies that do not otherwise provide them.
I just tried the solution using webpack, and I noticed that there is no need to npm install node, just install #types/node (and follow the rest of the instructions of course) and it will work perfectly :)

Resources