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

NodeJS_14 #2739

Closed
Closed

Conversation

MichaelHatherly
Copy link
Contributor

First, I'm aware of NodeJS.jl 😄. I think it might predate Yggdrasil perhaps, hence why it wasn't just written up as a build script here? This is mostly just to reduce the maintenance burden on @davidanthoff, if you don't mind?

  • Node version is bumped from 12.13.1 to the latest LTS 14.16.0.
  • chmod +x appears to be needed (like it was with Kaleido) on Windows for Julia 1.6. I was getting permission denied (EACCES) when using NodeJS.jl on windows CIs.
  • ExecutableProduct("node", :node), wasn't picking up the binary on Windows when I was trying this locally, perhaps it'll work on CI. Or is there something special I need to do to correctly pick up .exes?

@giordano
Copy link
Member

Executables are searched by default in the bin/ directory: https://docs.binarybuilder.org/stable/reference/#BinaryBuilderBase.ExecutableProduct

@giordano
Copy link
Member

I have no idea how this works, but perhaps all files need to be in the same directory, in case they reference each other?

@MichaelHatherly
Copy link
Contributor Author

Yeah, looks like they've to some references to each other. They also reference node_modules/ directory as well so putting them into bin breaks that. Perhaps I just need to patch the paths in npm and npx and their .cmd equivalents too.

@giordano
Copy link
Member

Alternatively, set dir_path in ExecutableProduct?

@giordano
Copy link
Member

Or move everything in bindir?

@davidanthoff
Copy link
Contributor

The main reason I opted against building node itself in NodeJS.jl was that I wanted it to work with pre-built binary node packages, and it was not clear to me whether that would work if we build node with a different compiler than the official build from the node webpage? For example, if we build it ourselves here, then we are using the default libc etc. libraries that Julia uses, right? And I was under the assumption that might then not work with prebuilt node binary packages because they might assume that the node they are running on would be using the versions of these libraries that the official node uses, which is presumably built with VS C++?

Two other random points:

  1. I think it would be super amazing if we had a way to run node in-process, rather than spawning a new process. There is a hosting API for that, and I think that is where a BinaryBuilder.jl built version of node would really come in handy. That might then not work with pre built node binary packages, but I think that would be ok, it would still be amazing if we could just pull that off.

  2. One thing that has turned out to be a problem (more so with Electron.jl than NodeJS.jl maybe) is that packages use this very much internally, and so forcing all Julia packages to always use the same version of Node is quite a bottleneck. So I was actually thinking that some future version of NodeJS.jl would allow you to specify which version of Node you want to use, and also allow use of multiple different versions at the same time. If we also start to package a BinaryBuilder.jl version of all of this, I would try to incorporate something like that from the get-go. One pretty primitive way would be to have say a NodeJS_14_jll package that is Node 14, and then separate packages for other major node versions, for example.

@MichaelHatherly
Copy link
Contributor Author

For example, if we build it ourselves here, then we are using the default libc etc. libraries that Julia uses, right? And I was under the assumption that might then not work with prebuilt node binary packages because they might assume that the node they are running on would be using the versions of these libraries that the official node uses, which is presumably built with VS C++?

Yes, we'd probably run into issues doing that. I'm not planning on building from source here, just wrapping the official binaries probably gives the most benefit here for that specific reason.

I think it would be super amazing if we had a way to run node in-process, rather than spawning a new process. There is a hosting API for that, and I think that is where a BinaryBuilder.jl built version of node would really come in handy. That might then not work with pre built node binary packages, but I think that would be ok, it would still be amazing if we could just pull that off.

Would definitely be handy to have a version like that.

One thing that has turned out to be a problem (more so with Electron.jl than NodeJS.jl maybe) is that packages use this very much internally, and so forcing all Julia packages to always use the same version of Node is quite a bottleneck. So I was actually thinking that some future version of NodeJS.jl would allow you to specify which version of Node you want to use, and also allow use of multiple different versions at the same time. If we also start to package a BinaryBuilder.jl version of all of this, I would try to incorporate something like that from the get-go. One pretty primitive way would be to have say a NodeJS_14_jll package that is Node 14, and then separate packages for other major node versions, for example.

Yes, that was my thinking as well, we do need access to different versions at times. I think that just going with the simple way of NodeJS_14_jll, etc is probably also the best way forward, then users can either pick manually which major version by requiring the jll package, and NodeJS.jl could become a "manager" package to just pulls its required binaries from the NodeJS_*_jll packages and allows switching between versions?

@davidanthoff
Copy link
Contributor

Ah, I didn't actually look at the PR, but now I see that you are also just repacking things, like I did in NodeJSBuilder! Yes, so I think for now that makes sense.

I think down the road if we wanted to host Node in process we would actually need to build it ourselves. So maybe the right way to handle that is to just at that point create another jll package, say NostedNodeJS_jll that provides a self compiled version. That would allow us for now to ignore the entire issue :)

and NodeJS.jl could become a "manager" package to just pulls its required binaries from the NodeJS_*_jll packages and allows switching between versions?

Yes, I like that a lot! Only problem I see right now is that NodeJS.jl then would require to have a dependency on ALL the major version jll packages, and they would all be downloaded at install, which seems not ideal... With artifacts we would have the option for the nice lazy stuff, but I guess with jll packages that is not in the cards... Not sure what the best solution for that is, maybe just to ignore?

Re file locations: I would definitely first try to use the dir_path option in ExecutableProduct that @giordano mentioned, I think we'll run into a lot of trouble if we try to change the directory structure ourselves.

@MichaelHatherly
Copy link
Contributor Author

That would allow us for now to ignore the entire issue :)

Exactly.

With artifacts we would have the option for the nice lazy stuff, but I guess with jll packages that is not in the cards... Not sure what the best solution for that is, maybe just to ignore?

Hmm, yeah, being able to lazy download the artifacts would be nice in NodeJS.jl rather than mass download them all.

@MichaelHatherly
Copy link
Contributor Author

Couldn't find a way to conditionally set dir_path on Windows without splitting the sources, products, and platforms and then using should_build_platform to build the right ones with the right stuff. Have I just missed some other more obvious way to do it?

It also isn't currently picking up npm and npx in the products on Windows. Not sure whether it's confused because of the existence of npm and npm.cmd...

@giordano
Copy link
Member

To have the artifacts lazy, you can pass the lazy_artifacts=true keyword argument to build_tarballs().

To have platform-dependent products... yeah, doing the should_build_platform dance is the only option at the moment unfortunately. Not nice, but it does the job

@giordano
Copy link
Member

giordano commented Mar 29, 2021

It also isn't currently picking up npm and npx in the products on Windows. Not sure whether it's confused because of the existence of npm and npm.cmd...

The problem is the extension of the files, we expect ExecutableProducts to have .exe extension on Windows: https://github.com/JuliaPackaging/BinaryBuilderBase.jl/blob/dd83f8b0189ccda4d01dd213c6c3dd089f31065a/src/Products.jl#L404-L407 We should probably allow .cmd too?

@giordano
Copy link
Member

But I feel like installing everything under ${bindir} instead of ${prefix} for Windows would be the less disruptive option, so you don't need platform-dependent products. The tree structure (and relative paths) would still be the same

@MichaelHatherly
Copy link
Contributor Author

We should probably allow .cmd too?

I guess so, they're batch files so technically "executable" even though they're not binary.

But I feel like installing everything under ${bindir} instead of ${prefix} for Windows would be the less disruptive option, so you don't need platform-dependent products. The tree structure (and relative paths) would still be the same

Yeah, having done the should_build_platform version, it'll probably be cleaner to just moving them all into ${bindir} instead. Don't think it could cause issues.

@giordano
Copy link
Member

I guess so, they're batch files so technically "executable" even though they're not binary.

Oh, wait, right, ExecutableProducts are only binaries. Anything else (like shell or batch scripts) should be FileProducts

@MichaelHatherly
Copy link
Contributor Author

I guess the last decision to make here then is whether to go with a naming scheme of NodeJS_*_jll (here NodeJS_14_jll) that @davidanthoff mentioned to leave room for a future version of NodeJS.jl as a manager package for the different versions that are built/hosted here.

@giordano
Copy link
Member

I must have missed why we can't have a single package with multiple versions. Does it make sense to have multiple node.js versions running at the same time in the same Julia environment?

@MichaelHatherly
Copy link
Contributor Author

MichaelHatherly commented Mar 29, 2021

Up in #2739 (comment):

One thing that has turned out to be a problem (more so with Electron.jl than NodeJS.jl maybe) is that packages use this very much internally, and so forcing all Julia packages to always use the same version of Node is quite a bottleneck.

I've not come across the issue in practice myself though.

@MichaelHatherly
Copy link
Contributor Author

A middle ground that I think we should just go with for now is merge this as NodeJS_jll and have it strictly follow the current LTS release of Node. When anyone actually requires using multiple versions in practice then we can go down the route of additional NodeJS_*_jlls, when the demand exists. Duplicating the script for different major versions at that point isn't much additional bookkeeping.

@MichaelHatherly
Copy link
Contributor Author

MichaelHatherly commented Mar 30, 2021

Bump, anything else we need to sort out here?

@giordano
Copy link
Member

I was waiting for final comments from @davidanthoff 🙂

@jeremiahpslewis
Copy link
Contributor

