Skip to main content

Developer contribution guide

This is a work-in-progress.

You can reference API documentation here.

Requirementsโ€‹

Either:

  • docker

Or:

  • Node v16.13.2
  • Yarn 1.22.17 (or anything recent enough that it recognizes yarn v3)

While you are free to develop with the second option (outside of docker) please note:

  • This isn't supported
  • You will find it more difficult to run integration tests

Additionally, it is not a requirement to develop in vscode but if you are using a different IDE it will be on you to consult the yarn v3 docs in order to get your IDE into a state where it recognizes yarn's zip-fs cache. Without zip-fs support your IDE links will probably not work.

Bud is compatible with x86 and arm architectures.

Getting startedโ€‹

vscode isn't a requirement to develop bud, but it is the easiest way to get started and is the best supported way to work with the codebase.

vscode as an IDE works particularly well in conjunction with the vscode remote development extension and docker (in the context of this repo).

If you have the extension installed you'll be prompted to restart vscode inside the container context when you first open the project. Doing so will build everything and ask you to install all of the recommended extensions. These extension installs only apply to the remote container context, so don't worry too much about messing up your IDE.

Opening a vscode terminal allows you to run commands within the container. The workbench will probably be a little different than the one you use outside the container, but it should all feel pretty familiar.

If you don't want to use docker but still use vscode you'll want to make sure that you have installed the arcanis.vscode-zipfs extension, since that won't be handled for you. Without it vscode will have a lot of difficulty tracing linked modules.

CLIโ€‹

The @bud CLI is a yarn plugin for managing the development environment and running project tasks.

Note that most @bud commands require being executed within the container. The command will fail if you try to run it on your host machine.

If you run yarn --help you can find a listing of all the commands under the @bud category.

Common tasks:

  • yarn @bud build: build all packages. this command passes through all options/flags to tsc.
  • yarn @bud dev: build all packages with tsc's --watch flag.
  • yarn @bud test all: run all tests. this command passes through all options/flags to jest.
  • yarn @bud lint: run all linters.

Integration testingโ€‹

In order to do integration testing you will either need to use docker or:

  • set the YARN_RC_FILENAME environment variable to ./config/yarn.dev.yml
  • be running verdaccio (see below) separately

This is because bud integration tests start by downloading the packages from a locally hosted private package registry. This repository is expected to be running at http://verdaccio:4873.

The proxy package registry is provided by software called verdaccio.

If you run yarn @bud release --tag latest (either in the container or with verdaccio running as a separate process on your machine) you'll have "released" the package to the registry at http://verdaccio:4873. If you go to that URL in a browser you should see your packages listed.

Now, anywhere in the container (or outside of it, locally) you can install the package from the registry like so: yarn install --registry http://verdaccio:4873 or yarn add @roots/bud --dev --registry http://verdaccio:4873. Same flag works for npm installs.

If you want to make a change and try it again, rerun yarn @bud release --tag latest. Don't worry about incrementing versions, the @bud cli will delete the old packages before publishing again.

Between publishes, you will probably need to revert your lockfile wherever you are running the installs so you don't get trigger checksum mismatch errors. Sometimes yarn will get annoyed anyway. Adding 'unsafe-disable-integrity-migration': false to .yarnrc will get it to chill.

Documentationโ€‹

bud.js documentation is generated with docusaurus. You can use the @bud CLI to run tasks related to documentation.

Check out yarn @bud docs --help for more information.

All site files are housed in ./sources/docs.

Docblocksโ€‹

API documentation is generated with api-extractor. You should not manually edit the API documentation at ./sources/docs/api. It will be overwritten.

When writing a bud.js package you should try and label exported symbols with either @public or @private. TS symbols labeled with @public will be included in built docs. TS symbols labeled with @private are not exposed to the public API and will not be included in built docs.

You should also consider using other tags supported by api-extractor: @params, @returns, @remarks, @decorator and @example. An ideal comment block has:

  • a simple single-line description
  • followed by a longer @remarks section, if appropraite.
  • an @example block showing how the export is used.
  • @params and @returns sections describing the parameters and return values (for functions, and methods).
  • the @decorator block can be used if you are using a decorator. bud.js makes extensive use of the @bind decorator from helpful-decorators.

Example:

/**
* Sums two numbers
*
* @remarks
* It is actually probably unncessary to have a remarks
* section for this function since it is so simple.
*
* @example
* ```ts
* const example = (a: number, b: number) => a + b
* ```
*
* @params a - the first number
* @params b - the second number
* @returns the sum of the two numbers
*
* @public
*/
function sum: (a: number, b: number) => number = sum(a, b) {
return a + b
}

This isn't strictly enforced. Adding docblocks to undocumented symbols is a great way to contribute to the project. There is a tsdoc linter which can be used to get feedback. It's pretty noisy right now (if you run it on the entire repository).

READMEsโ€‹

Don't edit README.md files directly. They are generated and your work will be overwritten.

Packagesโ€‹

This section is incomplete.

Core packagesโ€‹

@roots/bud-frameworkโ€‹

This package is core to all of bud.js. Its exports are used by almost all other packages. When writing a package for bud.js you will, in all likelihood, be implementing against interfaces exported by this package.

This package does not import from any other package. This is key to its role (IoC container).

Structuring your package with this package as a dependency will help ensure that your package is compatible with bud.js.

You can find many examples of using the interfaces exported from this package in any of the core bud packages or extensions.

@roots/bud-apiโ€‹

Many of the most visible configuration functions are provided by this service.

Other than providing the functions it has two other tasks:

  • binding the functions
  • exposing facades for each of the functions

Many of these functions are actually asynchronous but they are used as if they are sync functions in the configuration. This is because a call to a bud config function actually just stores a reference to the call in the bud.api service. Each stored reference is a tuple holding:

  • the function name as it was called (String)
  • the parameters passed (Array)

Later, these stored tuples are looped through and the actual calls are made.

This allows the user to enjoy a synchronous API while also keeping everything non-blocking.

  • @roots/bud-build
  • @roots/bud-cache
  • @roots/bud-compiler
  • @roots/bud-dashboard
  • @roots/bud-extensions
  • @roots/bud-hooks
  • @roots/bud-server
  • @roots/bud-support

Extensionsโ€‹

  • @roots/bud-babel
  • @roots/bud-compress
  • @roots/bud-criticalcss
  • @roots/bud-emotion
  • @roots/bud-entrypoints
  • @roots/bud-esbuild
  • @roots/bud-eslint
  • @roots/bud-imagemin
  • @roots/bud-library
  • @roots/bud-mdx
  • @roots/bud-postcss
  • @roots/bud-preset-recommend
  • @roots/bud-prettier
  • @roots/bud-purgecss
  • @roots/bud-react
  • @roots/bud-sass
  • @roots/bud-solid
  • @roots/bud-stylelint
  • @roots/bud-tailwindcss
  • @roots/bud-terser
  • @roots/bud-typescript
  • @roots/bud-vue
  • @roots/bud-wordpress-dependencies
  • @roots/bud-wordpress-externals
  • @roots/bud-wordpress-manifests
  • @roots/sage

Librariesโ€‹

  • @roots/container
  • @roots/dependencies
  • @roots/filesystem
  • @roots/ink-prettier
  • @roots/ink-use-style

Webpack plugins:โ€‹

  • @roots/critical-css-webpack-plugin
  • @roots/entrypoints-webpack-plugin
  • @roots/merged-manifest-webpack-plugin
  • @roots/wordpress-dependencies-webpack-plugin
  • @roots/wordpress-externals-webpack-plugin

Private packagesโ€‹

  • @repo/yarn-plugin-bud (./sources/yarn-plugin-bud)
  • @repo/docs (./sources/docs)
  • @repo/notifier (./sources/@repo/notifier)