Jest Error From Conflict With Composer PHP Packages

tl;dr

If working on a project that is not solely in NodeJS/JavaScript and writing tests in Jest, I would recommend updating the Jest config to ignore the path's of any directories containing package dependencies for the project.

In a Laravel project for example, you should specify that Jest should ignore the Composer PHP dependencies located in the /vendor directory which may include JavaScript and be considered a module for the Jest module loader to parse:

module.exports = {
    //...

    // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
    modulePathIgnorePatterns: ['/vendor'],

    //...
};

Full Context

I recently ran into a seemingly weird bug while working on writing some tests in Jest for a React component that is part of the frontend for a Laravel PHP project.

Essentially, when running npm test to run my Jest tests, it would error out with the following error:

Error: Cannot parse /Users/path/to/project/vendor/composer/70987396/tighten-ziggy-ffeff44/package.json as JSON: ENOENT: no such file or directory, open '/Users/path/to/project/vendor/composer/70987396/tighten-ziggy-ffeff44/package.json'
    at Object.worker (/Users/path/to/project/node_modules/jest-haste-map/build/worker.js:146:13)
    at execFunction (/Users/path/to/project/node_modules/jest-worker/build/workers/processChild.js:145:17)
    at execHelper (/Users/path/to/project/node_modules/jest-worker/build/workers/processChild.js:124:5)
    at execMethod (/Users/path/to/project/node_modules/jest-worker/build/workers/processChild.js:128:5)
    at process.messageListener (/Users/path/to/project/node_modules/jest-worker/build/workers/processChild.js:46:7)
    at process.emit (events.js:400:28)
    at emit (internal/child_process.js:912:12)
    at processTicksAndRejections (internal/process/task_queues.js:83:21)
npm ERR! Test failed.  See above for more details.

This error popped up after merging in a couple GitHub dependabot updates, along with an update to the project's PHP packages. I did try to rollback and clear caches but it continued to error out. Instead of digging further into the rabbit hole to find out what caused it, my main aim was to find a solution since other projects would likely need similar updates in the future and could encounter the same issues.

What threw me off was that Jest was complaining about a package.json file that was missing (likely in a cache), but inside the PHP package dependencies /vendor directory?! Why was Jest even looking inside the PHP dependencies directory, when it never did that before? Still not really sure what changed that modified its behavior. Maybe it was a bug that it wasn't looking in there before, when it should have been? Questions to ponder.

Anyhoo, after some narrowing down, the only Composer PHP packages that were triggering the error were Tighten's Ziggy package and Facade's Ignition package. What is notable is that both of these PHP packages also have their own package.json files which include Jest as a dev dependency (since these packages utilize JavaScript either for build output or scripts added to your code).

What I ultimately concluded, was that when Jest runs, its module loader will scour the project repository to find any potential modules (JavaScript code) that utilize Jest and try to include those in the test run. This is quite diligent of the little test runner, but also led to my confusion since this behavior was not occurring before and not sure what otherwise triggered it.

The solution was to edit the Jest configuration file and specify that Jest should ignore module paths in the /vendor directory:

module.exports = {
    //...

    // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
    modulePathIgnorePatterns: ['<rootDir>/vendor'],

    //...
};

This worked like a charm and all the code in the /vendor directory is now ignored when running Jest. I believe this also helped speed Jest up, since it was no longer scouring the hefty number of PHP dependency packages in this directory to find test files!

The above configuration setting should probably be standard for Laravel projects that use Jest, or any non-JavaScript project that has a dependency directory full package code files that can be ignored.