Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support symlinks within package #308

Open
ArGup opened this issue Dec 4, 2018 · 16 comments
Open

Support symlinks within package #308

ArGup opened this issue Dec 4, 2018 · 16 comments
Assignees
Labels
feature-request Request for new features or functionality help wanted Issues identified as good community contribution opportunities

Comments

@ArGup
Copy link

ArGup commented Dec 4, 2018

I am working on an extension which uses a node addon. The node addon in turn has a dependency on a custom mac framework that I am bundling with it. Everything work file in development mode. But when I package the extension using vsce package, it removes the symlinks from the Mac framework. Symlinks are required in a mac framework else it does not work. The .vsix file, when installed does not load the framework and the extension fails. Is there any option, by which I can instruct vsce not to remove symlinks.

  1. I have tried not to bundle the framework with extension and added the framework as a dependency(in package.json). But vsce brings all the dependencies while packaging. Ideally the dependencies should come at runtime i.e. when VSCode is installing the extension.

  2. I then tried to unpackage the .vsix file and then replaced the framework with my original framework and then repackaged it into .vsix. But when VSCode installs .vsix, it again removes the symlinks from framework, thereby corrupting it.

Please guide. Thanks.

@joaomoreno
Copy link
Member

I am working on an extension which uses a node addon. The node addon in turn has a dependency on a custom mac framework that I am bundling with it.

I don't fully understand the setup. Can you elaborate with actual path names and explaining what points to where? Also, what exactly gets removed?

@ArGup
Copy link
Author

ArGup commented Dec 5, 2018

@joaomoreno Lets say I have a mac framework(On your Mac you can go to: /System/Library/Frameworks/CoreFoundation.framework/). If you open above, you will notice there is CoreFoundation symlink which points to ./Versions/A/CoreFoundation. Similarly there is Resources symlink which points to ./Version/A/Resources. Now if you bundle this framework in your extension and use vsce package command, it will completely remove the Resources symlink and and it will replace that CoreFoundation symlink with actual binary at ./Versions/A/CoreFoundation. This way it corrupts the structure of Mac framework and it fails to load.

@joaomoreno
Copy link
Member

Now if you bundle this framework in your extension and use vsce package command, it will completely remove the Resources symlink and and it will replace that CoreFoundation symlink with actual binary at ./Versions/A/CoreFoundation. This way it corrupts the structure of Mac framework and it fails to load.

May I ask why you are including a macOS framework within your extension?

@ArGup
Copy link
Author

ArGup commented Dec 6, 2018

I have created a custom mac framework which contains my business logic. Basically i am working on debug adapter. The APIs are exposed through that mac framework. The framework contains resources too. And yes i can make that a dylib but the problem is it has more dependencies on other custom frameworks. What i want to ask is, is there any option by which i can instruct vsce not to touch symlinks. If there is not, then can I ask for dependencies at install time i.e. can vscode do yarn install in my extension package after it has done installation?

@joaomoreno joaomoreno changed the title vsce package command removes symlink from mac framework Support symlinks within package Dec 6, 2018
@joaomoreno joaomoreno self-assigned this Dec 6, 2018
@joaomoreno joaomoreno added the feature-request Request for new features or functionality label Dec 6, 2018
@joaomoreno joaomoreno added this to the Backlog milestone Dec 6, 2018
@joaomoreno joaomoreno added the help wanted Issues identified as good community contribution opportunities label Dec 6, 2018
@joaomoreno
Copy link
Member

joaomoreno commented Dec 6, 2018

There's no good suggestion I can give you right now apart from zipping up the framework beforehand and unzipping it at activation time. Needs fixing to support symlinks. Sorry about that!

@ArGup
Copy link
Author

ArGup commented Dec 6, 2018

No problem. Will look for workaround for the time being. Thanks anyways :)

@cagdas001
Copy link

cagdas001 commented Dec 21, 2018

I'm also having this. I'm spawning external Electron apps for some features in the extension. The Electron binary location on macOS (no problem on Windows with EXE file) is node_modules/electron/dist/Electron.app/Contents/MacOS/Electron It works properly when debugging in dev environment. But when I package the extension into VSIX, vsce removes some symlinks from Electron.app Therefore node_modules/electron/dist/Electron.app/Contents/MacOS/Electron executable cannot find a library and gets crashed.

