UNPKG

7.6 kBMarkdownView Raw
1# clark
2
3[![Greenkeeper badge](https://badges.greenkeeper.io/ianwremmel/clark.svg?token=42b42c90636529800fa4f28c6cb8fa617b6bfa4a45ccf892c6c5a3128b7fd4c8&ts=1521139102309)](https://greenkeeper.io/)
4
5<!-- THIS FILE WAS GENERATED BY @ianwremmel/proj. PLEASE DO NOT REMOVE ANY COMMENTS THAT BEGING WITH "PROJ" -->
6
7<!-- (optional) Put banner here -->
8
9<!-- PROJ: Badges Start -->
10
11[![license](https://img.shields.io/github/license/ianwremmel/clark.svg)](https://github.com/ianwremmel/clark/blob/master/LICENSE)
12[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
13[![npm (scoped)](https://img.shields.io/npm/v/@ianwremmel/clark.svg)](https://www.npmjs.com/package/@ianwremmel/clark)
14[![npm](https://img.shields.io/npm/dm/@ianwremmel/clark.svg)](https://www.npmjs.com/package/@ianwremmel/clark)
15
16[![Greenkeeper badge](https://badges.greenkeeper.io/ianwremmel/clark.svg)](https://greenkeeper.io/)
17[![dependencies Status](https://david-dm.org/ianwremmel/clark/status.svg)](https://david-dm.org/ianwremmel/clark)
18[![devDependencies Status](https://david-dm.org/ianwremmel/clark/dev-status.svg)](https://david-dm.org/ianwremmel/clark?type=dev)
19[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
20
21[![CircleCI](https://circleci.com/gh/ianwremmel/clark.svg?style=svg)](https://circleci.com/gh/ianwremmel/clark)
22[![Coverage Status](https://coveralls.io/repos/github/ianwremmel/clark/badge.svg?branch=master)](https://coveralls.io/github/ianwremmel/clark?branch=master)
23
24<!-- PROJ: Badges End -->
25
26> Monorepo tools
27
28Clark is a toolkit for interacting with [alle-inspired](https://github.com/boennemann/alle) monorepos. This is a productization of practices found in [PouchDB](https://github.com/pouchdb/pouchdb), the [Cisco Spark JavaScript SDK](https://github.com/ciscospark/spark-js-sdk), and other monorepo projects.
29
30## Table of Contents
31
32* [Install](#install)
33* [Usage](#usage)
34 * [Alle](#alle)
35 * [Non-Alle](#non-alle)
36 * [Commands](#commands)
37* [Maintainer](#maintainer)
38* [Contribute](#contribute)
39 * [Development](#development)
40* [License](#license)
41
42## Install
43
44```bash
45npm install @ianwremmel/clark
46```
47
48## Usage
49
50Unlike [lerna](https://lernajs.io/) or similar tools, `clark` lets you keep track of your dependencies all in your main `package.json` (key benefits being significantly faster `npm install` times and the ability to use greenkeeper). In order to get this benefit, however, you'll need to follow one of two patterns ([alle](#alle) or [non-alle](#non-alle), described below). Once you pick one of those patterns and configure your repository accordingly, you can use `clark hoist`, to move your deps from you individual subpackages to your repo root.
51
52### Alle
53
54[Alle](https://github.com/boennemann/alle) was originally described as just an example of how things _could_ work, before eventually being enacted by [pouchdb](). In order to follow the Alle pattern, all of your package **must** be kept in `./packages/node_modules` and the name of each `package.json` **should** match the subfolder path (yes, this includes the org/user scope if present).
55
56**Benefits**
57
58* Alle is symlink free. It relies on the behavior of `require()` inside a `node_modules` directory to search both up the tree and in sibling folders, thus letting your packages find each other automatically.
59
60**Caveats**
61
62* Many tools have hardcoded excludes for `node_modules` and some can't be overridden at all. Perhaps most problematically, GitHub PR will collapse most of your diffs assuming that anything in `node_modules` is vendored. GitHub language stats also get confused.
63* If you already have an established project, moving every folder can be problematic.
64
65### Non-Alle
66
67When npm encounters a package version that's simply a file path (e.g. `"my-package": "file:./packages/my-package"`), it will symlink it into `./node_modules`. By putting all of our local node_modules in the top-level `package.json`, we can expose our local packages to each other without making any other repo changes.
68
69> In addition to moving dependencies to the top-level, if `clark` sees your in a non-alle monorepo, it will automatically add the local `file:` entries to the top-level as well. You may want to run hoist whenever you create a new package.
70
71Simply add your package directories the `include` section of `.clarkrc`.
72
73```json
74//.clarkrc
75{
76 "include": ["frontend/*", "backend/*"]
77}
78```
79
80**Benefits**
81
82* No need to move anything in your existing project.
83* Doesn't break GitHub.
84
85**Caveats**
86
87* Not yet tested in the wild.
88* Likely requires a very recent version of npm. (Though, clark requires node 8 or later, so this may not be an issue).
89
90### Commands
91
92#### List all commands
93
94```bash
95clark --help
96```
97
98#### List all packages
99
100```bash
101clark list
102```
103
104#### Migrate all packages' dependencies to the root
105
106```bash
107clark hoist
108```
109
110> Note that `dependencies` and `devDepenencies` are combined because the distinction loses meaning in a monorepo (arguably, they should all be devDependencies, but that's not where `npm install` defaults).
111
112#### Migrate a package's dependencies to the root
113
114```bash
115clark hoist --package
116```
117
118#### Run a command in each package directory
119
120```bash
121clark exec <command>
122```
123
124The following environment variables will be available to your script:
125
126* `CLARK_ROOT_PATH`: The monorepo's root path.
127* `CLARK_PACKAGE_REL_PATH`: The relative path within the monorepo to the package currently being acted upon.
128* `CLARK_PACKAGE_ABS_PATH`: The absolute path to the package currently being acted upon.
129* `CLARK_PACKAGE_NAME`: The name of the package being acted upon according to its `package.json`
130
131The script will be invoked from within the package's directory.
132
133#### Run a command in a single package directory
134
135```bash
136clark exec <command> --package <packagename>
137```
138
139The script will be invoked from within the package's directory.
140
141#### Run npm scripts with default fallbacks
142
143While Clark, obviously, provides its own commands, there's a set of very project specific commands that we simply can't dictate for you. These are commands like `build`, `lint`, and `test` that you want to run each independently against each package.
144
145> In documenation, we refer to "commands", but in `.clarkrc`, we use `scripts` to more closely mirror `package.json`.
146
147##### Package Commands
148
149Package commands are executed sequentially in each package directory. They may be overridden with an entry in the package's package.json.
150
151> Note: these scripts receive the same environment variables as `clark exec` and are executed within each package directory.
152
153For example, your repository might use [mocha](https://mochajs.org/) to run your integration tests
154
155```json
156//.clarkrc
157{
158 "scripts": {
159 "package": {
160 "test": "mocha 'test/*/spec/**/*.js'"
161 }
162 }
163}
164```
165
166but if one of the packages in your monorepo is a React project, you might need to test it with [jest](https://facebook.github.io/jest/)
167
168```json
169//my-react-app/package.json
170{
171 "scripts": {
172 "test": "jest 'src/**/*-spec.js'"
173 }
174}
175```
176
177## Maintainer
178
179[Ian Remmel](https://github.com/ianwremmel)
180
181## Contribute
182
183PRs Welcome
184
185### Development
186
187Use `ts-node` to test your changes without rebuilding
188
189```bash
190ts-node ./src/cli.ts --help
191```
192
193## License
194
195[MIT](LICENSE) &copy; [Ian Remmel](https://github.com/ianwremmel) 2018 until at least now