From 9cec615a7e4e7db70b25add401d0888517ce6057 Mon Sep 17 00:00:00 2001 From: Thibault Derousseaux Date: Tue, 12 Jun 2018 16:18:34 -0400 Subject: [PATCH] BUGFIX: Use `junction` type when symlinking directories on Windows. It fixes an issue where `require` and `require.resolve` of a symlinked dependency would fail with an error such as: ``` Error: EPERM: operation not permitted, stat 'C:\workspace\packages\a-workspace-package\node_modules\antd' at Object.realpathSync (fs.js:1704:17) at toRealPath (internal/modules/cjs/loader.js:175:13) at Function.Module._findPath (internal/modules/cjs/loader.js:224:22) at Function.Module._resolveFilename (internal/modules/cjs/loader.js:546:25) at Function.resolve (internal/modules/cjs/helpers.js:18:19) ``` I also removed the uneeded `{force: true}` option in `createSymlinkForDependency` since there is an `if` above checking that the symlink path doesn't exist yet. --- package.json | 1 - src/lib/dependency.js | 4 +--- src/lib/file.js | 15 ++++++++++++--- yarn.lock | 23 ++--------------------- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index b4768256..bf4ab36c 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "inquirer": "5.2.0", "lodash.merge": "^4.6.1", "log-fancy": "1.3.2", - "make-symlinks": "1.1.0", "micromatch": "3.1.10", "yargs": "11.0.0" }, diff --git a/src/lib/dependency.js b/src/lib/dependency.js index 41bd5ee9..1909f5c7 100644 --- a/src/lib/dependency.js +++ b/src/lib/dependency.js @@ -208,9 +208,7 @@ const dependencyUtils = { return; } - await file.createSymlink(src, distDir, { - force: true - }); + await file.createSymlink(src, distDir); } }; diff --git a/src/lib/file.js b/src/lib/file.js index 0e18c9ab..5568a60f 100644 --- a/src/lib/file.js +++ b/src/lib/file.js @@ -1,20 +1,29 @@ // @flow const fs = require('fs'); -const makeSymlinks = require('make-symlinks'); +const {basename, join} = require('path'); const {promisify} = require('util'); const logger = require('./logger.js'); const _utils = { readFileAsync: promisify(fs.readFile), writeFileAsync: promisify(fs.writeFile), - accessAsync: promisify(fs.access) + accessAsync: promisify(fs.access), + statAsync: promisify(fs.stat), + symlinkAsync: promisify(fs.symlink) }; const fileUtils = { _utils, - createSymlink: makeSymlinks, + async createSymlink(target: string, distDir: string) { + const dist = join(distDir, basename(target)); + const stats = await _utils.statAsync(target); + // Use a junction on Windows like Yarn do. + // See: https://github.com/yarnpkg/yarn/blob/fc94a16b7ca90a188d084aef8cea406b60e8c38f/src/util/fs.js#L695-L696 + const type = stats.isDirectory() ? 'junction' : 'file'; + await _utils.symlinkAsync(target, dist, type); + }, /** * Asynchronously checks if a file exists or not. diff --git a/yarn.lock b/yarn.lock index 54cda565..55c95b75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1564,7 +1564,7 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -del@^2.0.2, del@^2.2.2: +del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" dependencies: @@ -2495,16 +2495,6 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - got@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" @@ -3917,15 +3907,6 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -make-symlinks@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-symlinks/-/make-symlinks-1.1.0.tgz#c6a05b0c60048a6c4dfe92b85b12f83a480b55c8" - dependencies: - del "^2.2.2" - globby "^6.1.0" - pify "^2.3.0" - pinkie-promise "^2.0.1" - makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -4603,7 +4584,7 @@ pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" -pinkie-promise@^2.0.0, pinkie-promise@^2.0.1: +pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" dependencies: