Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jchip/node-flat-module
Flat module dependencies system for NodeJS
https://github.com/jchip/node-flat-module
dependencies flat module nodejs
Last synced: 3 months ago
JSON representation
Flat module dependencies system for NodeJS
- Host: GitHub
- URL: https://github.com/jchip/node-flat-module
- Owner: jchip
- Created: 2017-02-07T04:16:37.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-03-22T06:07:52.000Z (almost 7 years ago)
- Last Synced: 2024-10-06T13:47:57.176Z (3 months ago)
- Topics: dependencies, flat, module, nodejs
- Language: JavaScript
- Homepage:
- Size: 322 KB
- Stars: 10
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# node-flat-module
#### Flat module dependencies system for NodeJS
This is an implementation of a flat module dependencies system for NodeJS.
# Motivation
NodeJS's nested `node_modules` is simple and autonomous. No matter where you are, your require will find the nearest `node_modules` that contains the module you want. It's elegant and simple, but doesn't come cheap.
The cost is duplicate modules, complexity of which is shifted to package managers, and it's a hard problem for them with no deterministic or perfect solution. NPM didn't offer a package hoisting solution to flatten duplicated modules until version 3. Even with the best hoisting, there's still bound to be duplications.
Node's module system also ignores any dependencies information and leaves that only to the package managers.
These lead to issues with deterministic module install and mixed up dependencies.
In my experience of using Node, these have been a constant source of problems in development, testing, and production.
Trying to keep deterministic `node_modules` has always been tricky. NPM's shrinkwrap has been buggy and generally complicated and a clunky chore to maintain and update.
When there are some modules that are best if they are not duplicated, managing that is not easy, and edge case issues occur during run time.
During development, developers constantly changes dependencies, and lead to completely unusable `node_modules` that requires full fresh installs. I've help resolved countless mysterious issues developers faced by having them reinstall everything.
Developing with `npm link`ing a module is generally a hit or miss thing. There are so many times that I had spent a lot of time helping someone debug an issue only to find out that they are doing `npm link`, which ends up being the cause of the issue.
So instead of trying to write the best Node Package Manager with the most optimal hoisting and flattening, and locking algorithms, another approach is to address the root of the complexity, Node's `node_modules` system.
# Design Overview
* No nested `node_modules`. Only one `node_modules`.
* All modules are installed at the top level under `node_modules`. Extra nested versions are installed under a directory `node_modules/__fv_//`. Therefore, one instance of each version of any module.
* For example, `lodash` v4 is installed at `node_modules/lodash` but a nested v3.0.0 would be in `node_modules/__fv_/3.0.0/lodash`.
* Dependencies information is retained and checked at run time.
* The file `package.json` will be significant for dependencies version resolution at run time.
* When package manager installs a module, it inserts a section `_depResolutions` into `package.json`.
* For the application, a file `__fyn_resolutions__.json` will be saved to its `node_modules` directory.
* You can explicitly specify a version in code when calling `require`
* ie: `require("foo@3")` or `require("[email protected]/lib/blah")`
* In a section `extraDependencies` in package.json, you can use an array of multiple semvers for a dependency.
* In case you have a lib that uses xyz but can work with multiple versions of xyz and you want to have tests for each one.
* Mainly something for package manager to implement.
* The first one in the array would be the default resolution.
* Internally aware of linked modules to make `npm link` a more robust approach to module development.
* Linked module will have a `node_modules` directory, within which is a `__fyn_link__.json` that contains the linking and dependencies resolution info.
* Dependencies for the linked module will be solely resolved from the application's `node_modules`.
* Will fallback to original module system if no dependencies resolution information found.## A Sample
Here is how an application's `node_modules` might look like. Captured from this module's test fixtures.
![sample](docs/sample_nm.png)