Configuration: Workspace Config File

The optional configuration for a workspace is defined in a file such as pacwich.workspace.ts in its directory or in its package.json file.

You can also use the project config to set workspace configs in bulk by using workspace patterns. See the workspace pattern configs page for more information.

Type Definition

{
  // Must be unique across other aliases and workspace names
  alias?: string | string[],
  // Tags can be used to group workspaces together
  tags?: string[],
  // Inputs for affected workspace resolution
  defaultInputs?: {
    // Default is all git-trackable files in the workspace directory
    files?: string[],
    // Workspaces to treat like dependencies
    workspacePatterns?: string[],
    // Dependency names (e.g. "react") to treat as dependencies (default: all)
    externalDependencies?: string[]
  },
  scripts?: {
    [script: string]: {
      // Optional sorting order for running scripts
      order?: number,
      // Inputs for affected workspace resolution
      inputs?: {
        // Default is all git-trackable files in the workspace directory
        files?: string[],
        // Workspaces to treat like dependencies
        workspacePatterns?: string[],
        // Dependency names (e.g. "react") to treat as dependencies (default: all)
        externalDependencies?: string[]
      }
    }
  },
  verify?: {
    workspaceDependencies?: {
      // Ignore these input files for verification of workspace dependencies.
      // These are relative to the workspace directory.
      // Using a leading slash will match from the project root.
      ignoreInputFiles?: string[],
      // Ignore imports/exports from these workspaces
      ignoreImportsFromWorkspacePatterns?: string[]
    }
  },
  rules?: {
    workspaceDependencies?: {
      // Use workspace patterns to match workspaces to allow as dependencies
      allowPatterns?: string[],
      // Workspace patterns to forbid as dependencies.
      // When combined with allowPatterns, filters within that allowed subset.
      denyPatterns?: string[]
    }
  }
}

Alias

Aliases are an alternate name or names for a workspace. See the workspace aliases page for more information.


Tags

Tags are simple strings that can be used to group workspaces together. They can be used in workspace patterns.


Default Inputs

The defaultInputs used to determine which files are considered inputs for the workspace, such as for affected workspaces resolution. These are applied to all scripts in the workspace that don't configure their own inputs (see below).

See the inputs page for more information.


Scripts

A map of script names to config specific to any respective script. Inline workspaces can use an optional name to be matched.

Order

The scripts[name].order option is used to set the script execution order for scripts.

Inputs

The scripts[name].inputs option is used to set the inputs for the script, such as for affected workspaces resolution.

See the inputs page for more information.


Verify

See the verify page for more information on this feature.

  • verify.workspaceDependencies.ignoreInputFiles: Ignore these input files for verification of workspace dependencies.
  • verify.workspaceDependencies.ignoreImportsFromWorkspacePatterns: Ignore imports/exports from these workspaces, using workspace patterns.

The same options can be used in the project config. Workspace verify configuration is additive with the project-level config.


Workspace Dependency Rules

Using the rules.workspaceDependencies field, you can define rules for which workspaces are allowed to be dependencies, using allowPatterns, denyPatterns, or both.

Workspace patterns are used to match workspaces.

allowPatterns defines the permitted subset of dependencies. denyPatterns forbids specific dependencies. When both are present, denyPatterns further filters within the subset permitted by allowPatterns. You can also use negated workspace patterns to exclude workspaces from the allowed or denied list.

For example, you may disallow dependencies with the tag "backend" for a frontend workspace with denyPatterns: ["tag:backend"].

Workspace dependencies are explicitly defined in workspaces' package.json files.


Examples:

1. TypeScript/JavaScript file

path/to/your/workspace/pacwich.workspace.ts or path/to/your/workspace/pacwich.workspace.js

import { defineWorkspaceConfig } from "pacwich/config";

export default defineWorkspaceConfig({
  alias: "myApp",
  tags: [
    "my-tag"
  ],
  scripts: {
    start: {
      order: 10
    },
    test: {
      order: 20
    }
  },
  rules: {
    workspaceDependencies: {
      allowPatterns: [
        "my-workspace-a",
        "tag:my-tag",
        "path:my-path/**/*",
        "not:tag:my-excluded-tag"
      ]
    }
  }
});

mergeWorkspaceConfig Utility

You can use the mergeWorkspaceConfig function to merge multiple workspace configurations left to right, with each subsequent config taking precedence. Arrays are concatenated while keeping items unique, while inputs (defaultInputs and scripts[name].inputs) are replaced entirely rather than merged.

import { mergeWorkspaceConfig } from "pacwich/config";

export default mergeWorkspaceConfig(
  {
    alias: "a",
    tags: ["x"],
    defaultInputs: { files: ["src/**/*.ts", "package.json"] },
    scripts: {
      build: { order: 1, inputs: { files: ["src/**/*.ts"] } },
      test: { order: 2 },
    },
    rules: { workspaceDependencies: { allowPatterns: ["tag:lib"] } },
    verify: { workspaceDependencies: { ignoreInputFiles: ["scripts/**/*"] } },
  },
  {
    alias: "b", // concatenated with "a"
    tags: ["x", "y"], // "x" deduplicated
    // whole object replaces the first config's defaultInputs
    defaultInputs: { files: ["src/**/*.ts", "!src/**/*.test.ts"] },
    scripts: {
      // build.order kept from the first config, but inputs is replaced
      // as a whole object ("src/**/*.ts" is gone unless restated)
      build: { inputs: { files: ["src/index.ts"] } },
    },
    rules: { workspaceDependencies: { denyPatterns: ["tag:app"] } },
    verify: {
      workspaceDependencies: {
        ignoreInputFiles: ["scripts/**/*", "legacy/**/*"], // concat + dedupe
        ignoreImportsFromWorkspacePatterns: ["tag:internal"],
      },
    },
  },
  // factory form reads the accumulated config so far
  (prevConfig) => ({
    tags: prevConfig.tags?.includes("y") ? ["frontend"] : [],
  }),
);

// result: {
//   alias: ["a", "b"],
//   tags: ["x", "y", "frontend"],
//   defaultInputs: { files: ["src/**/*.ts", "!src/**/*.test.ts"] },
//   scripts: {
//     build: { order: 1, inputs: { files: ["src/index.ts"] } },
//     test: { order: 2 },
//   },
//   rules: {
//     workspaceDependencies: {
//       allowPatterns: ["tag:lib"],
//       denyPatterns: ["tag:app"],
//     },
//   },
//   verify: {
//     workspaceDependencies: {
//       ignoreInputFiles: ["scripts/**/*", "legacy/**/*"],
//       ignoreImportsFromWorkspacePatterns: ["tag:internal"],
//     },
//   },
// }

2. JSON/JSONC file

path/to/your/workspace/pacwich.workspace.json or path/to/your/workspace/pacwich.workspace.jsonc

{
  "alias": "myApp",
  "tags": [
    "my-tag"
  ],
  "scripts": {
    "start": {
      "order": 10
    },
    "test": {
      "order": 20
    }
  },
  "rules": {
    "workspaceDependencies": {
      "allowPatterns": [
        "my-workspace-a",
        "tag:my-tag",
        "path:my-path/**/*",
        "not:tag:my-excluded-tag"
      ]
    }
  }
}

3. package.json

path/to/your/workspace/package.json
{
  "name": "@my-organization/my-application",
  "description": "My app",
  "version": "1.0.0",
  "pacwich": {
    "alias": "myApp",
    "tags": [
      "my-tag"
    ],
    "scripts": {
      "start": {
        "order": 10
      },
      "test": {
        "order": 20
      }
    },
    "rules": {
      "workspaceDependencies": {
        "allowPatterns": [
          "my-workspace-a",
          "tag:my-tag",
          "path:my-path/**/*",
          "not:tag:my-excluded-tag"
        ]
      }
    }
  }
}