microsoft / vscode-vsce

VS Code Extension Manager
https://code.visualstudio.com/
Other
777 stars 194 forks source link

Support symlinks within package #308

Open ArGup opened 5 years ago

ArGup commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

cagdas001 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

@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

phgn0 commented 4 years ago

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).

panoply commented 4 years ago

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 commented 3 years ago

Hi!

Dead simple npm links are also not supported

KevinEady commented 3 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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.