From 573bf8a94064ad712940732575ecc325c2c05b97 Mon Sep 17 00:00:00 2001 From: Rakha Kanz Kautsar Date: Mon, 24 Aug 2020 06:12:40 -0700 Subject: [PATCH] Fix scoped symlink module resolution (#1482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Fixes https://github.com/facebook/flipper/issues/1481 ## Changelog Fix symlinked scoped module resolving to outer directory Pull Request resolved: https://github.com/facebook/flipper/pull/1482 Test Plan: Added one more case to the existing test case for `getWatchFolders.ts` ``` ❯ yarn run test:debug getWatchFolders yarn run v1.22.4 $ yarn build:pkg && node --inspect node_modules/.bin/jest --runInBand getWatchFolders $ cd pkg && yarn build $ tsc -b Debugger listening on ws://127.0.0.1:9229/41e16e0b-8a44-42fe-93ac-9dd9d06e418d For help, see: https://nodejs.org/en/docs/inspector PASS pkg-lib/src/__tests__/getWatchFolders.node.ts getWatchFolders ✓ getWatchFolders correctly resolves symlinked packages (12 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 1 passed, 1 total Time: 2.358 s Ran all test suites matching /getWatchFolders/i. {emoji:2728} Done in 8.60s. ``` Reviewed By: mweststrate Differential Revision: D23293357 Pulled By: nikoant fbshipit-source-id: de2a506693727489238c6f6ec62d07526f8f0c69 --- .../pkg-lib/src/__tests__/getWatchFolders.node.ts | 12 +++++++++++- desktop/pkg-lib/src/getWatchFolders.ts | 14 +++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/desktop/pkg-lib/src/__tests__/getWatchFolders.node.ts b/desktop/pkg-lib/src/__tests__/getWatchFolders.node.ts index ed886c641..1123d3b53 100644 --- a/desktop/pkg-lib/src/__tests__/getWatchFolders.node.ts +++ b/desktop/pkg-lib/src/__tests__/getWatchFolders.node.ts @@ -44,6 +44,11 @@ describe('getWatchFolders', () => { fb_plugin_module_2: mockfs.symlink({ path: '../plugins/fb/fb_plugin_module_2', }), + '@scoped': { + local_module_3: mockfs.symlink({ + path: '../../local_module_3', + }), + }, }, local_module_1: { 'package.json': '{"dependencies": {"installed_module_1": "1.0.0"}}', @@ -52,9 +57,13 @@ describe('getWatchFolders', () => { 'package.json': '{"dependencies": {"fb_plugin_module_1": "1.0.0", "plugin_module_1": "1.0.0"}}', }, + local_module_3: { + 'package.json': '{"dependencies": {"installed_module_1": "1.0.0"}}', + }, plugins: { plugin_module_1: { - 'package.json': '{"dependencies": {"local_module_2": "1.0.0"}}', + 'package.json': + '{"dependencies": {"local_module_2": "1.0.0", "@scoped/local_module_3": "1.0.0"}}', }, plugin_module_2: { 'package.json': '{"dependencies": {"fb_plugin_module_1": "1.0.0"}}', @@ -102,6 +111,7 @@ describe('getWatchFolders', () => { "/test/root/plugins/fb/node_modules", "/test/root/plugins/plugin_module_1", "/test/root/plugins/plugin_module_2", + "/test/root/local_module_3", ] `); } finally { diff --git a/desktop/pkg-lib/src/getWatchFolders.ts b/desktop/pkg-lib/src/getWatchFolders.ts index 0f6ffb8a3..458312d56 100644 --- a/desktop/pkg-lib/src/getWatchFolders.ts +++ b/desktop/pkg-lib/src/getWatchFolders.ts @@ -36,15 +36,23 @@ export default async (packageDir: string): Promise => { if (await fs.pathExists(nodeModulesDir)) { watchDirs.add(nodeModulesDir); for (const moduleName of dependenciesSet) { + const isModuleNameScoped = moduleName.includes('/'); const fullModulePath = path.join(nodeModulesDir, moduleName); if (await fs.pathExists(fullModulePath)) { dependenciesSet.delete(moduleName); const stat = await fs.lstat(fullModulePath); if (stat.isSymbolicLink()) { const targetDir = await fs.readlink(fullModulePath); - const absoluteTargetDir = path.isAbsolute(targetDir) - ? targetDir - : path.resolve(nodeModulesDir, targetDir); + let absoluteTargetDir; + if (path.isAbsolute(targetDir)) { + absoluteTargetDir = targetDir; + } else if (isModuleNameScoped) { + const scope = moduleName.split('/')[0]; + const scopeDir = path.join(nodeModulesDir, scope); + absoluteTargetDir = path.resolve(scopeDir, targetDir); + } else { + absoluteTargetDir = path.resolve(nodeModulesDir, targetDir); + } if (!processedPackages.has(absoluteTargetDir)) { packagesToProcess.push(absoluteTargetDir); processedPackages.add(absoluteTargetDir);