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

Epic: Improved Support for node / Global Package Management (WIP/TBD) #600

Open
9 tasks
darcyclarke opened this issue Oct 31, 2022 · 1 comment
Open
9 tasks

Comments

@darcyclarke
Copy link
Contributor

darcyclarke commented Oct 31, 2022

node versioning w/ npm

Note: this originated as a hackmd document & is more ideation than any concrete plan - ref. https://hackmd.io/plwvVie7S4ycbvxefbdodA

Potential Goals & Action Items

  • globally installed package binarys should have some safe-guards/reasonable way to determine which one wins when there's duplicate names
  • help potentially transfer node package/namespace on npmjs.com to the Node.js Project
  • ask Node.js Project to begin distributing releases on npmjs.com using dist-tags as mutable references for things like LTS versions
    • benefit: support policies, version management & updates come out-of-the-box with the npm CLI or any other tool/package manager that interfaces with npmjs.com (not really different then using canonical git tags/releases on github.com or hosting distributions on nodejs.org - these can continue to exist)
  • there should be no need for third-party tools (ie. npm comes with node, you should be able to use that to update/upgrade your system node without the need for a third-party tool)
  • remove references to node version managers in npm/cli's README.md
    • this list has been controversial in terms of the criteria used to add net-new projects
  • add reference to upgrading/updating node using npm in npm/cli README.md
  • investigate nvm & missing features of npm i node
  • investigate volta & it's approach (may have similar concerns about it's proxy/aliasing as we do conceptually as well as license-wise for corepack)
  • make npm i node -g -f && npm outdated -g work (currentlty fails because of expected paths not existing)

The below is rough ideation/WIP

Example Use Cases & Usage

Install & Manage node System-wide

npm i node -g
npm i node@14 -g
npm i node@19 -g

Note: this currently requires the --force flag to install node if you already have it installed to overwrite the bin

Execute node in an individual process

npx node@14 -e "console.log(process.version)"

Check for outdated node version

npm outdated -g

Package  Current  Wanted  Latest  Location           Depended by
node     10.0.1   10.9.2  19.0.1  node_modules/node  global

Note: this currently fails after npm i node -g since there are paths we expect to exist, that don't, under {prefix}/lib/node_modules

Updating node to a specific version

npm update node@19 -g

Project-specific

npm i node
// package.json
{
    "dependencies": {
        "node": "*"
    },
    "engines": {
        "node": ">=14"
    }
}

Set Project-specific node versions with engines

npm pkg set engines.node="^14.17.0||^16.13.0||>=18.0.0"

Enforce node specific versions

# command specific
npm install --engines-strict
npm ci --engines-strict
# project-specific config
npm config set engines-strict=true --location=project
# user-specific config
npm config set engines-strict=true --location=user
# global config
npm config set engines-strict=true -g

Add Net-new Config for Maintaining Packages across Version Updates

node & npm become unique package names where we are able to provide unique flags/context when doing an install or update.

npm i node@14 -g -f -k
# -k | --keep-installed-packages 
# maybe `--keep-installed-packages=node@12` to allow only copying/reinstalling deps from a previous spec of node

Note: consider

Note: switching npm or node bins may loose context of previously installed packages; adding this flag should resolve this use-case of retaining packages across these package versions at the system-level

Note: two (or more?) types of node installations:

  • "main" node - the version that all your globally installed packages are linked
  • "test/project" nodes - the versions that are used on specific projects. when those are installed as set as the primary node, you should not lose access to your globally installed packages. those should be callable and will use the "main" node

Net-new Global Manifest & Improved Linking

npm link

# current:
cd ./pkg && npm link . && cd ../project && npm link <pkg> 

# future: interfaces with the global `package.json`
npm link <get|set|list>
npm link set <name>=<path>

npm link set lodash=.
npm link <path> # is equivalent to...
npm link <pkg>=<path>

npm link ls # returns all project deps that are symlinked
npm link ls -g # returns all globally available links
npm link get <pkg> # returns path to project linked package
npm link get <pkg> -g # returns path to globally linked package

Global package.json

// {global prefix}package.json
{
  "linkedDependencies": {
    "node": ["json", "diff-so-fancy"],
  },
  "dependencies": {
    "json": "*",
    "diff-so-fancy": "^3.0.0",
    "node-19": "npm:node@19",
    "node-18": "npm:node@18",
    "node-12": "npm:node@12",
    "node-current": "npm:node@current",
    "node": "node@lts"
  },
  "node": "12"
}
npm update|install node -g
# will update and save `json` and `diff-so-fancy` (if necessary?) and update global/package.json
# due to them being listed in linkedDependencies#node

Questions

  • how does the name of a bin on disk get inferred when multiple packages have the name and bin?
    • eg, node

Global + Project Example

// root/package.json
{
  "dependencies": {
    "json": "1"
  }
}
// root/project/package.json
{
  "dependencies": {
    "json": "2"
  },
  "scripts": {
    "run-json": "json"
  }
}
cd /root
json --version # 1.0.0
cd /root/project
npm run run-json -- --version # 2.0.0
json --version # 1.0.0
npx json --version # 2.0.0
cd /root
npx json --version # 1.0.0

Net-new Command to manage PATH

npm path <get|set|list>

Note: this is a global operation by default (aka. --global=true)

Questions

  • how to manage multiple installed versions and have one aliases to node?
    • --install-strategy=linked -g could create a global store where multiple versions of node can co-exist (hypothetically)
  • how to ensure compatability between other globally installed npm packages and npm installed version of node?

Links & References

@darcyclarke darcyclarke changed the title EPIC: Improved Support for node / Global Binary Management EPIC: (WIP) Improved Support for node / Global Binary Management Oct 31, 2022
@darcyclarke darcyclarke changed the title EPIC: (WIP) Improved Support for node / Global Binary Management EPIC: Improved Support for node / Global Binary Management (WIP/TBD) Oct 31, 2022
@darcyclarke darcyclarke changed the title EPIC: Improved Support for node / Global Binary Management (WIP/TBD) EPIC: Improved Support for node / Global Package Management (WIP/TBD) Oct 31, 2022
@darcyclarke darcyclarke changed the title EPIC: Improved Support for node / Global Package Management (WIP/TBD) Epic: Improved Support for node / Global Package Management (WIP/TBD) Oct 31, 2022
@ljharb
Copy link

ljharb commented Nov 1, 2022

I think the very first step is to make a devEngines - iow, engines is for consumers, and people currently abuse it for project devs, but it would be much more explicit (and necessary for proper version management) to have one explicitly for developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants