π§ EXPERIMENTAL π§ Though I use it as a Lerna replacement, Projector is still very much in its infancy! Check out the public roadmap to see the lay of things. What follows is RDD π
Projector is a lightweight monorepo and polyrepo management toolkit with a focus on simplicity, flexibility, and performance. It's built around semantic-release, conventional-changelog, and conventional-commits for commit-based automated release flows and (optionally) GitHub Actions and Dependabot for CI/CD. It supports task concurrency and, for monorepos, topologically ordered execution and cross-dependency version coherence during release.
Projector leans on as much native npm functionality and popular tooling as possible. This means your project is never locked-in to using Projector; there are no bootstrapping commands, no custom linking, no sprawling "Projector config file," no repository commit count limits, nor any reinventions of the features that git, npm, semantic-release, conventional-changelog, and other tooling already provide.
In this way, Projector tries to avoid being Yet Another Thing you have to learn. If you know how to use git, npm, and semantic-release, you're already 90% there. Combined with life cycle plugins, Projector is flexible enough to integrate with most JS projectsβbe it authoring a library, building a serverless or JAMstack app, bundling a CLI tool, etc.
See what Projector can do for you, or just jump right in!
- Feature Overview
- System Requirements
- Installation
- Usage
- Appendix
- Terminology
- Contributing and Support
- Compatible with new and existing projects.
- Presents a unified interface for both polyrepo (normal repos) and monorepo management.
- Built on popular open source tooling.
- Projector's core feature set relies on git, npm, and semantic-release.
- Projector provides several opinionated pre-made configurations and plugins for TypeScript, webpack, Babel, Jest, and other tools, but you can (and should) easily substitute your own.
- Projector uses lage, backfill, and Threads.js for topologically-ordered concurrent script/task execution and output caching. See the Dependency Topology and Script Concurrency section for details.
- Projector uses glob for easy workspace selection, debug for debugging support, npm-check-updates to selectively update dependencies, and Inquirer.js to gather input.
- Turnkey support for Continuous Integration and Deployment with
projector-pipeline
. - Supports deep customizations through simple npm-esque life cycle
plugins.
- Projector will call an npm script (Γ la
npm run an-npm-script
) with a well-defined name, if it exists, whenever an interesting event occurs.
- Projector will call an npm script (Γ la
- Robust debugging output available on demand.
- Set
DEBUG=projector
to enable debug output when running Projector. - Set
DEBUG=projector:<projector-package-id>
to view debug output from a single Projector package.<projector-package-id>
must be the name of a directory listed here. For example:DEBUG=projector:config-babel
.
- Set
DEBUG=projector:all
(orDEBUG=projector:<projector-package-id>:all
) to view all possible debug output Projector generates, including extra information that is normally hidden (potentially very verbose).
- Set
See
@projector-js/cli
for all available CLI commands and their options.
Like npm, the
-w
option, short for "workspace," matches against 1) an exact path or parent path in theworkspaces
config or 2) an exact workspacename
. Unlike npm,-w
also supports glob matching against the aforesaid paths andname
s. For example,-w '*pkg*'
will match workspaces withname
"some-pkg-1" and "another-pkg-2" in theirpackage.json
files. The-ws
option is supported as well.
Commands executed concurrently can be run in topological order, in simple parallel, or sequentially (no concurrency) depending on CLI arguments. See the Dependency Topology and Script Concurrency section for details.
- Build one, some, or all workspaces concurrently.
projector build -w pkg-1
projector build -w pkg-1 -w pkg-2
projector build -w 'pkg-*'
projector build -ws
projector build
- Test one, some, or all workspaces concurrently.
projector test some-specific-test
projector test --coverage --collectCoverageFrom 'src/**/*.ts' some-test
projector test
- Release from one, some, or all workspaces concurrently (including
cross-dependency version coherence for monorepos).
projector publish -w pkg-1
projector publish -w pkg-1 -w pkg-2 -w pkg-3
projector publish -ws
projector publish
- Run npm scripts within one, some, or all workspaces concurrently.
projector run -w pkg-1 script-in-workspace
projector run -w pkg-1 -w pkg-2 script-in-workspace
projector run -ws script-in-some-workspaces --parallel --if-present
projector run script-at-root-only
- Run arbitrary npm commands within one, some, or all workspaces.
projector -w pkg-1 npm info
projector -w pkg-1 -w pkg-2 npm list --depth=1
projector -ws npm audit
projector npm show
- Manage both individual and shared dependencies across workspaces.
projector install -w pkg-1
projector install -w pkg-1 -w pkg-2
projector install -w 'pkg-*' -w my-workspace installed-1 installed-2
projector install -ws install-to-every-workspace
projector install --save-dev install-to-root
projector uninstall -w pkg-1 installed-2
projector uninstall -ws uninstall-from-every-workspace
- Update the dependencies of one, some, or all workspaces, optionally
committing the updates by type (e.g.
devDependencies
,peerDependencies
, etc).projector update -w packages/pkg-1
projector update -w ./packages/pkg-1 -w pkg-2
projector update --no-commits -w pkg-1 -w pkg-3
projector update --doctor -ws
projector update
- Create new projects from scratch, or from a custom template.
projector create new-project-name
projector create --monorepo
projector create new-proj-name --using /some/path/to/template
projector create --using https://github.com/u/some-repo
- Add new workspaces when the current working directory is a monorepo root.
projector create new-package
projector create --at relative/path/to/package/root
projector create @scoped/new-package --using /some/path/to/template
projector create new-package --using https://github.com/u/some-repo
- Rename/move workspaces, updating metadata where necessary and optionally
executing a regex-powered "find and replace" across the source.
projector rename -w pkg-1 --to-name a-new-name --to-path new/pkg/root
projector rename -w pkg-1 --to-name a-new-name --find-and-replace
projector rename --to-name new-name-at-root-pkg-json
- List project and workspace metadata (especially useful for monorepos).
projector list
- At the moment, Projector is only guaranteed to work on Linux (Ubuntu) systems. It likely works on any unix-based OS. Projector has not been tested on Windows or WSL, though it should work with the latter. Full Windows support may be considered in the future.
- At the moment, Projector only works with npm. It is likely a short jump to enabling Yarn and/or pnpm support and this may be considered in the future.
- Projector requires an actively maintained version of Node.js and npm be installed.
- Projector requires Git be installed.
- See each individual package's documentation for further requirements.
There are several ways to utilize Projector: as a CLI tool or npm script, as a source of shared configuration, as a GitHub Action, as a semantic-release plugin, and as an imported library.
See Getting Started for details on how to use the various components that make up Projector.
Install the omnibus Projector package locally:
npm install --save-dev projector-js
To avoid prefixing every command with npx projector
, you can install
Projector's CLI package globally:
npm install -g @projector-js/cli
This makes the p
and projector
commands available in your system's PATH.
The following tweakable (but opinionated) tooling configurations are available for Projector projects. See each individual package's documentation for details.
- Babel (
@projector-js/config-babel
) - commitlint
(
@projector-js/config-commitlint
) - conventional-changelog (
@projector-js/config-conventional-changelog
) - ESLint (
@projector-js/config-eslint
) - Husky (
@projector-js/config-husky
) - Jest (
@projector-js/config-jest
) - lint-staged (
@projector-js/config-lint-staged
) - Next.js (
@projector-js/config-next
) - Prettier (
@projector-js/config-prettier
) - semantic-release-atam (
@projector-js/config-semantic-release-atam
) - TSConfig (
@projector-js/config-tsconfig
) - webpack (
@projector-js/config-webpack
)
Unless you're using a monorepo, these configurations are entirely optional and should only be used if you don't already have your own tooling stack configured. See Projector Project Structure for more details.
Additionally, several opinionated life cycle plugins are available. Since plugins are low overhead and extremely easy to create (you don't even have to make a new file), you'll likely want to write your own instead.
@projector-js/plugin-build
@projector-js/plugin-clean
@projector-js/plugin-dev
@projector-js/plugin-format
@projector-js/plugin-github
@projector-js/plugin-lint
@projector-js/plugin-list
@projector-js/plugin-list-types
@projector-js/plugin-metrics
@projector-js/plugin-prepare
@projector-js/plugin-sync-files
@projector-js/plugin-sync-vercel
@projector-js/plugin-test
See projector-pipeline
.
For monorepos, the semantic-release plugin enforces cross-dependency version coherence and topological ordering during the release cycle. Installing this plugin is required when publishing a monorepo's packages using Projector.
First, install the plugin:
npm install --save-dev @projector-js/semantic-release-plugin
Then, add the plugin to your release.config.js
configuration file:
{
...
plugins: [
...
['@projector-js/semantic-release-plugin', { ... }],
...
],
...
}
See @projector-js/semantic-release-plugin
for more details.
Projector's core functionality can be invoked programmatically if desired.
First, install @projector-js/core
:
npm install @projector-js/core
Then import it:
import { getEslintAliases() } from '@projector-js/core/import-aliases';
console.log(getEslintAliases());
See @projector-js/core
for details.
To use Projector, you must first install the CLI.
From there, you can use projector create
to create a new monorepo or
polyrepo if you want. See Getting Started to walk through inspecting,
testing, and publishing an existing monorepo instead.
If you don't already have your own tooling setup, pre-made configurations
can be used to configure their respective tools, and are easily tweaked. For
example, @projector-js/config-eslint
can be used in .eslintrc.js
like so:
module.exports = require('@projector-js/config-eslint')((config) => {
return {
...config,
// ? Tweak the overrides key in the shared config
overrides: [
{
files: ['*.test.*'],
extends: ['plugin:jest/all', 'plugin:jest/style'],
rules: {
'jest/lowercase': 'off',
'jest/consistent-test-it': 'off'
}
}
]
};
});
If your project is a monorepo, you'll have to use semantic-release-atam (PRs pending) and the semantic-release plugin instead of the normal semantic-release. semantic-release-atam is a drop-in replacement for semantic-release. Additionally, if you're using conventional-changelog, consider using the version patched to work better with monorepos (PRs pending) instead.
Projector's primary job is to run npm scripts at the right time; Projector
plugins are portable plug and play npm scripts. See Life Cycle Scripts
(plugins) for details on Projector's plugin system. And since they're just
npm scripts with a fancy name, plugins are easy to author yourself, even
directly in the relevant package.json
file (no new file needed).
For example, the @projector-js/plugin-build
and @projector-js/plugin-format
plugins can be added to package via package.json
:
{
"name": "@my-monorepo/pkg",
"version": "2.5.8",
...
"scripts": {
"build": "npm run build-dist --",
"build-changelog": "plugin-build changelog",
"build-dist": "plugin-build dist",
"build-docs": "plugin-build docs",
"format": "plugin-format"
...
},
...
}
If you're pushing to GitHub and using GitHub Actions, you can optionally set up CI/CD for your project using Projector's GitHub Action.
Finally, you can optionally setup advanced concurrent task pipelines and caching, if desired.
You can use projector create
to initialize a new project, but suppose we
already have a monorepo we've been working on at /repos/my-project
. It has the
following structure:
Expand Example
.
βββ .git
βββ package.json
βββ package-lock.json
βββ packages/
β βββ pkg-1/
β β βββ package.json
β β βββ README.md
β β βββ src/
β βββ pkg-2/
β βββ package.json
β βββ README.md
β βββ src/
βββ test/
βββ README.md
βββ release.config.js
package.json
:
{
"name": "my-cool-monorepo",
"workspaces": ["packages/pkg-1", "packages/pkg-2"],
"scripts": {
"test": "jest --coverage --collectCoverageFrom '**/src/**/*.js' general-tests",
...
},
...
}
packages/pkg-1/package.json
:
{
"name": "pkg-1",
"version": "1.1.2",
...
}
packages/pkg-2/package.json
:
{
"name": "@my-namespace/pkg",
"version": "3.0.1",
"dependencies": {
"@my-namespace/core": "1.1.2",
...
},
...
}
git tag
:
$ git tag | cat
pkg-1@1.0.0
pkg-2@1.0.0
pkg-2@2.0.0
pkg-2@2.1.0
pkg-1@1.1.0
pkg-1@1.1.1
pkg-2@3.0.0
pkg-1@1.1.2
pkg-2@3.0.1
Note how tag structure is based on
package-id
rather than the name of the package. This is configurable.
After installing Projector's CLI, we can list information about the project.
Expand Example
$ projector list
Monday, Nov 29, 2021, 12:02:59.556 PM PST
[12:02:59.578 PM] [projector] βΊ Β» Listing project metadata
M my-cool-monorepo@ /repos/my-project [β‘Β»β!?]
βββ pkg-1@1.1.2 (β¬1.2.0) [β!]
βββ @my-namespace/pkg@3.0.1 [?]
This tells us that:
- The project is a monorepo (
M
) rather than a polyrepo (P
) - The project is named "my-cool-monorepo"
- The project's root (
rootDir
) is at/repos/my-project
- The root
package.json
does not list a version - git status reports the project is ahead of the current remote branch
(
β‘
), has renamed files (Β»
), has deleted files (β
), has unstaged changes (!
), and has untracked changes (?
). See the full list of status symbols.
γ € - The latest release of
pkg-1
is1.1.2
(taken fromversion
field). - If
projector publish
is run, the next released version ofpkg-1
will be1.2.0
- git status reports the
packages/pkg-1
directory has deleted files (β
) and unstaged changes (!
).
γ € - The latest release of
@my-namespace/pkg
is3.0.1
(taken fromversion
field). - If
projector publish
is run, no new release of@my-namespace/pkg
will be made. - git status reports the
packages/pkg-2
directory has untracked changes (?
).
Next, we'll rename pkg-1
to @my-namespace/core
.
Expand Example
$ projector rename -w pkg-1 --to-name @my-namespace/core --find-and-replace
Monday, Nov 29, 2021, 12:03:01.981 PM PST
[12:03:02.013 PM] [projector] βΊ Β» Renaming "pkg-1" (at packages/pkg-1) to "@my-namespace/core" (at packages/pkg-1)
[12:03:02.040 PM] [projector] βΊ βΉ Update "name" field in packages/pkg-1/package.json
[12:03:02.040 PM] [projector] βΊ βΉ Update "name" field in packages/pkg-1/package.json
[12:03:02.059 PM] [projector] βΊ βΉ Find all strings matching /^pkg-1$/ and replace with "@my-namespace/core"
[12:03:02.123 PM] [projector] [find-replace] βΊ βΉ 2 replacements in README.md
[12:03:02.248 PM] [projector] [find-replace] βΊ βΉ 7 replacements in packages/pkg-1/README.md
[12:03:02.359 PM] [projector] βΊ βΉ Rebuild node_modules
added 2 packages, and audited 47 packages in 1s
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
[12:03:03.222 PM] [projector] βΊ β Rename successful
If you've used semantic-release before, the output style should look very familiar.
packages/pkg-1/package.json
:
{
"name": "@my-namespace/core",
"version": "1.1.2",
...
}
Let's run projector list
again.
Expand Example
$ projector list
Monday, Nov 29, 2021, 12:04:20.420 PM PST
[12:04:20.442 PM] [projector] βΊ Β» Listing project metadata
M my-cool-monorepo@ /repos/my-project [β‘Β»β?]
βββ @my-namespace/core@1.1.2 (β¬1.2.0) [?]
βββ @my-namespace/pkg@3.0.1 [?]
While @my-namespace/core
is technically a new package, the next release
version will be 1.2.0
since its package-id
has not changed. If we'd updated
@my-namespace/core
's path too (or used a different tagFormat
setting),
the package-id
would be different and the next release version would be
1.0.0
regardless of what version is listed in package.json
.
We can run npm show
in the packages/pkg-1
directory to prove
@my-namespace/core
has not yet been published.
Expand Example
$ projector -w pkg-1 npm show
Monday, Nov 29, 2021, 12:05:12.911 PM PST
[12:05:12.978 PM] [projector] βΊ Β» Executing command (at packages/pkg-1) npm show
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@my-namespace%2fcore - Not found
npm ERR! 404
npm ERR! 404 '@my-namespace/core@latest' is not in this registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/user/.npm/_logs/2021-11-29T21_54_47_723Z-debug.log
[12:05:13.117 PM] [projector] βΊ β Failed to execute command
Note how we can use
-w
to refer to a package by itspackage-id
regardless of itsname
;-w '**/core'
,-w @my-namespace/core
,-w '**/pkg-1'
, and-w packages/pkg-1
would also have worked.
When we did the find-and-replace on pkg-1
earlier, it updated the source at
packages/pkg-2/src/...
. Suppose we also added @my-namespace/core
as a
dependency of @my-namespace/pkg
. Let's commit all changes, run unit tests on
@my-namespace/pkg
, and release both packages.
Expand Example
$ git add packages
$ git commit -S -m 'update package structure'
[main 6ff080e] update package structure
...
$ projector test p2-tests
Monday, Nov 29, 2021, 12:07:47.776 PM PST
[12:07:47.780 PM] [projector] βΊ Β» Executing command (at root) npm test p2-tests
> test
> jest --coverage --collectCoverageFrom '**/src/**/*.js' general-tests "p2-tests"
PASS test/general-tests-1.test.js
PASS test/general-tests-2.test.js
PASS test/general-tests-3.test.js
PASS test/p2-tests.test.js
PASS test/p2-tests-integration.test.js
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
...
----------|---------|----------|---------|---------|-------------------
Test Suites: 5 passed, 5 total
Tests: 1 todo, 31 passed, 32 total
Snapshots: 0 total
Time: 0.58 s, estimated 1 s
Ran all test suites.
[12:07:48.336 PM] [projector] βΊ β Tests completed successfully
Note that the
test
commandβunlikebuild
,publish
, orrun
βrelies on the underlying test framework (Jest in this case) to deal with concurrency. All arguments after "test" will be passed as-is to the underlying test framework.
$ projector publish -ws
Monday, Nov 29, 2021, 12:07:55.101 PM PST
[12:07:55.123 PM] [projector] βΊ Β» Publishing all packages
[12:07:55.130 PM] [projector] βΊ βΉ Publishing package "@my-namespace/core" at packages/pkg-1
[12:07:55 PM] [semantic-release] βΊ βΉ Running semantic-release version 18.0.0
...
[12:07:55 PM] [semantic-release] [@semantic-release/commit-analyzer] βΊ βΉ Analysis of 104 commits complete: minor release
...
[12:08:14 PM] [semantic-release] [@semantic-release/npm] βΊ βΉ Publishing version 1.2.0 to npm registry on dist-tag latest
npm notice
npm notice π¦ @my-namespace/core@1.2.0
npm notice === Tarball Contents ===
npm notice 3.7kB README.md
...
npm notice 3.5kB package.json
npm notice === Tarball Details ===
npm notice name: @my-namespace/core
npm notice version: 1.2.0
npm notice filename: @my-namespace/core-1.2.0.tgz
npm notice package size: 7.2 kB
npm notice unpacked size: 25.8 kB
npm notice shasum: ...
npm notice integrity: ...
npm notice total files: 14
npm notice
+ @my-namespace/core@1.2.0
[12:08:16 PM] [semantic-release] [@semantic-release/npm] βΊ βΉ Published @my-namespace/core@1.2.0 to dist-tag @latest on https://registry.npmjs.org/
...
[12:08:16 PM] [semantic-release] [@semantic-release/github] βΊ βΉ Published GitHub release: ...
...
[12:08:49 PM] [semantic-release] βΊ β Published release 1.2.0 on default channel
[12:08:49.371 PM] [projector] βΊ βΉ Publishing package "@my-namespace/pkg" at packages/pkg-2
[12:07:55.481 PM] [semantic-release] βΊ βΉ Running semantic-release version 18.0.0
...
[12:07:55 PM] [semantic-release] [@semantic-release/commit-analyzer] βΊ βΉ Analysis of 122 commits complete: patch release
...
[12:08:15 PM] [semantic-release] [@semantic-release/npm] βΊ βΉ Publishing version 3.0.2 to npm registry on dist-tag latest
npm notice
npm notice π¦ @my-namespace/pkg@3.0.2
npm notice === Tarball Contents ===
npm notice 7.3kB README.md
...
npm notice 5.3kB package.json
npm notice === Tarball Details ===
npm notice name: @my-namespace/pkg
npm notice version: 3.0.2
npm notice filename: @my-namespace/pkg-3.0.2.tgz
npm notice package size: 10.6 kB
npm notice unpacked size: 44.8 kB
npm notice shasum: ...
npm notice integrity: ...
npm notice total files: 6
npm notice
+ @my-namespace/pkg@3.0.2
[12:08:16 PM] [semantic-release] [@semantic-release/npm] βΊ βΉ Published @my-namespace/pkg@3.0.2 to dist-tag @latest on https://registry.npmjs.org/
...
[12:08:16 PM] [semantic-release] [@semantic-release/github] βΊ βΉ Published GitHub release: ...
...
[12:08:49 PM] [semantic-release] βΊ β Published release 3.0.2 on default channel
[12:08:49.891 PM] [projector] βΊ β Released 2 packages successfully
Let's run projector list
a final time, but with the --with-cross-deps
argument.
Expand Example
$ projector list --with-cross-deps
Monday, Nov 29, 2021, 12:09:00.333 PM PST
[12:09:00.424 PM] [projector] βΊ Β» Listing project metadata
M my-cool-monorepo@ /repos/my-project
βββ @my-namespace/core@1.2.0
βββ¬ @my-namespace/pkg@3.0.2
βββ @my-namespace/core@1.2.0 π
Calling projector list
with --with-cross-deps
reveals cross-dependencies
(π), which are packages depended upon by other packages in the same monorepo.
Since projector publish
1) publishes packages concurrently where possible,
but ultimately in topological order and 2) synchronizes cross-dependency
versions at publish time: as Projector published @my-namespace/core
at version
1.2.0
, it automatically updated the dependencies['@my-namespace/core']
field
at packages/pkg-2/package.json
from "1.1.2"
to "1.2.0"
and committed the
change. Later, Projector published @my-namespace/pkg
at version 3.0.2
, which
included the updated cross-dependency. This is so-called "cross-dependency
version coherence".
packages/pkg-2/package.json
:
Expand Example
{
"name": "@my-namespace/pkg",
"version": "3.0.2",
"dependencies": {
"@my-namespace/core": "1.2.0",
...
},
...
}
See @projector-js/cli
.
All Projector projects require at least the following:
- A
package.json
file at the root of the repository.- Projector assumes a project is a polyrepo if the root
package.json
file does not contains aworkspaces
field.
- Projector assumes a project is a polyrepo if the root
That's it. TypeScript, Babel, semantic-release, etc are all yours to setup as you please, or you can use a tweakable pre-made configuration.
If your repository is using annotated tags, consider using semantic-release-atam, which is a semantic-release fork with _a_nnotated _t_ag _a_nd _m_onorepo support (PRs pending). Do not install semantic-release and semantic-release-atam at the same time!
Example
Expand Example
.
βββ .git
βββ package.json <==
βββ package-lock.json
βββ src/
βββ README.md
package.json
:
{
"name": "my-cool-package",
"version": "1.0.0",
...
}
Monorepos additionally require the following:
- A
workspaces
field in the rootpackage.json
file.- A
package.json
file with at least aname
field must exist at each package root.
- A
- semantic-release-atam installed (and the original semantic-release not
installed).
- semantic-release-atam is a drop-in replacement for semantic-release with added support for annotated tag and monorepo (ATAM).
- semantic-release-atam installation and configuration must meet the minimum
requirements listed in
@projector-js/config-semantic-release-atam
. @projector-js/semantic-release-plugin
must also be installed and configured.
Note that "fixed," "locked," or "synchronized" package versions, where every package maintains the same version number on every release, goes against the purpose of semantic-release and so is not currently supported.
Example
Expand Example
.
βββ .git
βββ package.json <==
βββ package-lock.json
βββ packages/
β βββ pkg-1/
β β βββ package.json <==
β β βββ README.md
β β βββ src/
β βββ pkg-2/
β βββ package.json <==
β βββ README.md
β βββ src/
βββ release.config.js <==
βββ README.md
package.json
:
{
"name": "my-cool-monorepo",
"workspaces": ["packages/pkg-1", "packages/pkg-2"],
...
}
packages/pkg-1/package.json
:
{
"name": "pkg-1",
"version": "1.0.0",
...
}
packages/pkg-2/package.json
:
{
"name": "pkg-2",
"version": "1.0.0",
...
}
Like Lerna and semantic-release, Projector too has a badge!
[![Maintained with Projector](https://xunn.at/badge-projector)](https://xunn.at/link-projector)
See each package for further information on the types they make available and other specifics.
- polyrepo: a git repository containing a root
package.json
file with noworkspaces
field. A polyrepo is the opposite of a monorepo. - monorepo: a git repository containing multiple packages/workspaces, each
listed under the
workspaces
field in the rootpackage.json
. A monorepo is the opposite of a polyrepo. - project root: the top-level directory of a git repository and Projector
project; it contains the root
package.json
file. This directory is also referred to as: "repository root,"rootDir
(always as an absolute path), "root package" (in npm documentation), "monorepo/polyrepo/repo root," or simply "root" (.e.g. "rootpackage.json
"). - package root: synonymous with a workspace in a monorepo. It contains
a package/workspace's
package.json
file. The basename of this directory (e.g.c
in/a/b/c/
) is also referred to as thepackage-id
, which may or may not match thename
field in the package'spackage.json
file. These directories are also referred to as a "monorepo package" or simply "sub-root" (.e.g. "sub-rootpackage.json
"). - topological order: a sequence of packages where dependent packages always come before their dependenciesβa so-called "package dependency order". Topological ordering ensures otherwise-concurrent tasks are performed at the right time and order (e.g. regenerate types in a core package before linting its dependent packages). Here's an illustrated example.
Projector is a tool I made for my own personal use. It was inspired by the pure awesomeness that is Lerna, Rush, and Nx.
New issues and pull requests are always welcome and greatly appreciated! π€© Just as well, you can star π this project to let me know you found it useful! βπΏ Thank you!
See CONTRIBUTING.md and SUPPORT.md for more information.
Thanks goes to these wonderful people (emoji key):
Bernard π π» π π§ |
||||||
Add your contributions |
This project follows the all-contributors specification. Contributions of any kind welcome!