Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create relative symlinks using absolute paths in Node.JS

I have a projects with the following structure:

project-root
├── some-dir
│   ├── alice.json
│   ├── bob.json
│   └── dave.json
└── ...

I want to create symlinks like the following ones:

  • foo -> alice.json

I chose to use the fs.symlink function:

fs.symlink(srcpath, dstpath[, type], callback)

Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms). Note that Windows junction points require the destination path to be absolute. When using 'junction', the destination argument will automatically be normalized to absolute path.

So, I did:

require("fs").symlink(
  projectRoot + "/some-dir/alice.json"
, projectRoot + "/some-dir/foo"
, function (err) { console.log(err || "Done."); }
);

This creates the foo symlink. However, since the paths are absolute the symlink uses absolute path as well.

How can I make the symlink path relative to a directory (in this case to some-dir)?

This will prevent errors when the parent directories are renamed or the project is moved on another machine.

The dirty alternative I see is using exec("ln -s alice.json foo", { cwd: pathToSomeDir }, callback);, but I would like to avoid that and use the NodeJS API.

So, how can I make relative symlinks using absolute paths in NodeJS?

like image 949
Ionică Bizău Avatar asked Apr 21 '15 16:04

Ionică Bizău


People also ask

Are Symlinks relative or absolute?

Symbolic links can either be absolute or relative links. Absolute links are links that specify each portion of the path name; relative links are determined relative to where relative–link specifiers are in a specified path.

How do I add a symlink to a node module?

It's as easy as typing npm link from the root directory where your module is located(i.e where your package. json is). This will create a symlink between the global directory where your node_modules is located and the local directory where you ran this command.

What is absolute path in JavaScript?

An absolute import path is a path that starts from a root, and you need to define a root first. In a typical JavaScript/TypeScript project, a common root is the src directory. For file1.

What is symbolic link in Linux with example?

A symlink is a symbolic Linux/ UNIX link that points to another file or folder on your computer, or a connected file system. This is similar to a Windows shortcut. Symlinks can take two forms: Soft links are similar to shortcuts, and can point to another file or directory in any file system.


2 Answers

Option 1: Use process.chdir() to change the current working directory of the process to projectRoot. Then, provide relative paths to fs.symlink().

Option 2: Use path.relative() or otherwise generate the relative path between your symlink and its target. Pass that relative path as the first argument to fs.symlink() while providing an absolute path for the second argument. For example:

var relativePath = path.relative('/some-dir', '/some-dir/alice.json');
fs.symlink(relativePath, '/some-dir/foo', callback);
like image 51
Trott Avatar answered Sep 17 '22 18:09

Trott


const path = require('path');
const fs = require('fs');

// The actual symlink entity in the file system
const source = /* absolute path of source */;

// Where the symlink should point to
const absolute_target = /* absolute path of target */;

const target = path.relative(
    path.dirname(source),
    absolute_target
);

fs.symlink(
    target,   
    source,
    (err) => {

    }
);
like image 22
Bryan Grace Avatar answered Sep 16 '22 18:09

Bryan Grace