From 0215671c6aab24e1885074761f44c502f0bb00e2 Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Fri, 27 Sep 2019 16:05:42 +0200 Subject: Initial PoC --- README.md | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 README.md (limited to 'README.md') diff --git a/README.md b/README.md new file mode 100644 index 0000000..d49980c --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +Npm.nix +======= + +Npm.nix is a project that organizes JavaScript packages with the +[Nix](https://nixos.org/nix/) package manager. + +There was [npm2nix](https://github.com/NixOS/npm2nix), then +[node2nix](https://github.com/svanderburg/node2nix). Both of them designed +to work with the [NPM package registry](https://www.npmjs.com/), and +leave you a little freedom and control. The gravest downside is that NPM +is not a repository of _source code_. Yes, some of the packages are plain +human-written JavaScript, but the others are derived from TypeScript, +Dart, and whatnot. Some require native extensions for the Node.js +runtime, which are usually precompiled and downloaded at _install_ time +(for example [node-sass](https://www.npmjs.com/package/node-sass) and +[fibers](https://www.npmjs.com/package/fibers)). + +Npm.nix fuses together the power of Nix and [the Debian Free Software +Guideline](https://www.debian.org/doc/debian-policy/). We build every +JavaScript package from its source code, we can apply any patches, we can +control what is installed. + + +To be (maybe) done +================== + +* A tool similar to [cabal2nix](https://github.com/NixOS/cabal2nix). +* Something like `nodeWithPackages`. +* Bundles. For example, a closed set of tarballs, so that NPM can install +them and resolve depenednecies offline. Or simply a bundle with `node_modules` +without symbolic links, deduplicated, etc. + + +How it works +============ + +Npm.nix basically replicates setup for Haskell or Python in +[Nixpkgs](https://nixos.org/nixpkgs). There is a predefined set of NPM +packages. The set can be extended. Each package in the set can be modified +or overriden for any particular use case. + +When building an NPM package we: + + 1. Upack its source code. + 2. Modify its `package.json` so that all dependencies were resolved to Nix store. + 3. Invoke `npm install` to populate the `node_modules` directory. + 4. Build the package. + 5. Strip `package.json`, e. g. remove `devDependencies` which are not longer needed. + 6. Pack the package and install it as a Nix derivation (unpacked, ready to use as is). + 7. Invoke `npm install` again to populate `node_modules` with runtime dependencies only. + 8. Strip `package.json` even more. + +When the package is built, its runtime dependencies are tracked by Nix through +symbolic links under its `node_modules`. Its `package.json` does not refer +any packages. A little surprise, that this approach is in line with +[Node.js recommendations](https://nodejs.org/api/modules.html). + +For example: + +``` +$ nix-build ./npmPackages/ -A _color-convert -o color-convert +these derivations will be built: + /nix/store/s30w2nskd2vk3mwylyja19bzmbwjr70v-color-name-4536ce5.drv + /nix/store/l5bkr89n5kr23fmnfgcsp05dvhl8n015-nodejs-10.16.3-color-name-1.1.4.drv + /nix/store/vk82xx042l1pf99ih4cj8yyna7vipamp-chalk-2.4.2-dummy.drv + /nix/store/wsxc4vgjwm0slq2i7zx0czzxg47y7wgy-xo-0.25.3-dummy.drv + /nix/store/zasx83qzd3dk5d9cfi5kifai3xg9vh8w-2.0.1.tar.gz.drv + /nix/store/q8rr2cgw74z2qdyhxqc12q7dxjzwa16c-nodejs-10.16.3-color-convert-2.0.1.drv +... +nodejs-10.16.3-color-convert-2.0.1 notice === Tarball Contents === +nodejs-10.16.3-color-convert-2.0.1 notice 782B package.json +nodejs-10.16.3-color-convert-2.0.1 notice 1.4kB CHANGELOG.md +nodejs-10.16.3-color-convert-2.0.1 notice 17.0kB conversions.js +nodejs-10.16.3-color-convert-2.0.1 notice 1.7kB index.js +nodejs-10.16.3-color-convert-2.0.1 notice 1.1kB LICENSE +nodejs-10.16.3-color-convert-2.0.1 notice 2.9kB README.md +nodejs-10.16.3-color-convert-2.0.1 notice 2.3kB route.js +... +shrinking RPATHs of ELF executables and libraries in /nix/store/wz943yq79k76khaglrdlafpy0f3ahiyf-nodejs-10.16.3-color-convert-2.0.1 +strip is /nix/store/sc8xmj2am32c8zvc4f7572g8r5cyxw91-binutils-2.31.1/bin/strip +patching script interpreter paths in /nix/store/wz943yq79k76khaglrdlafpy0f3ahiyf-nodejs-10.16.3-color-convert-2.0.1 +checking for references to /tmp/nix-build-nodejs-10.16.3-color-convert-2.0.1.drv-0/ in /nix/store/wz943yq79k76khaglrdlafpy0f3ahiyf-nodejs-10.16.3-color-convert-2.0.1... +/nix/store/wz943yq79k76khaglrdlafpy0f3ahiyf-nodejs-10.16.3-color-convert-2.0.1 + +$ cat color-convert/package.json +{ + "name": "color-convert", + "description": "Plain color conversion functions", + "version": "2.0.1", + "author": "Heather Arthur ", + "license": "MIT", + "repository": "Qix-/color-convert", + "files": [ + "index.js", + "conversions.js", + "route.js" + ] +} + +$ ls -lh color-convert/node_modules/ +total 4,0K +lrwxrwxrwx 1 pashev pashev 70 ene 1 1970 color-name -> ../../jbdpbcsfam331mqgylbhixsdydcsg7wd-nodejs-10.16.3-color-name-1.1.4 + +$ node +> var convert = require('./color-convert'); +undefined +> convert.keyword.rgb('blue'); +[ 0, 0, 255 ] + +$ npm i ./color-convert +... ++ color-convert@2.0.1 +added 1 package from 1 contributor in 0.838s + +$ node +> var convert = require('color-convert'); +undefined +> convert.keyword.rgb('blue'); +[ 0, 0, 255 ] + +``` + -- cgit v1.2.3