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

Node.js support #2996

Closed
W1M0R opened this issue Jul 12, 2024 · 40 comments
Closed

Node.js support #2996

W1M0R opened this issue Jul 12, 2024 · 40 comments
Labels
enhancement New feature or request

Comments

@W1M0R
Copy link

W1M0R commented Jul 12, 2024

Feature Overview

Please add node and npm to the package registry.

Why is the feature needed?

Very convenient. If aqua supports node, then I don't need proto, pixi or vfox for node.

Workaround

Use proto to install node.

Example Code

No response

Note

I see the documentation clearly states that node is not supported: https://aquaproj.github.io/docs/#use-aqua-along-with-asdf

This is still a request to see what could be done about that limitation.

Reference

Reference

@W1M0R W1M0R added the enhancement New feature or request label Jul 12, 2024
@suzuki-shunsuke
Copy link
Member

Please see this issue too.

@suzuki-shunsuke
Copy link
Member

Experimentally, I've added Node.js to aqua-registry again.

⚠️ For now, Windows isn't supported.

Please read the setup instruction in the release note too.

I'd really appreciate if you try this out and give us your feedback.

@suzuki-shunsuke
Copy link
Member

Oh, I found that the change of Node.js version isn't reflected...
We need to fix the setup instruction.

@W1M0R
Copy link
Author

W1M0R commented Aug 18, 2024

Thanks @suzuki-shunsuke. I use aqua on Windows.

@suzuki-shunsuke
Copy link
Member

I use aqua on Windows.

Oops. I see. I'm sorry about that.
I excluded Windows for now as the content of zip file was different from macOS and Linux, and it's a bit troublesome to verify on Windows.
After Linux and macOS, I'll work on Windows.

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 18, 2024

Windows has a different API of environment variables from Linux and macOS, so maybe it's difficult.
I'm not familiar with Windows.
I'll take a look.

@W1M0R
Copy link
Author

W1M0R commented Aug 19, 2024

Here is how Scoop installs Node on Windows:

{
    "version": "22.6.0",
    "description": "An asynchronous event driven JavaScript runtime designed to build scalable network applications.",
    "homepage": "https://nodejs.org",
    "license": "MIT",
    "architecture": {
        "64bit": {
            "url": "https://nodejs.org/dist/v22.6.0/node-v22.6.0-win-x64.7z",
            "hash": "3d280cd238e4010b862f5668ea84741d17e014c834ba2e12616a0c3effdda2eb",
            "extract_dir": "node-v22.6.0-win-x64"
        },
        "32bit": {
            "url": "https://nodejs.org/dist/v22.6.0/node-v22.6.0-win-x86.7z",
            "hash": "d6da737a1029c7ca9bc507727b841bf37dde104e5bce6e9e9d3fdf1c256abf3e",
            "extract_dir": "node-v22.6.0-win-x86"
        },
        "arm64": {
            "url": "https://nodejs.org/dist/v22.6.0/node-v22.6.0-win-arm64.7z",
            "hash": "c17433d0efdd6ca8e14af168b6301a992d2bfeeab83c1fb11efa0c8e7f275d91",
            "extract_dir": "node-v22.6.0-win-arm64"
        }
    },
    "persist": [
        "bin",
        "cache"
    ],
    "env_add_path": [
        "bin",
        "."
    ],
    "post_install": [
        "# Set npm prefix to install modules inside bin and npm cache so they persist",
        "Set-Content -Value \"prefix=$persist_dir\\bin`ncache=$persist_dir\\cache\" -Path \"$dir\\node_modules\\npm\\npmrc\""
    ],
    "checkver": {
        "url": "https://nodejs.org/dist/index.json",
        "jsonpath": "$..version",
        "regex": "v([\\d.]+)"
    },
    "autoupdate": {
        "architecture": {
            "64bit": {
                "url": "https://nodejs.org/dist/v$version/node-v$version-win-x64.7z",
                "extract_dir": "node-v$version-win-x64"
            },
            "32bit": {
                "url": "https://nodejs.org/dist/v$version/node-v$version-win-x86.7z",
                "extract_dir": "node-v$version-win-x86"
            },
            "arm64": {
                "url": "https://nodejs.org/dist/v$version/node-v$version-win-arm64.7z",
                "extract_dir": "node-v$version-win-arm64"
            }
        },
        "hash": {
            "url": "$baseurl/SHASUMS256.txt.asc"
        }
    }
}

@suzuki-shunsuke
Copy link
Member

Please try pre-release versions and give your feedback!

Dear folks,
we are working on the support of Node.js.

About the history of Node.js support, please see the following links too.

Unlike other aqua features, Node.js support tightly depends on shell such as Bash and Zsh, so tests on various environments are necessary.
We are testing the feature on our laptops and it works fine, but we need your help.
If you're interested in this feature, could you try it out and give your feedback?

If you help us, we can find and fix bugs, improve the quality, and release this feature officially quickly.
On the other hand, if we can't get your help, we can't test this feature fully, and it takes more time to release this feature officially and the release may include bugs.
So, we need your help!

If you have any feedback, please post comments to this issue or the pull request.

Supported environment

  • Shell: Bash and Zsh
    • Other shells such as Fish haven't been supported yet. Your contribution is welcome
  • OS: macOS and Linux
    • Windows hasn't been supported yet. Your contribution is welcome

Set up

  1. Install pre-release versions

This feature hasn't been released officially yet.
So you need to use pre-release versions.

aqua upa v2.31.0-1
registries:
  - type: standard
    ref: v4.215.0-2 # renovate: depName=aquaproj/aqua-registry
packages:
  - name: nodejs/[email protected]
  1. Add scripts to .bashrc or .zshrc

And you need to add scripts to your shell configuration

.bashrc

eval "$(aqua set-shell bash)"

.zshrc

eval "$(aqua set-shell zsh)"

Note that aqua set-shell hasn't been released officially. So aqua v2.31.0-1 is required.

  1. Launch a new shell or reload your shell configuration to reflect the update of shell configuration

Try

  1. Install Node.js
  2. Check versions of Node.js and npm
  3. Install CLI using npm
  4. Run a command installed by npm
  5. Change the version of Node.js
  6. Check versions of Node.js and npm
  7. Install CLI using npm
  8. Run a command installed by npm
aqua i -l
node -v
npm -v
npm i -g zx # Install a command `zx` https://github.com/google/zx
zx -v
aqua up [email protected] # Change the node version
node -v
npm -v
npm i -g zx
zx -v

In this example, we install zx, but off course you can also install other tools.

How does this feature work?

This is the detail of the feature, so you don't have to read this section necessarily.

npm i -g installs command line tools on the same directory with npm, so aqua needs to add the directory to the environment variable $PATH to allow you to execute those tools.
And the path depends on the version of Node.js, so aqua needs to change $PATH when the version of Node.js is changed.
To do that, you need to configure your shell.
The configuration depends on the type of shells.

In case of Zsh, aqua uses the hook function (add-zsh-hook preexec).
In case of Bash, aqua uses the $PROMPT_COMMAND.
The command aqua set-output outputs the snippet for your shell.
The snippet depends on the type of shells, so you need to specify the shell type.
Supported shell types are bash and zsh.

eval "$(aqua set-shell <shell type>)"

aqua set-shell uses the command aqua output-shell.
aqua output-shell is a hidden command as you don't have to be aware of this command.
aqua output-shell does the following things.

  1. Read all aqua.yaml including global configuration files
  2. Check if each package has the .shell.env.PATH setting

e.g.

        shell:
          env:
            PATH: node-{{.Version}}-{{.OS}}-{{.Arch}}/bin
  1. Restore paths which the previous run of aqua output-shell is outputted and compare them to the current result
  2. Output export PATH=%s to update the environment variable $PATH and save it to a file. If there is no change of $PATH, output nothing

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke I use aqua on Windows, so I won't be able to test this out, but thanks for the detailed feedback.

