How to get Jest to ignore package.json files? - jestjs

I have a project with yeoman generators. The generators contain package.json template files that are used to generate actual package.json files in the generated project. As they are templates, they are not valid JSON.
Even though I don't run any tests in the generator sub-directories and there is no reason for Jest to open these files, it does visit them and throw invalid JSON errors. I've tried all the combinations I can find of the various Jest ignore options and Jest won't ignore these files.
I wonder if anyone knows how to persuade Jest not to visit these files.
The error looks like this:
Error: Cannot parse .../generator-terraform/generators/crud-api/templates/api/package.json as JSON: Unexpected token < in JSON at position 193
at Object.worker (.../generator-terraform/node_modules/jest-haste-map/build/worker.js:146:13)
at execFunction (.../generator-terraform/node_modules/jest-worker/build/workers/processChild.js:140:17)
at execHelper (.../generator-terraform/node_modules/jest-worker/build/workers/processChild.js:124:5)
at execMethod (.../generator-terraform/node_modules/jest-worker/build/workers/processChild.js:128:5)
at process.messageListener (.../generator-terraform/node_modules/jest-worker/build/workers/processChild.js:46:7)
at process.emit (events.js:314:20)
at emit (internal/child_process.js:902:12)
at processTicksAndRejections (internal/process/task_queues.js:81:21)

I solved it this way jest --modulePathIgnorePatterns='./template'

Related

Mock zip.js lib to be able to use jest

