aboutsummaryrefslogtreecommitdiff
path: root/npmPackages/buildNpmPackage.nix
blob: 5ed4e999276f8fc359aa4da0e0d5b83553da4ecd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{stdenv, lib, nodejs, writeText}:

{ pname
, version
, src
, npmInputs ? [] # NPM packages used to resolve dependencies
, dropDevDependencies ? []
, buildInputs ? [] # Other build inputs
, nativeBuildInputs ? []
, patches ? []
, files ? [] # override "files" in package.json
, buildPhase ? "npm install"
, checkPhase ? "npm test"
, doCheck ? true
, jailbreak ? true # Ignore version constraints of the dependencies
, meta ? {}
}:

let

  name = "nodejs-${nodejs.version}-${pname}-${version}";

  scripts = "${./_scripts}";

in
stdenv.mkDerivation {
  inherit
    buildInputs buildPhase checkPhase doCheck meta name patches src
    ;

  outputs = [ "out" "pack" ];

  nativeBuildInputs = nativeBuildInputs ++ [ nodejs ];

  configurePhase = ''
    export HOME=$PWD

    cat << 'NPMRC' > $HOME/.npmrc
      audit = false
      heading = ${name}
      loglevel = verbose
      metrics-registry = http://localhost
      nodedir = ${nodejs}
      offline = true
      optional = false
      package-lock = false
      registry = http://localhost
      save = false
      script-shell = ${stdenv.shell}
      send-metrics = false
      update-notifier = false
    NPMRC

    ${lib.optionalString (dropDevDependencies != []) ''
      node ${scripts}/drop-dev-deps.js ${lib.concatMapStringsSep " " (f: "'${f}'") dropDevDependencies} \
      < package.json > package.json.devdeps
      mv package.json.devdeps package.json
    ''}

    node ${scripts}/resolve.js \
      ${lib.optionalString jailbreak "--jailbreak"} \
      ${toString npmInputs} < package.json > package.json.resolved
    mv package.json.resolved package.json

    rm -f package-lock.json
    npm --ignore-scripts install

    node ${scripts}/strip.js --post-configure < package.json > package.json.stripped
    mv package.json.stripped package.json

  '';

  installPhase = ''
    node ${scripts}/strip.js --pre-install < package.json > package.json.stripped
    mv package.json.stripped package.json

    ${lib.optionalString (files != []) ''
      node ${scripts}/files.js ${lib.concatMapStringsSep " " (f: "'${f}'") files} < package.json > package.json.files
      mv package.json.files package.json
    ''}

    cp package.json package.json.resolved

    node ${scripts}/pindeps.js < package.json > package.json.pinned
    mv package.json.pinned package.json

    npm pack

    mkdir -p $pack
    cp ${pname}-${version}.tgz $pack/

    mkdir -p $out
    tar xf ${pname}-${version}.tgz --strip-components=1 -C $out
    mv package.json.resolved $out/package.json

    # Link runtime depdendencies, if any, to node_modules:
    cd $out
    npm install

    # Finally, strip info about runtime dependencies,
    # so that NPM will not complain about missed or extraneous dependencies:
    node ${scripts}/strip.js --post-install < package.json > package.json.stripped
    mv package.json.stripped package.json
  '';
}