|
| 1 | +# Maintaining Dependencies |
| 2 | + |
| 3 | +Node.js depends on additional components beyond the Node.js code |
| 4 | +itself. These dependencies provide both native and JavaScript code |
| 5 | +and are built together with the code under the `src` and `lib` |
| 6 | +directories to create the Node.js binaries. |
| 7 | + |
| 8 | +All dependencies are located within the `deps` directory. |
| 9 | + |
| 10 | +Any code which meets one or more of these conditions should |
| 11 | +be managed as a dependency: |
| 12 | + |
| 13 | +* originates in an upstream project and is maintained |
| 14 | + in that upstream project. |
| 15 | +* is not built from the `preferred form of the work for |
| 16 | + making modifications to it` (see |
| 17 | + [GNU GPL v2, section 3.](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) |
| 18 | + when `make node` is run. A good example is |
| 19 | + WASM code generated from C (the preferred form). |
| 20 | + Typically generation is only supported on a subset of platforms, needs |
| 21 | + additional tools, and is pre-built outside of the `make node` |
| 22 | + step and then committed as a WASM binary in the directory |
| 23 | + for the dependency under the `deps` directory. |
| 24 | + |
| 25 | +By default all dependencies are bundled into the Node.js |
| 26 | +binary, however, `configure` options should be available to |
| 27 | +use an externalized version at runtime when: |
| 28 | + |
| 29 | +* the dependency provides native code and is available as |
| 30 | + a shared library in one or more of the common Node.js |
| 31 | + distributions. |
| 32 | +* the dependency provides JavaScript and is not built |
| 33 | + from the `preferred form of the work for making modifications |
| 34 | + to it` when `make node` is run. |
| 35 | + |
| 36 | +Many distributions use externalized dependencies for one or |
| 37 | +more of these reasons: |
| 38 | + |
| 39 | +1. They have a requirement to build everything that they ship |
| 40 | + from the `preferred form of the work for making |
| 41 | + modifications to it`. This means that they need to |
| 42 | + replace any pre-built components (for example WASM |
| 43 | + binaries) with an equivalent that they have built. |
| 44 | +2. They manage the dependency separately as it is used by |
| 45 | + more applications than just Node.js. Linking against |
| 46 | + a shared library allows them to manage updates and |
| 47 | + CVE fixes against the library instead of having to |
| 48 | + patch all of the individual applications. |
| 49 | +3. They have a system wide configuration for the |
| 50 | + dependency that all applications should respect. |
| 51 | + |
| 52 | +## Supporting externalized dependencies with native code. |
| 53 | + |
| 54 | +Support for externalized dependencies with native code for which a |
| 55 | +shared library is available can added by: |
| 56 | + |
| 57 | +* adding options to `configure.py`. These are added to the |
| 58 | + shared\_optgroup and include an options to: |
| 59 | + * enable use of a shared library |
| 60 | + * set the name of the shared library |
| 61 | + * set the path to the directory with the includes for the |
| 62 | + shared library |
| 63 | + * set the path to where to find the shared library at |
| 64 | + runtime |
| 65 | +* add a call to configure\_library() to `configure.py` for the |
| 66 | + library at the end of list of existing configure\_library() calls. |
| 67 | + If there are additional libraries that are required it is |
| 68 | + possible to list more than one with the `pkgname` option. |
| 69 | +* in `node.gypi` guard the build for the dependency |
| 70 | + with `node_shared_depname` so that is is only built if |
| 71 | + the dependency is being bundled into Node.js itself. For example: |
| 72 | + |
| 73 | +```text |
| 74 | + [ 'node_shared_brotli=="false"', { |
| 75 | + 'dependencies': [ 'deps/brotli/brotli.gyp:brotli' ], |
| 76 | + }], |
| 77 | +``` |
| 78 | + |
| 79 | +## Supporting externalizable dependencies with JavaScript codeIZA |
| 80 | + |
| 81 | +Support for an externalizable dependency with JavaScript code |
| 82 | +can be added by: |
| 83 | + |
| 84 | +* adding an entry to the `sharable_builtins` map in |
| 85 | + `configure.py`. The path should correspond to the file |
| 86 | + within the deps directory that is normally bundled into |
| 87 | + Node.js. For example `deps/cjs-module-lexer/lexer.js`. |
| 88 | + This will add a new option for building with that dependency |
| 89 | + externalized. After adding the entry you can see |
| 90 | + the new option by running `./configure --help`. |
| 91 | + |
| 92 | +* adding a call to `AddExternalizedBuiltin` to the constructor |
| 93 | + for BuildinLoader in `src/node_builtins.cc` for the |
| 94 | + dependency using the `NODE_SHARED_BUILTLIN` #define generated for |
| 95 | + the dependency. After running `./configure` with the new |
| 96 | + option you can find the #define in `config.gypi`. You can cut and |
| 97 | + paste one of the existing entries and then update to match the |
| 98 | + inport name for the dependency and the #define generated. |
| 99 | + |
| 100 | +## Supporting non-externalized dependencies with JavaScript code |
| 101 | + |
| 102 | +If the dependency consists of JavaScript in the |
| 103 | +`preferred form of the work for making modifications to it`, it |
| 104 | +can be added as a non-externalizable dependency. In this case |
| 105 | +simply add the path to the JavaScript file in the `deps_files` |
| 106 | +list in the `node.gyp` file. |
0 commit comments