1 | # clark
|
2 |
|
3 | [![Greenkeeper badge](https://badges.greenkeeper.io/ianwremmel/clark.svg?token=42b42c90636529800fa4f28c6cb8fa617b6bfa4a45ccf892c6c5a3128b7fd4c8&ts=1521139102309)](https://greenkeeper.io/)
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
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 |
|
25 |
|
26 | > Monorepo tools
|
27 |
|
28 | Clark 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
|
45 | npm install @ianwremmel/clark
|
46 | ```
|
47 |
|
48 | ## Usage
|
49 |
|
50 | Unlike [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 |
|
67 | When 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 |
|
71 | Simply 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
|
95 | clark --help
|
96 | ```
|
97 |
|
98 | #### List all packages
|
99 |
|
100 | ```bash
|
101 | clark list
|
102 | ```
|
103 |
|
104 | #### Migrate all packages' dependencies to the root
|
105 |
|
106 | ```bash
|
107 | clark 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
|
115 | clark hoist --package
|
116 | ```
|
117 |
|
118 | #### Run a command in each package directory
|
119 |
|
120 | ```bash
|
121 | clark exec <command>
|
122 | ```
|
123 |
|
124 | The 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 |
|
131 | The script will be invoked from within the package's directory.
|
132 |
|
133 | #### Run a command in a single package directory
|
134 |
|
135 | ```bash
|
136 | clark exec <command> --package <packagename>
|
137 | ```
|
138 |
|
139 | The script will be invoked from within the package's directory.
|
140 |
|
141 | #### Run npm scripts with default fallbacks
|
142 |
|
143 | While 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 |
|
149 | Package 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 |
|
153 | For 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 |
|
166 | but 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 |
|
183 | PRs Welcome
|
184 |
|
185 | ### Development
|
186 |
|
187 | Use `ts-node` to test your changes without rebuilding
|
188 |
|
189 | ```bash
|
190 | ts-node ./src/cli.ts --help
|
191 | ```
|
192 |
|
193 | ## License
|
194 |
|
195 | [MIT](LICENSE) © [Ian Remmel](https://github.com/ianwremmel) 2018 until at least now
|