So, I have a project that imports a package utils, and this package depends on '#zip.js/zip.js' lib. This lib is meant for browser usage and doesn't work on node.
The first weird thing is that, when I try to run jest, I get:
FAIL tests/index.test.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:
./node_modules/#zip.js/zip.js/index.js:29
import Deflate from "./lib/core/codecs/deflate.js";
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import {
| ^
2 | Data64URIWriter,
3 | Entry,
4 | TextWriter,
at Runtime.createScriptFromCode (../../node_modules/jest-cli/node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (../utils/src/unzipFolder.ts:1:1)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 5.926 s
Which is totally misleading.
Anyway, now that I know that the problem is the usage of zip.js on node, I need to mock it so that jest doesn't break.
According to the docs for Manual mocks, here is what I did:
create a folder __mocks__ in the root folder (next to node_modules)
create a folder #zip.js inside it
create a file zip.js inside
It didn't work. So I tried the code we see in that doc and try to add jest.mock('#zip.js/zip.js') as first line in my test file, but to no avail.
I'm really not sure about how the mock system is actually working, so any help is really appreciated.
Edit:
I'll keep here the list of what was tried and failed:
using "type": "module" in package.json (same result)
All solutions from here and there (same result. Anyway, I'm convinced that the error message is just misleading)
I discovered the moduleNameMapper feature from jest. It totally solved my problem.
Here is my final jest.config.js file:
export default {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'#zip.js/zip.js': '<rootDir>/__mocks__/#zip.js/zip.js',
},
}
And here is what I have in <rootDir>/__mocks__/#zip.js/zip.js file:
module.exports = {}
Hope it helps someone!

Express application crashes when it is built with webpack

I am trying to use graphql-upload in a typescript express app (graphql api) built with webpack. When I run with ts-node my app works fine. But when I compile with webpack and then run I get a weird error when I try to upload a file.
My setup
Typescript app
Apollo server / Typegraphql
Build with webpack
My Code
(stripped down to the essentials)
https://github.com/ziggy6792/graphql-file-uploads
My Problem
When I run with ts-node yarn start:ts:node then run yarn test an image gets uploaded no problem
But then I build with webpack yarn start then run yarn test I get the following error
/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:56105
if (!isObject(operations) && !Array.isArray(operations))
^
TypeError: isObject is not a function
at Busboy.<anonymous> (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:56105:18)
at Busboy.emit (node:events:378:20)
at Busboy.module.exports../node_modules/busboy/lib/main.js.Busboy.emit (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:32204:33)
at PartStream.onEnd (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:32528:15)
at PartStream.emit (node:events:390:22)
at Dicer.onPart (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:32386:13)
at Dicer.emit (node:events:378:20)
at Dicer.module.exports../node_modules/dicer/lib/Dicer.js.Dicer.emit (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:45439:35)
at Dicer.module.exports../node_modules/dicer/lib/Dicer.js.Dicer._oninfo (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:45540:12)
at SBMH.<anonymous> (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:45486:10)
[nodemon] app crashed - waiting for file changes before starting...
My Attempts to solve
I am not sure if this actually a problem with graphql-upload or webpack or something else. I also noticed that my issue looks similar to this issue, but I didn't really understand if there were any fixes to that issue and if indeed it is the same issue I am facing.
I tried to upgrade webpack (branch upgraded-packages) but this made the problem worse as I get this issue when I start the server
TypeError: Cannot read property 'graphql' of undefined
at getPeerDependencyGraphQLRequirement (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:104216:44)
at Object.ensureInstalledCorrectGraphQLPackage (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:104221:32)
at Function.checkForErrors (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:103346:27)
at Function.generateFromMetadataSync (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:103325:14)
at Function.generateFromMetadata (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:103315:29)
at Object.buildSchema (/Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:103940:61)
at /Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:99831:41
at Generator.next (<anonymous>)
at /Users/sive/Documents/workspace/graphql-file-uploads/dist/index.js:99819:71
at new Promise (<anonymous>)
Any help would be greatly appreciated.
My best guess at the problem
From reading the linked issue it seems like isObject seems to ship ECMA Script modules with a newer version. Webpack might pick the ES modules version, but this version differs in the sense that the default export is now default and Apollo Server would have to import it as such or call isObject.default. In this changelog they say it might be breaking for users using bundlers.
Your two options now:
You could use yarn force the dependency to a previous version of isobject:
{
...
"resolutions": {
"graphql-file-uploads/isobject": "3.0.1"
}
}
Or you could simply not bundle your app and use TypeScript for building instead. You lose the benefits of bundling, but you are using an environment that is much more common for running node apps. Furthermore you will use TypeScript as a compiler just like ts-node unifying your development and production tooling.
You can compile using TypeScript like this:
yarn tsc 'src/**/*.ts'
In your TSConfig you should configure the output so that it also emits files to /dist.

#loadable/server pass the whole stats JSON to eval('require')(modulePath)

I'm trying to setup SSR for react app with #loadable/components. I setup all based on docs with babel and webpack plugins. When I try to run node server.js it runs ok but when I open a browser and throws the following error (into node console):
TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received an instance of Object
at validateString (internal/validators.js:118:11)
at Module.require (internal/modules/cjs/loader.js:1033:3)
at require (internal/modules/cjs/helpers.js:72:18)
at smartRequire (/Users/max/Documents/repos/app/node_modules/#loadable/server/lib/util.js:44:25)
at new ChunkExtractor (/Users/max/Documents/repos/app/node_modules/#loadable/server/lib/ChunkExtractor.js:181:50)
at renderer (webpack://app/./node_modules/#MYSCOPE/elm/dist/elm.esm.js?:3619:19)
at eval (webpack://app/./src/server.tsx?:64:90)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
code: 'ERR_INVALID_ARG_TYPE'
}
As you can see there is #MYSCOPE in the traceback which holds some of my internal packages (if it matters).
#loadable/server/lib/util.js is the following function:
And when I try to console.log(modulePath) on line 42 I see a whole stats JSON output which seems wrong and I should get a single module path (as I understand).
Any help?
I can share some specific parts of my configuration files if needed. Because I see my own package in console output seems like something is wrong with it's build (it works perfectly on the client-side with cjs build), but having full stats object as module path is very confusing.
UPD: Demo https://www.dropbox.com/s/9r947cgg4qvqbu4/loadable-test.zip?dl=0
Run
yarn
yarn dev:server
# go to localhost:3000 and see the error in console
to rebuild:
yarn
yarn dev:build-client
yarn dev:build-server
yarn dev:server # go to localhost:3000
The statsFile option passed to ChunkExtractor expects a path to the loadable-stats.json file, not the actual JSON content of it. By doing require('../loadable-stats.json'), webpack actually resolve the JSON during build time and assign it to the loadableJson variable.
You can change your loadableJson as follow:
import path from 'path';
const loadableJson = path.resolve(__dirname, '../bundle_client/loadable-stats.json');
This will solve the problem you had on your question. But, if you only do this, you will notice that you have another problem. Loadable by default assumes that your entry chunk name is main. This is not the case in your demo, as you have set the entry chunk name to be app instead.
entry: {
app: ['#babel/polyfill', './src/index.tsx']
},
To solve this, simply tell loadable about your entrypoints names by passing an array to the ChunkExtractor contructor as such:
const extractor = new ChunkExtractor({
statsFile: loadableJson,
entrypoints: ["app"], // name of your entry chunk
});
That's it, everything should now be working properly!
If it helps, I set up the demo on GitHub so you can easily see the changes I made here.

NuxtJS build breaks with UglifyJS and node-rsa. How do I resolve this?

I'm using the library node-rsa (https://www.npmjs.com/package/node-rsa) in a NuxtJS project. When building for production using the command nuxt build (which includes minification of JS and CSS by default), the build process breaks near the end with the following message:
ERROR in 0.nuxt.bundle.7c6932a7a42bdaaa7fa4.js from UglifyJs
Unexpected token: name (pem) [./~/node-rsa/src/formats/pkcs1.js:55,0][0.nuxt.bundle.7c6932a7a42bdaaa7fa4.js:42640,20]
Error: Webpack build exited with errors
at /home/ubuntu/front-end/node_modules/nuxt/dist/nuxt.js:904:44
at /home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:267:15
at Compiler.emitRecords (/home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:362:37)
at /home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:260:12
at /home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:355:11
at next (/home/ubuntu/front-end/node_modules/tapable/lib/Tapable.js:154:11)
at Compiler.compiler.plugin (/home/ubuntu/front-end/node_modules/webpack/lib/performance/SizeLimitsPlugin.js:99:4)
at Compiler.applyPluginsAsyncSeries1 (/home/ubuntu/front-end/node_modules/tapable/lib/Tapable.js:158:13)
at Compiler.afterEmit (/home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:352:8)
at Compiler.<anonymous> (/home/ubuntu/front-end/node_modules/webpack/lib/Compiler.js:347:14)
at /home/ubuntu/front-end/node_modules/async/dist/async.js:460:16
at iteratorCallback (/home/ubuntu/front-end/node_modules/async/dist/async.js:1034:13)
at /home/ubuntu/front-end/node_modules/async/dist/async.js:944:16
at /home/ubuntu/front-end/node_modules/graceful-fs/graceful-fs.js:43:10
at FSReqWrap.oncomplete (fs.js:117:15)
I was able to temporarily mitigate the issue by disabling uglifyJS (solution found at https://github.com/nuxt/nuxt.js/issues/250) but that does not seem like a long term solution. What is the correct way to resolve this?
Potentially related issue: Webpack breaks when i include node-rsa library
The problem is that I was trying to use a node library (not uglify-safe) on the browser without webpacking it. I switched to using pure JS for my crypto needs and everything went fine.

grunt-couch failing with error in task.js:205:15 & taskjs.:241:33

I'm not sure where this error is coming from - a misconfigured grunt.initConfig object, my files, or grunt itself. The error output is not clear about what might be wrong...
The error output:
Error: Task "couch-compile:app" failed.
at Task.<anonymous> (/Users/me/Dev/gitlab/theapp/src/node_modules/grunt/lib/util/task.js:205:15)
at null._onTimeout (/Users/me/Dev/gitlab/theapp/src/node_modules/grunt/lib/util/task.js:241:33)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
I tried figuring it out from other projects getting the same error in the task.js file, but I don't understand what's going on.
My couchapp works with the python version of couchapp push, so getting my project into a format usable by this grunt plugin could be my problem. My structure is basically (almost exactly) what is being expected by this plugin though. I've had to exclude some files that the .couchappignore file lists (the grunt-couch plugin doesn't account for that).
My grunt.initConfig object:
'couch-compile': {
app: {
files: {
'app.json' ['!*.txt','!*.sh','!_docs','!.couchapp*','webapp/**/*']
}
}
}
Could someone tell me whether it's my file structure, my grunt config object, or if the grunt-couch plugin is the one throwing the error?
Thanks.

Resources