I think we can add an option that allows user to enable this feature (e.g. called --include-symlinks, or something like that)

So

vsce package

will work as it currently is.

If user needs this feature,

vsce package --include-symlinks

will do the job.

What are your thoughts? I guess I'll be able to open a PR for this

@ArGup
Copy link
Author

ArGup commented Dec 22, 2018

@cagdas001 The problem is not only with vsce package. Here is what I also tried.

  1. I created .vsix file.
  2. Unzipped the .vsix file.
  3. Then I replaced the framework with the original one(with symlinks)
  4. Created a zip and renamed to .vsix.

Now when I installed this .vsix file, VSCode removed the symlinks again. So it needs to be fixed in VSCode too.

The workaround that I am using is(till the time it gets fixed in vsce and VSCode both):

  1. Create a tarball of framework(or .app in your case).
  2. Package it in .vsix
  3. Unpack the tarball in extension activation event(this needs to happen for the first time only).

@cagdas001
Copy link

cagdas001 commented Dec 22, 2018

@ArGup thanks, I'll temporarily use a similar solution to yours

If VSCode also ignores symlinks within package (have not investigated yet, how it does this), maybe we can add a flag in the package manifest.

If vsce package command called with --include-symlinks then VSCode will know this from the flag and will not ignore symlinks

I think this optional way is better rather than getting all symlinks in all cases

@joaomoreno joaomoreno removed this from the Backlog milestone Oct 11, 2019
@phgn0
Copy link

phgn0 commented Nov 10, 2019

I can confirm vsce package still ignores symlinks.

I temporarily fixed it for my usecase by manually resolving the symlink (i.e. duplicating the files).

phgn0 pushed a commit to phgn0/vscode-starlark that referenced this issue Nov 10, 2019
@panoply
Copy link

panoply commented Apr 29, 2020

I use pnpm which symlinks modules. Vsce being unable to support symlinks means preserving dependencies within node_modules like the vscode-languageserver is not possible. Would be cool to see this supported.

@sguillia
Copy link

Hi!

Dead simple npm links are also not supported

@KevinEady
Copy link

Hello,

Is there any progress on this? My use-case is a little different (not embedding Mac Frameworks), but I do want to have symlinks across modules in my extension.

I am creating an LSP extension, and my extension structure is as such:

extension
├── client
├── native
└── server

... where server has a dependency on native, via file:../native

My extension comes with native Node bindings, so I cannot webpack them into one JavaScript source. The LSP part works between client and server, because it does not require() the server by module name but by absolute path, see https://github.com/microsoft/vscode-extension-samples/blob/main/lsp-sample/client/src/extension.ts#L20 . I could move my native bindings into the server module, but I prefer to keep it self-contained for separation of concerns.

My workaround was something similar:

// Does not work, as `native` does not exist. In my dev workspace where
// I perform `vsce package`, it is a symlink to `server/node_modules`
import { foo } from 'native';

// Workaround
const { foo } = require('../../../native') as typeof import('native');

Workaround works, but I just wanted to provide additional use-cases for this feature.

Thanks, Kevin

@ssbarnea
Copy link
Contributor

Is there any way to raise awareness about this issue? In a world where many extensions are using language-servers, which are separated projects, they also need to test with main branch of their language-servers, so they need to build an extension using a linked npm package.

@ganeshrn
Copy link

Is there any way to raise awareness about this issue? In a world where many extensions are using language-servers, which are separated projects, they also need to test with main branch of their language-servers, so they need to build an extension using a linked npm package.

Agreed, to test unreleased versions for cross project testing it requires hack like these https://github.com/ansible/ansible-language-server/blob/v0.6.1/.github/workflows/vscode.yml#L37 which results in other problems.

@ssbarnea
Copy link
Contributor

As the main issue with this is related with npm link which continues to be broken even after years, it worth mentioning that yarn link support is in much better shape.

That made us start a switch from npm to yarn for our extension and once #743 is sorted we will be able to finish the switch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality help wanted Issues identified as good community contribution opportunities
Projects
None yet
Development

No branches or pull requests

9 participants