TL;DR The set-shell method looks like a valuable contribution that will enable this and other (python?) workflows. That being said, it may be good to document the other ways one might achieve this functionality without set-shell, in case other nuances are discovered. As you indicated, the set-shell method introduces a strong dependency on the platform and shell, and requires careful consideration and lots of testing. The other methods presented below are mostly shell/platform independent and more likely to translate to both windows and linux/macos with minimal testing.

The details

You mentioned the following:

npm i -g installs command line tools on the same directory with npm, so aqua needs to add the directory to the environment variable $PATH to allow you to execute those tools.

In response to your statement above, I just wanted to add more details about other options available:

According to the npm docs:

https://docs.npmjs.com/cli/v10/commands/npm-install#global

Operates in "global" mode, so that packages are installed into the prefix folder instead of the current working directory. See folders for more on the differences in behavior.

packages are installed into the {prefix}/lib/node_modules folder, instead of the current working directory.
bin files are linked to {prefix}/bin
man pages are linked to {prefix}/share/man

And:

https://docs.npmjs.com/cli/v10/configuring-npm/folders#prefix-configuration

The prefix config defaults to the location where node is installed. On most systems, this is /usr/local. On Windows, it's %AppData%\npm. On Unix systems, it's one level up, since node is typically installed at {prefix}/bin/node rather than {prefix}/node.exe.

When the global flag is set, npm installs things into this prefix. When it is not set, it uses the root of the current package, or the current working directory if not in a package already.

And:

https://docs.npmjs.com/cli/v10/using-npm/config#prefix

Default: In global mode, the folder where the node executable is installed. Otherwise, the nearest parent folder containing either a package.json file or a node_modules folder.
Type: Path
The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder.

And:

https://docs.npmjs.com/cli/v10/using-npm/config#npmrc-files

The four relevant files are:

per-project configuration file (/path/to/my/project/.npmrc)
per-user configuration file (defaults to $HOME/.npmrc; configurable via CLI option --userconfig or environment variable $NPM_CONFIG_USERCONFIG)
global configuration file (defaults to $PREFIX/etc/npmrc; configurable via CLI option --globalconfig or environment variable $NPM_CONFIG_GLOBALCONFIG)
npm's built-in configuration file (/path/to/npm/npmrc)
See npmrc for more details.

And:

https://docs.npmjs.com/cli/v10/using-npm/config#environment-variables

Any environment variables that start with npm_config_ will be interpreted as a configuration parameter. For example, putting npm_config_foo=bar in your environment will set the foo configuration parameter to bar. Any environment configurations that are not given a value will be given the value of true. Config values are case-insensitive, so NPM_CONFIG_FOO=bar will work the same. However, please note that inside scripts npm will set its own environment variables and Node will prefer those lowercase versions over any uppercase ones that you might set. For details see this issue.

Notice that you need to use underscores instead of dashes, so --allow-same-version would become npm_config_allow_same_version=true.

Given all that context, the following methods could also be used:

NPM_CONFIG_PREFIX

Aqua set-shell could set the NPM_CONFIG_PREFIX environment variable:

export NPM_CONFIG_PREFIX=$(aqua root-dir)/npm-global

The docs could then be updated to:

export PATH="$(aqua root-dir)/bin:$(aqua root-dir)/npm-global/bin:$PATH"

Ideally, set-shell wouldn't be necessary, and the aqua-shim for npm (and node?) will just set NPM_CONFIG_PREFIX before calling into npm.

However, set-shell has the potential to replace this aqua setup step. In which case, using set-shell would be preferred.

In the case where the npm (and npx?) aqua-shim sets the process environment variable, it could also read the package file and use that information to set process environment variables, e.g.:

shim:
          env:
            NPM_CONFIG_PREFIX: {{.AQUA_ROOT_DIR}}/npm-global

npmrc File

Another solution is to do nothing at the implementation level, but add documentation to guide users to create a .npmrc file in their project (next to their aqua.yaml or their package.json) file with the following content:

prefix=/path/to/directory

Users would still need to update their PATH:

> export PATH="$(aqua root-dir)/bin:/path/to/directory/bin:$PATH"

NODE_PATH

The environment (whether through set-shell or whether through the aqua-shim for node and npm), could set the NODE_PATH environment variable:

export NODE_PATH="$(aqua root-dir)/node-path"

This doesn't tell npm where to install packages, but it does tell node where to look for globally installed packages.

@suzuki-shunsuke
Copy link
Member

@W1M0R

Thank you for your suggestion.
I didn't know the details.
I thought aqua has to support changing the environment variable $PATH dynamically because the location where npm i -g installs tools depends on the Node.js version.
But if we configure NPM_CONFIG_PREFIX or NODE_PATH, the location would be fixed so aqua doesn't have to change the environment variables. It's interesting.

When we configure NPM_CONFIG_PREFIX or NODE_PATH, the install location would be shared between multiple Node.js versions.
This would have both pros and cons.

pros:

We can share tools between multiple Node.js versions. We don't have to reinstall tools when we change Node.js versions.

cons:

The share of the install path between multiple Node.js versions may cause some trouble.

@suzuki-shunsuke
Copy link
Member

The other methods presented below are mostly shell/platform independent and more likely to translate to both windows and linux/macos with minimal testing.

This is very awesome.

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke This is true:

cons:

The share of the install path between multiple Node.js versions may cause some trouble.

One way to achieve separation if this is a problem, is to isolate the aqua environments on a per-project level. This is how I am currently doing it:

Using a justfile to control my environment for a project, I have the following configuration:

# this is the key part (every project has its own AQUA_ROOT_DIR so that they don't interfere with each other)
export AQUA_ROOT_DIR := join(env("LOCALAPPDATA"), "aquaproj-aqua-project-1")

aqua_bin := join(AQUA_ROOT_DIR, "bin")
aqua_node := join(AQUA_ROOT_DIR, "npm-global/bin")
export PATH := aqua_bin + ";" + aqua_node + ";" + env("PATH")

init:
  aqua i
  npm install -g zx
  zx -v

Running the just init recipe, will use aqua to install packages. All just recipes defined in this justfile will execute with that PATH configuration.

So if I have another project that uses a different version of node/npm, I'll just modify the AQUA_ROOT_DIR in its justfile to:

export AQUA_ROOT_DIR := join(env("LOCALAPPDATA"), "aquaproj-aqua-project-2")

I install aqua globally via scoop, e.g. scoop install aqua. So all projects use the same version of aqua, but every project's justfile configures an isolated aqua environment for that project.

If I wanted to use the set-shell method instead, I would need to adjust the justfile to look like this (assuming set-shell has a PowerShell implementation for Windows):

init:
  #!pwsh.exe
  aqua set-shell pwsh | out-string | iex
  aqua i
  npm install -g zx
  zx -v

This approach would be a bit more cumbersome, since I'd either have to do set-shell before I execute my just recipes, or I have to call set-shell inside every just recipe. It's not a problem though, it would only require a different per-project setup.

The set-shell pattern will probably be required for other stuff in the long run, since it seems to be a common pattern among the other projects:

  1. https://pixi.sh/latest/reference/cli/#shell-hook
  2. https://moonrepo.dev/docs/proto/commands/activate#pwsh
  3. https://vfox.lhan.me/guides/quick-start.html#_2-hook-vfox-to-your-shell
  4. https://docs.pkgx.sh/using-pkgx/shell-integration
  5. https://mise.jdx.dev/getting-started.html#_2a-activate-mise

@suzuki-shunsuke
Copy link
Member

Hmm. I think it's a bit hard to change AQUA_ROOT_DIR by Node.js version.
If we manage Node.js in a project and Node.js is updated by Renovate, we need to update AQUA_ROOT_DIR too somehow.
Otherwise, AQUA_ROOT_DIR can't solve the above issue.

This is how I am currently doing it:

BTW, I'm wondering why you change AQUA_ROOT_DIR by project.
Basically, aqua shares AQUA_ROOT_DIR between all projects (aqua.yaml), but I don't think this is an issue because all packages and their versions are installed in different paths and they don't conflict each other.
You should be able to change tool versions in multiple projects without any problem.

