Skip to content

javascript: singleton packages #3

@bmeck

Description

@bmeck

Some packages are intended to only exist within a dependency graph once. often things expecting to act like singletons.

I think it would be good to investigate 2 possible fields for package.json tooling to use.

"singleton": boolean

If present, the package must have a name unique within the entire module graph, else it will fail to install. This would prevent things like having 2 different versions of react-intl be able to install in the same graph.

"singletonDependencies": string[] | "all"

If present this field ensures that dependencies with the same name are not present multiple times within a graph. This could be useful for preventing things like having multiple configuration packages which might not wish to use "singleton" in their own package.json.

If the value is an array of strings, it does search of the graph to ensure that the name is a singleton. This applies to the entire graph, not only the submodules of the current package.

If the value is "all" then all submodules must be singletons and their submodules recursively must also be singletons.

determination of "package name"

Module names are not found within package.json files. They are determined by the presence of a file with a filename that could be loaded as a the starting segments of a bare specifier like request for import("request") or lodash for import("lodash/chunk").

scoped packages

Installation of packages by tools are given the full name by which the package is to be imported:

npm i @npm/invalid

If the package contained "singleton": true. This would result in singleton checks against all the dependency graph for @npm/invalid before placing the installation such that it could be used via import("@npm/invalid"). It would not check the value of "name" within the package.json that is installed.

bundledDependencies

Bundled dependencies are also checked to be singletons, no exceptions are to be made when searching for collisions. If you wish to use a duplicate package in a bundled fashion: you can rename it, add a scope, or put it into a vendor folder.

root package

When writing applications, they tend to be at the root/entry point of your dependency graph. The directory name of this entry point and package.json "name" field are not used when searching for singletons. This allows modules to link to themselves in such a way that they can be loaded as bare specifiers while still being declared singletons.

realpathing

Due to the nature of various runtime flags like --preserve-symlinks, realpathing should not be performed when searching for singletons.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions