Skip to content

hongaar/moker

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

moker npm

No more struggles setting up a new JavaScript repository. Kick-start single-purpose repos, monorepos, monorepo workspaces and common tooling:

# initialize a monorepo
yarn dlx moker create --monorepo my-monorepo
cd my-monorepo

# install common tools
yarn moker use prettier doctoc semantic-release

# create workspaces
yarn moker add --template express server
yarn moker add --template cra client
yarn moker add --template lib shared
yarn moker add --template bandersnatch cli

Features

  • πŸ‘’ Kick-start a new repo or monorepo using Yarn
  • 🧰 Plugins to use pre-configured common tooling
  • βž• Quickly add workspaces to a monorepo
  • 🧬 Workspace templates for a shared library, React app, API or CLI
  • ⚑ Extensible, bring your own plugins

πŸ€“ Default: The core plugins make some assumptions you may not agree with. If that's the case, this tool is probably not for you. The defaults used are documented below and marked with a nerd-face emoji so you should be able to get a clear picture of what to expect.

Table of contents

Getting started

Prerequisites

You will need Node v18+ and Yarn v2+ in order to use moker.

  • Install Node with nvm or using nodesource.
  • Install Yarn using these simple steps:
    corepack enable
    corepack prepare yarn@stable --activate

Usage

moker is distributed as a NPM package, and can be run with yarn dlx:

yarn dlx moker <command>

Note: Note that when we use yarn dlx moker to create a new repo, moker is added as a dependency to your new repo, so we can simply use yarn moker to execute commands from within the repo directory.

Creating a single-purpose repo

To create a new repo in the my-repo directory:

yarn dlx moker create my-repo

Creating a monorepo

To create a new monorepo in the my-monorepo directory: :

yarn dlx moker create --monorepo my-monorepo

πŸ€“ Default: The monorepo is initiated with Yarn without Zero-Installs and in legacy nodeLinker: node-modules mode because a lot of packages are not yet compatible with PnP or require a workaround.

Creating a monorepo workspace

Workspaces (a.k.a. monorepo packages) are added in a customizable subdirectory of the monorepo (the default is packages). To add a new workspace called my-workspace to your monorepo, run this from within the monorepo directory:

yarn moker add my-workspace

Using plugins

Plugins are used to add additional tools to your repo or workspace. Add the prettier plugin with:

yarn moker use prettier

Plugins may work together. For example, lint-staged will install a pre-commit hook which formats code if prettier and husky are installed. The order in which plugins are added does not matter. You can install multiple plugins at once:

yarn moker use prettier lint-staged husky

Note: Some plugins only work at the repo or workspace level, moker will warn you if you try to add a plugin at the wrong level.

For a complete list of out-of-the-box plugins, see the section available plugins. Using 3rd party plugins is also supported:

yarn add --dev --exact moker-plugin-name
yarn moker use moker-plugin-name

Using templates

Templates are pre-defined collections of plugins and scaffolding to quickly create focussed new repos or workspaces. To create a new repo my-repo with the common template:

yarn dlx moker create --template common my-repo

To add a workspace called shared to a monorepo using the lib template:

yarn moker add --template lib shared

You can install multiple templates at once:

yarn dlx moker create --template common --template github-action my-action

For a complete list of out-of-the-box templates, see the section available templates. Using 3rd party templates is also supported:

yarn dlx --package moker-template-name \
  moker create --template moker-template-name my-repo

Using plugins and templates together

Plugins and templates can be used together, for example:

yarn dlx moker create --template express --use prettier my-repo

Available plugins

dependabot

Scope: repo

This plugin adds a Dependabot configuration to your monorepo with an updater for NPM packages.

If you have the github-actions plugin installed, it will add an updater for GitHub Actions workflows.

devcontainer

Scope: repo

This plugin creates a Development Containers configuration using the typescript-node image.

If you have the prettier plugin installed, it will add the Prettier VS Code extension.

doctoc

Scope: repo

This plugin adds a script to generate a table of contents for the README using doctoc.

If you have the husky plugin installed, it will also add a pre-commit hook.

esbuild

Scope: repo or workspace

This plugin sets up esbuild and adds a build and build:watch script to the repo or both the workspace and the monorepo.

πŸ€“ Default: If you have the typescript plugin installed as well, we'll assume that you want to build to a bundle instead of transpiled TypeScript. We will still use tsc for type checking.

github-actions

Scope: repo

This plugin creates a simple ci.yml GitHub Actions workflow and a workflow to update the Node versions periodically.

If you have the prettier plugin installed, this will also setup a lint.yml workflow.

If you have the semantic-release plugin installed, this will also setup a release.yml workflow. This workflow needs these secrets to be added to your repository:

  • GH_PAT: a GitHub token with read/write access to your repository
  • NPM_TOKEN: an NPM token with publish access to your packages

If you have the dependabot plugin installed, this will also setup two additional workflows. A dependabot-automerge workflow which enables auto-merge (squash) on dependabot PRs. You need to enable Allow auto-merge in the GitHub repository settings and apply Branch protection rules for the main branch.

Note: If you enabled Require approvals in the branch protection rules, this won't automatically approve the PR. You will need to add an additional command to the workflow, like:

 steps:
-  - run: gh pr merge --auto --squash "$PR_URL"
+  - run: |
+      gh pr review --approve "$PR_URL"
+      gh pr merge --auto --squash "$PR_URL"
     env:

A reload-moker-plugins workflow is added to reload the moker plugins and create a pull request with changes made by moker whenever dependencies are updated by dependabot.

πŸ€“ Default: The workflows will use the main branch by default, but it is trivial to change this.

husky

Scope: repo

This plugin sets up Husky at the repo level.

Warning: The postinstall script to install Husky automatically is only installed on (private) monorepos. Otherwise, postinstall will run when someone installs your package and result in an error.

See Husky docs on installing with Yarn 2

jest

Scope: repo or workspace

πŸ§ͺ Experimental Currently only works with the typescript plugin. Currently doesn't work when you have ESM dependencies in node_modules.

This plugin sets up Jest and adds a test and test:watch script to the repo or both the workspace and the monorepo.

lint-staged

Scope: repo

This plugin sets up lint-staged at the monorepo level.

If you have the prettier plugin installed, this will setup a task to format staged files using prettier --write --ignore-unknown.

If you have the husky plugin installed, this will setup a pre-commit hook to run yarn lint-staged.

prettier

Scope: repo

This plugin sets up Prettier.

πŸ€“ Default: Prettier is installed with this configuration:

proseWrap: always

We only set this proseWrap override because we think markdown files should always be truncated to match whatever the printWidth setting is. This makes it so much easier to read and write markdown files!

semantic-release

Scope: repo

This plugin sets up semantic-release. It uses the semantic-release-yarn plugin which has support for releasing monorepos.

Please note that by default the root repository is not published. You can change this by setting the private property in package.json to false.

πŸ€“ Default: The release configuration will use the main branch by default, but it is trivial to change this.

test

Scope: repo or workspace

This plugin enables testing with the native node --test functionality.

When the typescript plugin is also installed, it will use ts-node to load TypeScript test files.

todos

Scope: repo or workspace

This plugin adds a script to generate a TODO markdown file from all code annotations using leasot.

If you have the husky plugin installed, it will also add a pre-commit hook.

typescript

Scope: repo or workspace

πŸ§ͺ Experimental Since v2, this plugin uses the new --build mode of TypeScript, which makes building a lot faster but may require some additional configuration.

This plugin sets up TypeScript and adds a build and build:watch script to the repo or both the workspace and the monorepo.

In addition, this will add a typescript and typescript:watch script to the monorepo which can use project references to build workspaces which depend on each other faster and provides a better developer experience.

In order to use this, add all TypeScript workspaces to tsconfig.json in the monorepo root directory:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "references": [
    { "path": "./packages/some-library" },
    { "path": "./packages/some-dependency" }
  ],
  "files": []
}

And reference dependant workspaces in the workspace tsconfig.json:

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist",
    "declarationDir": "types"
  },
  "references": [{ "path": "../some-dependency" }],
  "include": ["src/**/*"]
}

You can optionally sync project references with yarn dlx @monorepo-utils/workspaces-to-typescript-project-references.

xv

Scope: repo or workspace

πŸ§ͺ Experimental Currently only works with the typescript plugin.

This plugin sets up xv and adds a test script to the repo or both the workspace and the monorepo.

Available templates

bandersnatch

Scope: repo or workspace

Scaffolds a simple bandersnatch CLI app tool with the typescript and jest plugins.

common

Scope: repo

This is the only monorepo template at this point. It simply installs all available monorepo plugins.

cra

Scope: repo or workspace

Uses create-react-app to scaffold a React.js app (web client).

express

Scope: repo or workspace

Scaffolds a simple express HTTP app with the typescript and jest plugins.

github-action

Scope: repo

πŸ§ͺ Experimental

Scaffolds a custom GitHub Action template.

lib

Scope: repo or workspace

A plain shared library template with the typescript and jest plugins.

next

Scope: repo or workspace

Uses create-next-app to scaffold a Next.js app.

sanity

Scope: repo or workspace

Uses create-sanity which interactively scaffolds a Sanity Studio package.

Commands

See moker --help for a list of available commands.

Contributing

Contributions are very welcome!

Roadmap

  • Use TS project references for better (incremental) compilation example
  • Support for swc/esbuild
  • A compat lib (which builds cjs and mjs targets)
  • Blog post / tutorial
  • Docs for writing custom plugins / templates
  • Add LICENSE file to repo
  • Adapt for non-monorepo use-cases
  • github-actions plugin
  • devcontainer plugin
  • leasot (todos) plugin
  • doctoc plugin
  • semantic-release plugin
  • Port templates
  • Support for BYO plugins/templates
  • Remove plugins

Also see TODO.md.

Development

To run the moker CLI from source, run:

yarn start

Note that you can create a new monorepo for testing purposes outside the current working directory with:

yarn start create /path/to/my-repo

Devcontainer

A devcontainer configuration is included in this repo to get started quickly.

Credits

©️ Copyright 2022 Joram van den Boezem
♻️ Licensed under the MIT license
πŸ€” Moker? MOnorepo KickstartER