The set-shell pattern will probably be required for other stuff in the long run, since it seems to be a common pattern among the other projects:

I understand, but I don't want to support this pattern as much as possible because it tightly depends on environments.
aqua has already supported much more tools than alternatives such as asdf and mise.
And current aqua's approach enables Lazy Install, which provides awesome UX.

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 22, 2024

One of problems of aqua set-shell is that it doesn't work in non interactive shell such as shell scripts.
Even if the version of Node.js is changed in shell scripts, the hook mechanism such as Zsh's hook function and Bash's PROMPT_COMMAND doesn't work.

I'm not sure how aqua alternatives such as asdf address this issue.

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke

BTW, I'm wondering why you change AQUA_ROOT_DIR by project.
Basically, aqua shares AQUA_ROOT_DIR between all projects (aqua.yaml), but I don't think this is an issue because all packages and their versions are installed in different paths and they don't conflict each other.
You should be able to change tool versions in multiple projects without any problem.

I might be doing some unnecessary steps then. Thanks for highlighting this, I'll adjust my approach and see if I can remember why I did this in the first place.

I understand, but I don't want to support this pattern as much as possible because it tightly depends on environments.
aqua has already supported much more tools than alternatives such as asdf and mise.
And current aqua's approach enables Lazy Install, which provides awesome UX.

I agree. I like the aqua approach very much.

One of problems of aqua set-shell is that it doesn't work in non interactive shell such as shell scripts.
Even if the version of Node.js is changed in shell scripts, the hook mechanism such as Zsh's hook function and Bash's PROMPT_COMMAND doesn't work.

Good to know this limitation.

@bluegumcity
Copy link

Initial testing shows that it works perfect with pulumi and typescript 👍

@suzuki-shunsuke
Copy link
Member

Thank you for your feedback! Awesome!
Could you tell us your environment?

  • OS: macOS or Linux
  • Shell: Bash or Zsh

@bluegumcity
Copy link

Thank you for your feedback! Awesome! Could you tell us your environment?

  • OS: macOS or Linux
    Linux, Fedora 40
  • Shell: Bash or Zsh
    Bash

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 22, 2024

Same as NPM_CONFIG_PATH, pip can also change the install path by the environment variable PIP_TARGET.

https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-t

So aqua can also support Python by same approach without aqua set-shell.
So except for the issue The share of the install path between multiple Node.js versions may cause some trouble, this approach is great, so I'm thinking if we can adopt this approach.

In case of Node.js

  1. Use aqua-registry v4.215.0-2

You don't have to use aqua's pre-release version.

registries:
  - type: standard
    ref: v4.215.0-2 # renovate: depName=aquaproj/aqua-registry
packages:
  - name: nodejs/[email protected]

Set the environment variable.

export NPM_CONFIG_PREFIX="$(aqua root-dir)/npm-global" # You can change the path freely
export PATH=$NPM_CONFIG_PREFIX/bin:$PATH

Then you can install Node.js, and install and execute tools by npm.

aqua i
npm i -g zx
which zx
zx -v
aqua up [email protected]
zx -v
node -v
npm -v

I've confirmed it works fine on my laptop.

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

Thanks for confirming @suzuki-shunsuke. It doesn't look like this works in Windows yet. My aqua g does show that node is available, but when I add it to my aqua.yaml, it doesn't install it.

@suzuki-shunsuke
Copy link
Member

@suzuki-shunsuke
Copy link
Member

Could you try this? aquaproj/aqua-registry@b1b803e

registries:
  - type: standard
    ref: b1b803eb9e1eb9759908616413978dc1d6f92eea

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke I get the following:

❯ aqua i -l
INFO[0000] creating a hard link to aqua-proxy            aqua_version=2.30.0 command=corepack env=windows/amd64 program=aqua
INFO[0000] creating a hard link to aqua-proxy            aqua_version=2.30.0 command=node env=windows/amd64
 program=aqua
INFO[0000] creating a hard link to aqua-proxy            aqua_version=2.30.0 command=npm env=windows/amd64 program=aqua
INFO[0000] creating a hard link to aqua-proxy            aqua_version=2.30.0 command=npx env=windows/amd64 program=aqua

❯ node --version
INFO[0000] download and unarchive the package            aqua_version=2.30.0 env=windows/amd64 exe_name=node package_name=nodejs/node package_version=v22.6.0 program=aqua registry=standard
Downloading nodejs/node v22.6.0 100% |███████████████████████████████████████| (34/34 MB, 10 MB/s)        
INFO[0008] rename a file                                 aqua_version=2.30.0 env=windows/amd64 exe_name=node file_name=corepack new="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\corepack.exe" old="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\corepack" package_name=nodejs/node package_version=v22.6.0 program=aqua registry=standard      
INFO[0008] rename a file                                 aqua_version=2.30.0 env=windows/amd64 exe_name=node file_name=npm new="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\npm.exe" old="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\npm" package_name=nodejs/node package_version=v22.6.0 program=aqua registry=standard
INFO[0008] rename a file                                 aqua_version=2.30.0 env=windows/amd64 exe_name=node file_name=npx new="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\npx.exe" old="C:\\Users\\user2\\AppData\\Local\\aquaproj-aqua-sdl-tms\\pkgs\\http\\nodejs.org\\dist\\v22.6.0\\node-v22.6.0-win-x64.zip\\node-v22.6.0-win-x64\\npx" package_name=nodejs/node package_version=v22.6.0 program=aqua registry=standard
v22.6.0

❯ npm --version 
FATA[0000] aqua failed                                   aqua_version=2.30.0 env=windows/amd64 error="it failed to start the process" exe_name=npm package_name=nodejs/node package_version=v22.6.0 program=aqua

❯ npx --version
FATA[0000] aqua failed                                   aqua_version=2.30.0 env=windows/amd64 error="it failed to start the process" exe_name=npx package_name=nodejs/node package_version=v22.6.0 program=aqua

❯ node --version
v22.6.0

❯ gcm node | select source -expandproperty source
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl-tms\bin\node.exe

❯ gcm npm | select source -expandproperty source 
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl-tms\bin\npm.exe

❯ gcm npx | select source -expandproperty source
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl-tms\bin\npx.exe

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 22, 2024

Thank you for your confirmation.

Hmm. This setting may be wrong.

            files:
              - name: corepack
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/corepack
              - name: node
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/node
              - name: npm
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/npm
              - name: npx
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/npx

We need to download the tarball and check the correct paths of them.

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 22, 2024

Could you try this? aquaproj/aqua-registry@e833e85

registries:
  - type: standard
    ref: e833e85f301e8ed08c06c253463028bef80b8b8d

I've confirmed that it works fine on GitHub Actions Windows Runner using action-tmate.

runneradmin@fv-az534-393 MINGW64 /d/a/aqua-registry/aqua-registry
# node -v                                                                                                                                      
v22.6.0

runneradmin@fv-az534-393 MINGW64 /d/a/aqua-registry/aqua-registry
# npm -v
10.8.2

runneradmin@fv-az534-393 MINGW64 /d/a/aqua-registry/aqua-registry
# npx -v                                                                                                                                       
10.8.2

runneradmin@fv-az534-393 MINGW64 /d/a/aqua-registry/aqua-registry
# corepack -v                                                                                                                                  
0.29.3

🤔 $NPM_CONFIG_PREFIX doesn't work well on GitHub Actions Windows Runner.

# echo $NPM_CONFIG_PREFIX
C:\Users\runneradmin\AppData\Local\aquaproj-aqua\npm-global

# aqua exec -- npm i -g zx                                                                                                                     

changed 5 packages in 2s

# which zx
/c/npm/prefix/zx

# ls $NPM_CONFIG_PREFIX
ls: cannot access 'C:\Users\runneradmin\AppData\Local\aquaproj-aqua\npm-global': No such file or directory

# ls "C:\Users\runneradmin\AppData\Local\aquaproj-aqua"
bin  internal  pkgs  policies

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke

The binaries work:

❯ node --version
INFO[0000] download and unarchive the package            aqua_version=2.30.0 env=windows/amd64 exe_name=node package_name=nodejs/node package_version=v22.6.0 program=aqua registry=standard
Downloading nodejs/node v22.6.0 100% |████████████████████████████████████████████| (34/34 MB, 7.4 MB/s)
v22.6.0

❯ npx --version 
10.8.2

❯ npm -v       
10.8.2

❯ corepack -v
0.29.3

❯ gcm npx | select source -expandproperty source
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl\bin\npx.exe

❯ gcm node | select source -expandproperty source                 
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl\bin\node.exe

❯ gcm corepack | select source -expandproperty source             
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl\bin\corepack.exe

❯ gcm npm | select source -expandproperty source     
C:\Users\user2\AppData\Local\aquaproj-aqua-sdl\bin\npm.exe

I'll test the NPM_CONFIG_PREFIX next.

The error you are getting here is a common occurrence when running native windows programs in a mingw64 environment:

ls $NPM_CONFIG_PREFIX
ls: cannot access 'C:\Users\runneradmin\AppData\Local\aquaproj-aqua\npm-global': No such file or directory

You can try setting NPM_CONFIG_PREFIX using unix paths in your runner:

# echo $NPM_CONFIG_PREFIX
/c/Users/runneradmin/AppData/Local/aquaproj-aqua/npm-global

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke Setting NPM_CONFIG_PREFIX and updating my path works as expected!

My justfile:

export NPM_CONFIG_PREFIX := join(source_directory(), ".npm")
export PATH := NPM_CONFIG_PREFIX + path_sep + aqua_bin + path_sep + proto_shims + path_sep + proto_bin + path_sep + GOBIN + path_sep + tms_bin + path_sep + tms_node_bin + path_sep + env("PATH")

check-bla:
  echo "$Env:NPM_CONFIG_PREFIX"
  aqua exec -- npm i -g zx
  gcm zx | select source -ExpandProperty source
  zx --version

Running the check-bla recipe:

❯ just check-bla
echo "$Env:NPM_CONFIG_PREFIX"
C:\Users\user2\sdl\src\tms\.npm
aqua exec -- npm i -g zx

changed 5 packages in 1s
gcm zx | select source -ExpandProperty source
C:\Users\user2\sdl\src\tms\.npm\zx.ps1
zx --version
8.1.4

@suzuki-shunsuke
Copy link
Member

Great! Thank you!

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke It also works with an older version of node:

- name: nodejs/[email protected]
❯ just check-bla
echo "$Env:NPM_CONFIG_PREFIX"
C:\Users\user2\sdl\src\tms\.npm
uutils.exe rm -rf "$Env:NPM_CONFIG_PREFIX"
aqua i -l
npm i -g zx
INFO[0000] download and unarchive the package            aqua_version=2.30.0 env=windows/amd64 exe_name=npm package_name=nodejs/node package_version=v20.12.2 program=aqua registry=standard
Downloading nodejs/node v20.12.2 100% |████████████████████████████████████████████| (30/30 MB, 7.6 MB/s)        

added 5 packages in 3s
gcm zx | select source -ExpandProperty source
C:\Users\user2\sdl\src\tms\.npm\zx.ps1
zx --version
8.1.4
node --version
v20.12.2
npm --version
10.5.0
npx --version
10.5.0

@W1M0R
Copy link
Author

W1M0R commented Aug 22, 2024

@suzuki-shunsuke Thanks for all your efforts. Let me know if there is anything else you'd like me to check.

@Kesin11
Copy link

Kesin11 commented Aug 22, 2024

It works perfectly for me too. I try it with my simple nodejs repository on Codespaces.

First I installed nodejs/[email protected] and then aqua up [email protected] . Both nodejs worked with tsc and vitest.

$ uname -a
Linux codespaces-36f6f5 6.5.0-1022-azure #23~22.04.1-Ubuntu SMP Thu May  9 17:59:24 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

@W1M0R
Copy link
Author

W1M0R commented Aug 23, 2024

@suzuki-shunsuke The node tarball also contains npm.ps1 and npx.ps1. Can you also add those files to aquaproj/aqua-registry@e833e85

Running from inside powershell, calling into ps1 scripts is more convenient than calling into cmd files.

My current workaround is to install node via aqua, but then replace the npm using npm itself:

❯ aqua i -l
❯ npm install -g npm
❯ ls $Env:NPM_CONFIG_PREFIX 

    Directory: C:\Users\user2\sdl\src\tms\.npm

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2024/08/23    09:58                node_modules
-a---          2024/08/23    09:58            405 npm
-a---          2024/08/23    09:58            333 npm.cmd
-a---          2024/08/23    09:58            837 npm.ps1
-a---          2024/08/23    09:58            405 npx
-a---          2024/08/23    09:58            333 npx.cmd
-a---          2024/08/23    09:58            837 npx.ps1

❯ gcm npm | select source -expandproperty source
C:\Users\user2\sdl\src\tms\.npm\npm.ps1

❯ gcm npx | select source -expandproperty source
C:\Users\user2\sdl\src\tms\.npm\npx.ps1

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 23, 2024

Do you mean to replace *.cmd with *.ps1?

              - name: npm
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/npm.ps1
              - name: npx
                src: node-{{.Version}}-{{.OS}}-{{.Arch}}/npx.ps1

aqua associates commands such as npm and npx with files such as npm.cmd and npx.cmd, which means aqua can't associate multiple files (e.g. npm.cmd and npm.ps1) with a same command.

@W1M0R
Copy link
Author

W1M0R commented Aug 23, 2024

@suzuki-shunsuke Ok that makes sense. I was just wondering why a ctrl+c was asking to "Terminate a command". Maybe it is something else (although using the ps1 does resolve the issue). Don't worry about it, it is probably something else in my environment.

I reverted back to using the aqua npm.exe and npx.exe, they work fine.

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 23, 2024

Thank you guys. @W1M0R @bluegumcity @Kesin11
Thanks to your help, we would be able to release Node.js support soon.
Especially, thank you @W1M0R . Your suggestion lead us to the right way.

Through the above discussion, we decided to use npm's prefix config instead of adding aqua set-shell command.
So if you updated your shell configuration file such as .bashrc and .zshrc according to #2996 (comment) , please revert the update.

eval "$(aqua set-shell <bash|zsh>)" # Remove this

Instead, please configure npm's prefix config.

export NPM_CONFIG_PREFIX="${XDG_DATA_HOME:-$HOME/.local/share}/npm-global" # You can change the path freely
export PATH=$NPM_CONFIG_PREFIX/bin:$PATH

About npm's prefix config, please see #2996 (comment)

Remaining tasks

@suzuki-shunsuke suzuki-shunsuke pinned this issue Aug 24, 2024
@suzuki-shunsuke
Copy link
Member

All task has been done.
Thank you for your contribution!

Node.js support is out 🎉
https://aquaproj.github.io/docs/reference/nodejs-support/

@W1M0R
Copy link
Author

W1M0R commented Aug 24, 2024

Thanks @suzuki-shunsuke. Just a windows specific note (the documentation site may need to state this):

❯ exa $Env:NPM_CONFIG_PREFIX                                                                     
node_modules  npm  npm.cmd  npm.ps1  npx  npx.cmd  npx.ps1  zx  zx.cmd  zx.ps1

Notice there is no bin subfolder in the NPM_CONFIG_PREFIX directory on windows.

So the PATH export must look like this on Windows:

$Env:PATH = "$NPM_CONFIG_PREFIX;$PATH"

Also, I find it useful for aqua bins to take preference (because aqua is more declarative and responds to version changes automatically), so I do this:

$Env:PATH = "$AQUA_ROOT_DIR/bin;$NPM_CONFIG_PREFIX;$PATH"

@suzuki-shunsuke
Copy link
Member

suzuki-shunsuke commented Aug 24, 2024

Thank you. I'll update the document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Status: Backlog
Development

No branches or pull requests

4 participants