Support Haxe on NPM

I think the suggestion is to allow managing haxelibs through npm.

It would mean:

  • making the haxelibs compatible with npm (e.g. generate a package.json), including haxelib dependencies resolution, so you can use npm to manage them,
  • and finding a way for the haxe compiler to resolve haxelibs inside node_modules.

And yes we also need to install neko along with haxe from npm.

It should be easy to download neko along with haxe npm.
In the first version of this module i had a wrapper to the haxe bin to convert -lib arguments to -cp and support node_modules. It could be a solution again and maybe for the haxelib bin too.

I think we should be able to do all that things without updating haxelib.

1 Like

On that note, it should be possible to detect (and use) extraParams.hxml inline when calling the Haxe build process, if present.

There are complicated cases that could be somewhat hard to support, but the simple cases would support most projects anyway, and help make this more comfortable.

What do you think about this change on package.json management ?

  • Remove the config section
  • Use a custom property haxeDependencies
{
	"name": "application-name",
	"version": "0.0.1",
	"private": true,
	"dependencies": {
		"express": "2.4.7",
		"jade": ">= 0.0.1"
	},
	"haxeDependencies": {
		"haxe": "3.2.1",
		"haxelib": "3.2.0",
		"neko": "2.0.0",
		"pixijs": "4.5.5",
		"perfjs": "1.1.18"
	}
}

Like that, we can manage haxe, haxelib, and neko versions, and also haxelib dependencies

You’d still need haxe in the main dependencies to install your tool.

And this means that it still uses haxelib to install dependencies and not using npm or storing the libs under node_modules, right? That would be a bit a missed opportunity, isn’t it?

If we were to try managing haxelibs using npm we could try hacking a npm repository proxy that would return haxelib packages maybe? GitHub - verdaccio/verdaccio: 📦🔐A lightweight private proxy registry build in Node.js

Right, i forgot it.
We need haxe in the npm dependencies.
My exemple means i can manage haxelib dependencies but it still possible to use npm if the lib is available. It’s because there is too much relevant libs only available on haxelib.

Is it possible to set a new npm registery from package.json or from the haxe module for exemple ?
Not sure.
I was thinking about using directly haxelib cli to download dependencies into an haxe_modules folder.

I’ve been using switchx, haxeshim and lix since they were released and it just works so well. It fetches the correct haxe version (and neko if missing) while all you need to start is npm, no other requirements. If you want to setup your package.json like the typescript example above all you’d need is something like this:

// package.json
{
  "scripts": {
    "postinstall": "lix download",
    "build": "haxe build.hxml"
  },
  "devDependencies": {
    "haxeshim": "^0.9.2",
    "lix.pm": "^0.11.8"
  }
}
// .haxerc (can be created through switchx)
{
  "version": "3.4.3",
  "resolveLibs": "scoped"
}

This is will install the correct haxe version (you can even pick nightlies) and all (pinned down) haxelibs with only npm install. The .haxerc file gets created via switchx and libs managed via lix. I get that the discussion here is about managing haxelibs through npm, but if you’re actually looking for a way of managing reproducible builds right now, this is the best solution.

Mmm, what do you think if we use it as the official haxe module ? Could it be the solution ?

I like this proposal, unless our haxelibs are packaged to be compatible with NPM, it makes sense to maintain a “haxe_modules” directory, and to automatically point the local haxelib to use this directory. The main missing point is to wire up support for npm install for doing the install, but that could easily be handled with a script

Perhaps there are features from “haxeshim” that could be used in the official “haxe” module, or merged. However, I think it is important that it does work locally (and does not replace your global “haxe” script) which may already be the current behavior, I don’t like the requirement for “lix.pm” (strange name) though if someone doesn’t want to use it.

It’s all local if you need it to be. The example I presented uses npm and its scripts. Haxeshim provides the haxe bin and lix.pm the lix bin. It doesn’t mess with your existing haxe install. It would if you install switchx or haxeshim globally, but that’s true for any global npm package which provides binaries.

Most of the features in haxeshim/lix were mentioned here: [stage2] Haxelib replacement · Issue #34 · HaxeFoundation/haxe-evolution · GitHub
Lix (however strange the name) is a package manager for haxe, like haxelib, but with a few much needed features to lock down builds and is probably a lot saner to recommend than using haxelib.

I just thought I’d mention these again, because it seems people like exploring a lot of options (haxelib rewrite, libs on npm, …) while not giving what’s there already a try (and it’s pretty good!). Jason did a nice writeup here: Lix: A step forward in dependency management for Haxe projects – Jason O'Neil

Does switchx support project-local copies of Haxe, or is it designed just to switch a global context of Haxe between versions?

This is important, because Project A might use Haxe 3.4.4, while Project B is on bleeding edge, and they may be building at the same time on the same system.

npm-haxe has worked well for me, except the Haxelib it includes is not compatible with Haxe 3.4, and I find that the versioning is a bit off-putting. I would like to be able to npm install haxe@3.4.4 and know that’s the version used, but I understand why this is so.

TypeScript has a good workflow, where you npm install --save-dev typescript and forget it. I think npm install --save-dev haxe has potential to be that easy… if it gets updated with a newer Haxelib and a newer default Haxe version.

I like "haxeDependencies", but I agree with Philippe that distributing through NPM would make sense. That’s one reason I suggested the idea of @haxe/<lib> like TypeScript’s @type/ namespace, but we would need to get it sorted out right before starting, since NPM won’t allow a re-release of the same version number.

This is what haxeshim solves, although not by having project-local copies of Haxe. Rather there’s a global store for haxe versions and libraries and a convention that allows to reference them from within projects. This convention is leveraged by lix (and switchx, which has been merged into lix recently for simplicity) to provide fully replicable and isolated setups. If you want to try it without interfering with your global haxe installation, please follow this documentation: GitHub - lix-pm/lix.client: A dependable package manager for your Haxe projects

These two things are not exclusive. The registry will accept additional fields in the package.json and will even expose them through the API. I made a little experiment, and as a result you can find “haxeDependencies” in https://registry.npmjs.org/lix.pm

Hi,
I just published a new release on the beta channel haxe@4.1.4
It support now :

  • Binaries caching
  • Neko install
  • haxeDependencies

More info are available on github :
https://github.com/HaxeFoundation/npm-haxe/tree/feature/haxelib_dependencies

What do you think ?

3 Likes

This is super hot - what do the libs in haxeDependencies do? Does it haxelib install them?

Yes sir :slight_smile:
https://github.com/HaxeFoundation/npm-haxe/blob/feature/haxelib_dependencies/lib/install-haxelib-dependencies-task.js#L14

If you want try it, use haxe@beta.
this always reference the latest release.

I just published npm-haxe v5 on the main npm channel. :haxe::smile:

2 Likes

Sorry I hadn’t any time to try it yet, but I will.

1 Like

@damoebius hey I tested with Docker debian:jessie - seems to work fine for haxe and haxelib but it fails for neko.
I think the problem is neko isn’t exported in index.js:

var executable = require('./lib/executable');
var vars = require('./lib/vars');

module.exports = {
    haxe: executable( vars.haxe.path, vars.haxe.args ),
    haxelib: executable( vars.haxelib.path, vars.haxelib.args )
}

As a side note, the binary wrappers are odd:

#!/usr/bin/env node
require('..').haxe.cli();

I’m a bit surprised it works - that is it probably works by gathering all the index exports of all the node modules, so I guess it would be more reasonable to have require('haxe').haxe.cli() there.