Is there any technical reason to avoid a self-depending local dependency (file reference) in npm?

Viewed 316

I would like to use local import paths for my Node.js package (self-reference) in the same way I am using local import paths for other local packages (instead of relative paths). Here is an example of a package.json:

{
  "name": "@somecompany/testproject",
  "dependencies": {
    "@somecompany/_self": "file:.",
    "@somecompany/utils": "file:../utils"
  }
}

After installing the package, I can something like this, if there is a test.js in the same package:

import { randomize } from "@somecompany/utils/random.util";
import { test } from "@somecompany/_self/test";

Is there any technical drawback of this solution, as it introduces obviously a circular dependency? Are there performance issues (I assume each resolution must first resolve to the symlink)? Is it an anti-pattern? Are there any other reasons to avoid this pattern (e.g. OS-depending problems)?

As far as I've tested (npm install, running it with node) it does seem to work (Linux, npm@7, node@14).

The reason for using such a pattern is to have a consistent import path strategy across all packages including the current one (avoiding relative paths). I don't like to postprocess the import paths by e.g. using webpack or babel. I've seen a similar pattern using the invalid package name @ for the current package to avoid relative file paths. But this requires post-processing.

1 Answers

Node imports modules in a fixed way. See What is require. This "self reference" registers the local directory under the given npm package name, but the exports and files are the same to node.

It is unconventional. Other devs could get lost in this structure, or forgot that a local file change will affect the import as well. I don't know what will break, but it is pretty odd.

I could see benefit if you are planning to break apart a module to a separate NPM repo (public or private) and are using the code this way until that's ready. Or to avoid network trips to NPM on installs.

Also, be very careful how files in that "inner repo" reference other files. Keep it contained - import order matters in NodeJS and that could be a mess to unravel if something goes wrong.

Related