-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8eeacaa
commit 77ae991
Showing
5 changed files
with
273 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,190 @@ | ||
# veendor | ||
a tool for vendoring your npm dependencies in arbitrary remote storage | ||
A tool for stroing your npm dependencies in arbitraty storage | ||
|
||
in development... stay tuned | ||
### Features | ||
Veendor: | ||
* caches your `node_modules` in you-define-where. | ||
* bootstraps your deps **fast**. | ||
* only installs deps that have changed, effectively locking your deps. | ||
* provides multi-layered cache. | ||
* supports caching in git and local directory out-of-the-box. | ||
* supports customizing cache keys calculation. | ||
|
||
### How it works | ||
It calculates SHA-1 of `dependencies` and `devDependencies` in your `package.json`, | ||
then searches for that hash in `backends` (cache providers). | ||
If found, veendor downloads archive and unpacks your `node_modules`. Voila! | ||
If not, veendor looks at previous revisions of your `package.json` and | ||
tries to find older bundles, then installs only deps that have changed. | ||
After that, veendor uploads new bundle to all `backends`. | ||
If older bundles not found, veendor does clean `npm install` and | ||
pushes bundle for future use. | ||
|
||
### Installation and use | ||
Install veendor globally: | ||
``` | ||
npm install -g veendor | ||
``` | ||
|
||
Go to your project and add a config file (`.veendor.js` or `.veendor.json`). | ||
See section about config file below. | ||
Run `veendor install`. | ||
That's all! | ||
|
||
### Config file | ||
Veendor supports configs as nodejs-modules or JSON-files. | ||
Config file contains these sections: | ||
|
||
#### backends | ||
Required. | ||
Define your caches here. `backends` property is an array of objects. | ||
Bundles search/upload will be in order defined here. | ||
Each object has this format: | ||
```js | ||
{ | ||
alias: 'some_name', // required, choose any name you like | ||
backend: 'local', // string or module. See built-in backends and backend API sections | ||
push: true, // optional, defaults to `false`. Should bundles be pushed to this backend | ||
pushMayFail: true // optional, defaults to `false`. | ||
// `veendor install` won't fail if push to backend fails | ||
options: {} // backend-specific options | ||
} | ||
``` | ||
|
||
#### packageHash | ||
Optional, object. | ||
Used to extend cache key calculation. | ||
Right now, only `suffix` property is used. | ||
`suffix` may be string or function that returns string. | ||
Examples: | ||
```js | ||
// Suffix by arch. | ||
// Hashes will look like this: d0d5f10c199f507ea6e1584082feea229d59275b-darwin | ||
packageHash: { | ||
suffix: process.platform | ||
} | ||
``` | ||
|
||
```js | ||
// Suffix by arch and node api version | ||
// d0d5f10c199f507ea6e1584082feea229d59275b-darwin-46 | ||
packageHash: { | ||
suffix: process.platform + '-' + process.versions.modules | ||
} | ||
``` | ||
|
||
```js | ||
// Invalidate every month | ||
// d0d5f10c199f507ea6e1584082feea229d59275b-2017-7 | ||
packageHash: { | ||
suffix: () => { | ||
const date = new Date(); | ||
return date.getFullYear() + '-' + date.getMonth(); | ||
} | ||
} | ||
``` | ||
|
||
#### installDiff | ||
Optional, defaults to `true`. Enables diff installation. | ||
|
||
#### fallbackToNpm | ||
Optional, defaults to `true`. | ||
If true, runs `npm install` when bundle is not found. | ||
Use this if you want to lock deps with veendor. | ||
Should either be environmental-dependent or your backends should be populated manually. | ||
|
||
#### useGitHistory | ||
Optional. | ||
If contains `depth` property with number value, will look at | ||
that amount of git revisions of package.json. | ||
Note that only changes that affect dependencies and devDependencies count. | ||
Example: | ||
```js | ||
useGitHistory: { | ||
depth: 5 | ||
} | ||
``` | ||
|
||
### Built-in backends | ||
#### git-lfs | ||
Stores bundles in git repo. | ||
Accepts these options: | ||
```js | ||
{ | ||
repo: '[email protected]:you/your-vendors.git', // required. Git remote. | ||
compression: 'xz', // optional, defaults to 'gzip'. Also supports 'bzip2', 'xz'. | ||
defaultBranch: 'braanch' // deafult branch of your repo. Defaults to 'master' | ||
} | ||
``` | ||
Note: while supporting git-lfs is not mandatory for your remote, | ||
it's pretty much required due to future repo size regressions. | ||
Don't forget to set it up — add following to your `.gitattributes`: | ||
``` | ||
.tar.gz filter=lfs diff=lfs merge=lfs -text | ||
``` | ||
(replace `.tar.gz` with your selected compressison format) | ||
[more about git-lfs](git-lfs.github.com) | ||
|
||
#### local | ||
Stores bundles in local directory | ||
Accepts these options: | ||
```js | ||
{ | ||
directory: '/var/cache/veendor', // required. Directory to store bundles in. | ||
compression: 'xz' // optional, defaults to 'gzip'. Also supports 'bzip2', 'xz'. | ||
} | ||
``` | ||
|
||
#### Example config | ||
```js | ||
const path = require('path'); | ||
|
||
module.exports = { | ||
backends: [ | ||
{ | ||
alias: 'local', | ||
push: true, | ||
backend: 'local', | ||
options: { | ||
directory: path.resolve(process.env.HOME, '.veendor-local') | ||
} | ||
}, | ||
{ | ||
alias: 'github', | ||
push: true, | ||
backend: 'git-lfs', | ||
options: { | ||
repo: '[email protected]:you/your-vendors.git' | ||
} | ||
} | ||
], | ||
useGitHistory: { | ||
depth: 5 | ||
} | ||
}; | ||
|
||
``` | ||
|
||
### Backends API | ||
Backend should be an object with these properties: | ||
#### pull(hash, options, cacheDir) => Promise | ||
Should search for bundle with provided hash and | ||
place node_modules into `process.cwd()`. | ||
Promise resolves if succeded, rejects if not. | ||
Options is object called `backend-specific options` earlier. | ||
If backend needs to store some temp data, | ||
veendor provides a clean `cacheDir` | ||
#### push(hash, options, cacheDir) => Promise | ||
Should take node_modules from `process.cwd()` and | ||
upload it to the remote as bundle with `hash`. | ||
`options` and `cacheDir` are same as in `pull`. | ||
Promise resolves if succeded, rejects if not. | ||
#### validateOptions(options) => undefined | ||
Called upon start while validating config. | ||
Should throw error if backend-specific options in config | ||
are invalid. | ||
May mutate options to set default values. | ||
#### keepCache | ||
Boolean, optional, defaults to false. | ||
If your backend needs old calls cache for sake of efficiency, set it to true. | ||
Otherwise, `cacheDir` will be clean before every call. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters