diff --git a/.changeset/orange-swans-relax.md b/.changeset/orange-swans-relax.md new file mode 100644 index 00000000000..6f7d006dae6 --- /dev/null +++ b/.changeset/orange-swans-relax.md @@ -0,0 +1,6 @@ +--- +"@pnpm/symlink-dependency": patch +"pnpm": patch +--- + +Symlink a local dependency to `node_modules`, even if the target directory doesn't exist [#5219](https://github.com/pnpm/pnpm/issues/5219). diff --git a/packages/symlink-dependency/jest.config.js b/packages/symlink-dependency/jest.config.js new file mode 100644 index 00000000000..f697d831691 --- /dev/null +++ b/packages/symlink-dependency/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js') diff --git a/packages/symlink-dependency/package.json b/packages/symlink-dependency/package.json index ce49bbb7234..d598c0e580e 100644 --- a/packages/symlink-dependency/package.json +++ b/packages/symlink-dependency/package.json @@ -16,6 +16,7 @@ }, "devDependencies": { "@pnpm/logger": "^4.0.0", + "@pnpm/prepare": "workspace:*", "@pnpm/symlink-dependency": "workspace:*" }, "directories": { @@ -33,10 +34,11 @@ "repository": "https://github.com/pnpm/pnpm/blob/main/packages/symlink-dependency", "scripts": { "start": "tsc --watch", - "test": "pnpm run compile", - "lint": "eslint src/**/*.ts", + "test": "pnpm run compile && pnpm run _test", + "lint": "eslint src/**/*.ts test/**/*.ts", "prepublishOnly": "pnpm run compile", - "compile": "tsc --build && pnpm run lint --fix" + "compile": "tsc --build && pnpm run lint --fix", + "_test": "jest" }, "dependencies": { "@pnpm/core-loggers": "workspace:*", diff --git a/packages/symlink-dependency/src/symlinkDirectRootDependency.ts b/packages/symlink-dependency/src/symlinkDirectRootDependency.ts index 8d060d81bdd..3e1ef4b1e05 100644 --- a/packages/symlink-dependency/src/symlinkDirectRootDependency.ts +++ b/packages/symlink-dependency/src/symlinkDirectRootDependency.ts @@ -50,7 +50,10 @@ export default async function symlinkDirectRootDependency ( } catch (err: any) { // eslint-disable-line if (err.code !== 'ENOENT') throw err globalWarn(`Local dependency not found at ${dependencyLocation}`) - return + // Sometimes the linked in local package does not exist during installation + // and is created later via a build script. + // That is why we create the symlink even if the target directory does not exist. + dependencyRealLocation = dependencyLocation } const dest = path.join(destModulesDirReal, importAs) diff --git a/packages/symlink-dependency/test/symlinkDirectRootDependency.test.ts b/packages/symlink-dependency/test/symlinkDirectRootDependency.test.ts new file mode 100644 index 00000000000..737d7fad1eb --- /dev/null +++ b/packages/symlink-dependency/test/symlinkDirectRootDependency.test.ts @@ -0,0 +1,21 @@ +import fs from 'fs' +import path from 'path' +import { tempDir } from '@pnpm/prepare' +import { symlinkDirectRootDependency } from '@pnpm/symlink-dependency' + +test('symlink is created to directory that does not yet exist', async () => { + const tmp = tempDir(false) + const destModulesDir = path.join(tmp, 'node_modules') + const dependencyLocation = path.join(tmp, 'dep') + fs.mkdirSync(destModulesDir) + await symlinkDirectRootDependency(dependencyLocation, destModulesDir, 'dep', { + linkedPackage: { + name: 'dep', + version: '1.0.0', + }, + prefix: '', + }) + fs.mkdirSync(dependencyLocation) + fs.writeFileSync(path.join(dependencyLocation, 'index.js'), 'module.exports = {}') + expect(fs.existsSync(path.join(destModulesDir, 'dep/index.js'))).toBe(true) +}) diff --git a/packages/symlink-dependency/tsconfig.json b/packages/symlink-dependency/tsconfig.json index 2cce143602d..783b976c392 100644 --- a/packages/symlink-dependency/tsconfig.json +++ b/packages/symlink-dependency/tsconfig.json @@ -9,6 +9,9 @@ "../../typings/**/*.d.ts" ], "references": [ + { + "path": "../../privatePackages/prepare" + }, { "path": "../core-loggers" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25fc9544a3c..c5e823e6da5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5031,6 +5031,9 @@ importers: '@pnpm/logger': specifier: ^4.0.0 version: 4.0.0 + '@pnpm/prepare': + specifier: workspace:* + version: link:../../privatePackages/prepare '@pnpm/symlink-dependency': specifier: workspace:* version: 'link:'