@MichaelHatherly @davidanthoff Quick question here...just started to look into what would be involved in enabling Apple Silicon support and it looks like, unfortunately, the first release with Darwin-arm64 builds is the 16.0 release. Does it make sense to add v16 support this to the PR as a separate file / as a loop over different version numbers? The plotting story for Apple Silicon and Julia is currently thoroughly broken (Plots, Makie, VegaLite) and I'd love to see VegaLite emerge as the first general plotting lib to support Apple Silicon. :)

@MichaelHatherly
Copy link
Contributor Author

I'd be in favour of having separate NodeJS_{{major_version}}_jll packages so we can pick and choose what's needed in particular situations.

The plotting story for Apple Silicon and Julia is currently thoroughly broken (Plots, Makie, VegaLite) and I'd love to see VegaLite emerge as the first general plotting lib to support Apple Silicon. :)

Yes, getting that sorted would be great.

@jeremiahpslewis
Copy link
Contributor

@MichaelHatherly Sent a PR your way to update the folder structure on this PR, bump node 14 to 14.16.1

MichaelHatherly#1

@MichaelHatherly
Copy link
Contributor Author

Thanks @jeremiahpslewis.

Copy link
Contributor

@davidanthoff davidanthoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think this is all excellent. Maybe we add the Apple silicon artifact, and then merge and ship?

Platform("x86_64", "macos"),
Platform("x86_64", "windows"),
Platform("i686", "windows"),
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I would just say it would be great if we could cover the same platforms here that I have here.

Also, I would suggest we add MacOS(:aarch64) and just package the x64 binaries into that artifact. They then work via rosetta, and folks on M1 can use it for now. And starting with node 16 we can then start to ship the native apple silicon binaries instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would suggest we add MacOS(:aarch64) and just package the x64 binaries into that artifact.

Why is that necessary? If someone is using the x86-64 Julia binary with Rosetta there is no need to have a fake aarch64-apple-darwin artifact, the x86-64 would just work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we also want it to work for folks that are using the Apple Silicon Julia binaries :)

@Pangoraw Pangoraw mentioned this pull request May 3, 2021
@MichaelHatherly MichaelHatherly changed the title NodeJS_jll NodeJS_14 May 4, 2021
Co-authored-by: David Anthoff <anthoff@berkeley.edu>
Copy link
Contributor

@davidanthoff davidanthoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this also looks ready to be merged :) Once this one here is released, I'll start to use it from Vega.jl and VegaLite.jl.

Comment on lines +13 to +15
ArchiveSource("$(url_prefix)-linux-x64.tar.gz", "068400cb9f53d195444b9260fd106f7be83af62bb187932656b68166a2f87f44"; unpack_target = "x86_64-linux-musl"),
ArchiveSource("$(url_prefix)-linux-arm64.tar.gz", "58cb307666ed4aa751757577a563b8a1e5d4ee73a9fac2b495e5c463682a07d1"; unpack_target = "aarch64-linux-musl"),
ArchiveSource("$(url_prefix)-linux-armv7l.tar.gz", "54efe997dbeff971b1e39c8eb910566ecb68cfd6140a6b5c738265d4b5842d24"; unpack_target = "arm-linux-musleabihf"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, these binaries are only for glibc I assume?

products = [
ExecutableProduct("node", :node),
FileProduct("bin/npm", :npm),
FileProduct("bin/npx", :npx),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm just realizing that this won't work: bin/npm and bin/npx are cygwin specific (I think). Instead, on Windows there are bin/npm.cmd and bin/npx.cmd batch files present that we should actually expose. But not sure how we can do that, i.e. use a different path for Windows here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be the pattern we are looking for?

FileProduct("share/$amazon_root_certificate_filename", :amazon_ca_root_certificate),

Probably need to change the node.js 16 code as well, once we figure this out

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into it further, less convinced the above link helps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seem to recall https://github.com/JuliaPackaging/Yggdrasil/blob/master/fancy_toys.jl#L15 being useful for dealing with differences in platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeremiahpslewis btw I've given you write access to my fork so you can just push direct to this branch to make this easier to finish off.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't want bin/npm and bin/npx at all in the Windows tarballs you can't delete them and have a FileProduct with multiple names. But note that FileProducts don't provide much convenience besides a variable pointing to their path, it's not like an ExecutableProduct for which we generate wrapper functions, so you may just ignore these two products in the JLL package.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what we want is a FileProduct named npm that points to bin/npm.cmd on Windows, but to bin/npm everywhere else. Same for npx.

It would actually be nice if one could use ExecutableProudct for batch files...

@quinnj
Copy link
Contributor

quinnj commented Jul 10, 2022

This doesn't seem relevant anymore since 16 is now LTS?

@quinnj
Copy link
Contributor

quinnj commented Jul 10, 2022

(and #2869 was merged)

@MichaelHatherly
Copy link
Contributor Author

Yes, let's just close this one.

@MichaelHatherly MichaelHatherly deleted the mh/nodejs branch July 10, 2022 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants