fix(rspack): handle potentially missing lockfile in @nx/rspack/plugin plugin (#30086)

## Current Behavior

If the lock file is missing the `@nx/rspack/plugin` plugin throws a
cryptic error.

## Expected Behavior

The `@nx/rspack/plugin` should handle a missing lock file.

## Related Issue(s)

Fixes #
This commit is contained in:
Leosvel Pérez Espinosa 2025-02-18 12:30:43 +01:00 committed by GitHub
parent 9cdc1ccba4
commit c78279990d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 9 deletions

View File

@ -0,0 +1,47 @@
import { type CreateNodesContext } from '@nx/devkit';
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
import { createNodesV2 } from './plugin';
jest.mock('@nx/js/src/utils/typescript/ts-solution-setup', () => ({
...jest.requireActual('@nx/js/src/utils/typescript/ts-solution-setup'),
isUsingTsSolutionSetup: jest.fn(),
}));
describe('@nx/rspack', () => {
let createNodesFunction = createNodesV2[1];
let context: CreateNodesContext;
let tempFs: TempFs;
beforeEach(() => {
(isUsingTsSolutionSetup as jest.Mock).mockReturnValue(false);
tempFs = new TempFs('rspack-test');
context = {
configFiles: [],
nxJsonConfiguration: {
namedInputs: {
default: ['{projectRoot}/**/*'],
production: ['!{projectRoot}/**/*.spec.ts'],
},
},
workspaceRoot: tempFs.tempDir,
};
tempFs.createFileSync(
'my-app/project.json',
JSON.stringify({ name: 'my-app' })
);
tempFs.createFileSync('my-app/rspack.config.ts', `export default {};`);
});
afterEach(() => {
jest.resetModules();
tempFs.cleanup();
});
it('should handle missing lock file', async () => {
await expect(
createNodesFunction(['my-app/rspack.config.ts'], {}, context)
).resolves.not.toThrow();
});
});

View File

@ -107,20 +107,22 @@ async function createNodesInternal(
const normalizedOptions = normalizeOptions(options);
// We do not want to alter how the hash is calculated, so appending the config file path to the hash
// to prevent vite/vitest files overwriting the target cache created by the other
const nodeHash = hashArray([
...[
join(context.workspaceRoot, configFilePath),
const lockFileHash =
hashFile(
join(
context.workspaceRoot,
getLockFileName(detectPackageManager(context.workspaceRoot))
),
].map(hashFile),
hashObject(options),
)
) ?? '';
const nodeHash = hashArray([
hashFile(join(context.workspaceRoot, configFilePath)),
lockFileHash,
hashObject({ ...options, isTsSolutionSetup }),
hashObject(packageJson),
]);
// We do not want to alter how the hash is calculated, so appending the config file path to the hash
// to prevent vite/vitest files overwriting the target cache created by the other
const hash = `${nodeHash}_${configFilePath}`;
targetsCache[hash] ??= await createRspackTargets(