nix: add docs about NodeJS modules, small refactor

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2020-12-02 13:40:23 +01:00
parent 458ef05740
commit c62abf10c1
No known key found for this signature in database
GPG Key ID: 4EF064D0E6D63020
4 changed files with 105 additions and 27 deletions

View File

@ -0,0 +1,18 @@
# Description
This Nix derivation takes the result of the [`nix/deps/nodejs/default.nix`](../nodejs/default.nix) derivation and adjusts it for use with Gradle.
# Details
Modules provided by `yarn2nix` are normally fine, but we use `react-native-*` packages which have their own `gradle.build` files that reference external Maven repositories:
```js
repositories {
google()
jcenter()
}
```
And these need to be patched and replaced with `mavenLocal()` to make sure Gradle doesn't try to fetch dependencies from remote repos.
This derivation symlinks most of the modules found in the `yarn2nix` result and copies the ones that require patching of `gradle.build` files in `patchGradlePhase`.
It also applies other fixes like making `BuildId` static in `patchBuildIdPhase` and fixing a Hermes bug in `patchHermesPhase`.

View File

@ -6,8 +6,14 @@
stdenv.mkDerivation {
name = "${deps.nodejs.name}-patched";
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
phases = [
"unpackPhase"
"patchGradlePhase"
"patchBuildIdPhase"
"patchHermesPhase"
"patchJavaPhase"
"installPhase"
];
# First symlink all modules as is
# WARNING: Metro has issues when dealing with symlinks!
@ -19,10 +25,10 @@ stdenv.mkDerivation {
cp -r ${deps.nodejs}/node_modules/.bin ./node_modules/
'';
# Then patch the modules that have build.gradle files
patchPhase = ''
# Patch maven and google central repositories with our own local directories.
# Patch build.gradle files in 'react-native-*' dependencies to replace
# maven and google central repositories with our own local directories.
# This prevents the builder from downloading Maven artifacts
patchGradlePhase = ''
for modBuildGradle in $(find -L ./node_modules -name build.gradle); do
relativeToNode=''${modBuildGradle#*node_modules/}
moduleName=''${relativeToNode%%/*}
@ -33,26 +39,26 @@ stdenv.mkDerivation {
fi
${patchMavenSources} $modBuildGradle
done
patchShebangs ./node_modules
'';
# Do not add a BuildId to the generated libraries, for reproducibility
patchBuildIdPhase = ''
substituteInPlace ./node_modules/react-native/ReactAndroid/src/main/jni/Application.mk --replace \
'-Wl,--build-id' \
'-Wl,--build-id=none'
'';
# Fix bugs in Hermes usage:
# https://github.com/facebook/react-native/issues/25601#issuecomment-510856047
# - Make PR builds also count as release builds
# - Fix issue where hermes command is being called with same input/output file
patchHermesPhase = ''
substituteInPlace ./node_modules/react-native/react.gradle --replace \
'targetName.toLowerCase().contains("release")' \
'!targetName.toLowerCase().contains("debug")'
'';
# Patch Java files in modules which are not yet ported to AndroidX
patchJavaPhase = ''
${nodejs}/bin/node ./node_modules/jetifier/bin/jetify
'';
installPhase = ''
mkdir -p $out
cp -R node_modules $out/

58
nix/deps/nodejs/README.md Normal file
View File

@ -0,0 +1,58 @@
# Description
This derivation uses a [yarn2nix](https://github.com/nix-community/yarn2nix) to generate a Nix store package containing all NodeJS dependencies.
# Details
If you look at [`nix/deps/nodejs/default.nix`](./default.nix) you'll see that it it loads `package.json` and `yarn.lock` files and uses them to generate the derivation:
```sh
> make nix-repl
Welcome to Nix version 2.3.9. Type :? for help.
nix-repl> pkgs.deps.nodejs
«derivation /nix/store/23mpmpjjnq7miclv6bc6ilgypy8wz69p-status-react-node-deps-1.8.0.drv»
```
You can build the derivation:
```
nix-repl> :b pkgs.deps.nodejs
this derivation produced the following outputs:
out -> /nix/store/dqb2cjyz1g6n7jic07058y26lnmgaaz9-status-react-node-deps-1.8.0
```
And look inside:
```
> cd /nix/store/dqb2cjyz1g6n7jic07058y26lnmgaaz9-status-react-node-deps-1.8.0
> ls
deps node_modules
> ls node_modules | grep react-native-image
react-native-image-crop-picker
react-native-image-resizer
react-native-image-viewing
```
# Known Issues
It's important that dependencies from GitHub are added in a correct format:
```
git+https://github.com/status-im/bignumber.js.git#v4.0.2-status
```
Notice three things:
* `git+` prefix for the `https://` URL
* Repository name ends with `.git`
* Tag or branch is added after `#` character
__WARNING__: Using branches can cause dependencies to change their hash and cause builds to fail. Using them during development is fine, but tags should be used in the final version.
If this format is not used correctly you can see issues like:
```
fatal: unable to access 'https://github.com/status-im/bignumber.js.git/': Could not resolve host: github.com
```
or
```
error Couldn't find any versions for "bignumber.js" that matches "github.com/status-im/bignumber.js.git#v4.0.2-status" in our cache (possible versions are ""). This is usually caused by a missing entry in the lockfile, running Yarn without the --offline flag may help fix this issue.
```
or
```
error Can't make a request in offline mode ("https://codeload.github.com/status-im/bignumber.js/tar.gz/f322b670969512a35c84441036a0ba4836a96428")
```

View File

@ -1,14 +1,10 @@
{ lib, yarn2nix-moretea }:
let
# Create a yarn package for our project that contains all the dependecies.
yarn2nix-moretea.mkYarnModules rec {
pname = "status-react";
name = "${pname}-node-deps-${version}";
version = lib.fileContents ../../../VERSION;
yarnLock = ../../../yarn.lock;
packageJSON = ../../../package.json;
packageJSONContent = lib.importJSON packageJSON;
in
# Create a yarn package for our project that contains all the dependecies.
yarn2nix-moretea.mkYarnModules rec {
pname = "status-react";
name = "${pname}-node-deps-${version}";
inherit version packageJSON yarnLock;
}
}