Skip to content

Commit 1605028

Browse files
authored
feat: config refactor (#87)
* feat: internal refactor + configuration revamp * fix: incorrect path * feat: scope workspaces to "packages/" * fix: better feedback for failed integrity check * fix: add missing await * fix: changeset formatting * fix: run checks in parallel * fix: log integrity check errors
1 parent dd46b9a commit 1605028

File tree

16 files changed

+334
-256
lines changed

16 files changed

+334
-256
lines changed

.changeset/ten-panthers-play.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
"bob-the-bundler": major
3+
---
4+
5+
Remove the global config. Please add `bob: false` to the individual `package.json` workspaces that should not be processed by bob.
6+
7+
This is the new config format for bob.
8+
9+
```ts
10+
type BobConfig =
11+
/** completely disable bob for this package. */
12+
| false
13+
| {
14+
/** Whether the package should be built. */
15+
build?:
16+
| false
17+
| {
18+
/** Files to copy from the package root to dist */
19+
copy?: Array<string>;
20+
};
21+
/** Whether the package should be checked. */
22+
check?:
23+
| false
24+
| {
25+
/** Exports within the package that should not be checked. */
26+
skip?: Array<string>;
27+
};
28+
};
29+
```

README.md

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,67 @@
1-
# Bob (The Bundler)
1+
# Bob (The ~~Bundler~~ Butler)
22

3-
There's no documentation yet but you can check [GraphQL Code Generator](https://github.com/dotansimha/graphql-code-generator) repository to see how to use Bob.
3+
Bob is the TypeScript build, bundle and verification tool used by almost all [The Guild](https://the-guild.dev) open source projects.
4+
5+
Scope:
6+
7+
- **Build**: Build ESM and CommonJS compatible npm packages
8+
- **Verify**: Ensure all ESM and CommonJS imports within a npm package are usable
9+
- **Bundle**: Build a single executable for an application (experimental)
410

511
## Requirements
612

7-
- Supports only scoped packages (same scope)
8-
- Yarn Workspaces
9-
- TypeScript with Paths
13+
- Yarn workspace or single package project
14+
- TypeScript
1015
- It's so strict you shouldn't use it!
1116

17+
## Setup
18+
19+
Setting up bob is currently undocumented. You can check [GraphQL Code Generator](https://github.com/dotansimha/graphql-code-generator) repository (or any other The Guild repository).
20+
1221
## Configuration
1322

14-
Bob only accepts `bob.config.js` in root directory:
23+
You can add a `bob` key to each `package.json`.
24+
25+
**Disable bob for a single package**
1526

1627
```js
17-
module.exports = {
18-
scope: "@graphql-codegen", // Scope of organization
19-
ignore: ["@graphql-codegen/website", "@graphql-codegen/live-demo"], // ignored packages
20-
track: [
21-
// files in root that mark the entire workspace as dirty
22-
"bob.config.js", // we could include it in Bob itself but we decided to turn your life into hell :)
23-
"jest.config.js",
24-
"jest-project.js",
25-
"package.json",
26-
"tsconfig.json",
27-
// files in packages that mark the package as dirty
28-
"<project>/src/**",
29-
"<project>/jest.config.js",
30-
"<project>/package.json",
31-
"<project>/tsconfig.json",
32-
],
33-
base: "origin/master", // we need to compare against something
34-
commands: {
35-
test: {
36-
track: ["<project>/tests/**"],
37-
run(affected) {
38-
// {
39-
// paths: string[] <- ['packages/core', 'packages/cli']
40-
// names: string[] <- ['@foo/core', '@foo/cli']
41-
// }
42-
43-
// why such a weird syntax? We use spawn, so you have too
44-
return [`yarn`, ["test", ...affected.paths]];
45-
},
46-
},
47-
build: {
48-
run() {
49-
return [`yarn`, ["build"]];
50-
},
51-
},
52-
},
53-
};
28+
{
29+
"name": "graphql-lfg",
30+
"bob": false // exclude a single package from all things bob related
31+
}
5432
```
5533

56-
## Build Options
57-
58-
In your `<project>/package.json`:
34+
**Disable build for a single package**
5935

60-
```json
36+
```js
6137
{
62-
"buildOptions": {
63-
"external": ["simple-git/promise"], // Marks nested imports as external
64-
"bin": {
65-
"cli": {
66-
"input": "src/cli.ts" // Entry point for `cli` command
67-
}
68-
}
38+
"name": "graphql-lfg",
39+
"bob": {
40+
"build": false
6941
}
7042
}
7143
```
7244

73-
## Support for Node ES Modules
45+
**Disable check for a single package**
7446

75-
In your `<project>/package.json`, just add `"exports"` like this:
47+
```js
48+
{
49+
"name": "graphql-lfg",
50+
"bob": {
51+
"check": false
52+
}
53+
}
54+
```
7655

77-
```json
56+
**Disable check for a single export in a package**
57+
58+
```js
7859
{
79-
"main": "dist/index.cjs.js",
80-
"exports": {
81-
"require": "dist/index.cjs.js", // should match "main"
82-
"default": "dist/index.mjs" // should ends with ".mjs" extension
60+
"name": "graphql-lfg",
61+
"bob": {
62+
"check": {
63+
"skip": ["./foo"]
64+
}
8365
}
8466
}
8567
```
@@ -88,12 +70,10 @@ In your `<project>/package.json`, just add `"exports"` like this:
8870

8971
```bash
9072

91-
$ bob affected test
92-
$ bob affected build
93-
9473
$ bob build
95-
$ bob prepack
74+
$ bob check
9675

76+
# only use this command if you know the secret sauce
9777
$ bob runify
9878

9979
```

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"@vercel/ncc": "^0.34.0",
2828
"builtins": "^5.0.1",
2929
"consola": "^2.15.3",
30-
"cosmiconfig": "^7.0.1",
3130
"cross-spawn": "^7.0.3",
3231
"dependency-graph": "^0.11.0",
3332
"fs-extra": "^10.1.0",

src/command.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { CommandModule } from "yargs";
2-
import { BobConfig } from "./config";
32
import { Consola } from "consola";
43

54
export { CommandModule as Command };
65

76
export interface CommandAPI {
8-
config: BobConfig;
97
reporter: Consola;
108
}
119

src/commands/bootstrap.ts

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import globby from "globby";
22
import pLimit from "p-limit";
3+
import * as path from "path";
34
import * as fse from "fs-extra";
45
import { createCommand } from "../command";
6+
import { buildArtifactDirectories } from "../constants";
7+
import { getRootPackageJSON } from "../utils/get-root-package-json";
8+
import { getWorkspaces } from "../utils/get-workspaces";
9+
import { getWorkspacePackagePaths } from "../utils/get-workspace-package-paths";
510

611
/** The default bob fields that should be within a package.json */
712
export const presetFields = Object.freeze({
@@ -60,11 +65,11 @@ function transformModuleImports(fileContents: string) {
6065
);
6166
}
6267

63-
async function applyESMModuleTransform(distDirs: Array<string>) {
68+
async function applyESMModuleTransform(cwd: string) {
6469
const files = await globby("**/*.ts", {
65-
cwd: process.cwd(),
70+
cwd,
6671
absolute: true,
67-
ignore: ["**/node_modules/**", ...distDirs],
72+
ignore: ["**/node_modules/**", ...buildArtifactDirectories],
6873
});
6974

7075
const limit = pLimit(20);
@@ -89,7 +94,7 @@ async function applyPackageJSONPresetConfig(
8994

9095
const limit = pLimit(20);
9196

92-
export const bootstrapCommand = createCommand<{}, {}>((api) => {
97+
export const bootstrapCommand = createCommand<{}, {}>(() => {
9398
return {
9499
command: "bootstrap",
95100
describe:
@@ -98,48 +103,35 @@ export const bootstrapCommand = createCommand<{}, {}>((api) => {
98103
return yargs.options({});
99104
},
100105
async handler() {
101-
const { config } = api;
102-
103-
const [rootPackageJSONPath] = await globby("package.json", {
104-
cwd: process.cwd(),
105-
absolute: true,
106-
});
107-
108-
if (rootPackageJSONPath === undefined) {
109-
throw new Error("Must be executed within a (monorepo-)package root.");
110-
}
111-
112-
const rootPackageJSON: Record<string, unknown> = await fse.readJSON(
113-
rootPackageJSONPath
114-
);
115-
const isSinglePackage =
116-
Array.isArray(rootPackageJSON.workspaces) === false;
117-
118-
const distDirs =
119-
config.dists?.map(({ distDir }) => `**/${distDir}/**`) ?? [];
106+
const cwd = process.cwd();
107+
const rootPackageJSON = await getRootPackageJSON(cwd);
108+
const workspaces = getWorkspaces(rootPackageJSON);
109+
const isSinglePackage = workspaces === null;
120110

121111
// Make sure all modules are converted to ESM
122-
await applyESMModuleTransform(distDirs);
123112

124113
if (isSinglePackage) {
114+
await applyESMModuleTransform(cwd);
125115
await applyPackageJSONPresetConfig(
126-
rootPackageJSONPath,
116+
path.join(cwd, "package.json"),
127117
rootPackageJSON
128118
);
129119
return;
130120
}
131121

132-
const packageJSONPaths = await globby("packages/**/package.json", {
133-
cwd: process.cwd(),
134-
absolute: true,
135-
ignore: ["**/node_modules/**", ...distDirs],
136-
});
122+
const workspacePackagePaths = await getWorkspacePackagePaths(
123+
cwd,
124+
workspaces
125+
);
126+
137127
await Promise.all(
138-
packageJSONPaths.map((packageJSONPath) =>
128+
workspacePackagePaths.map((packagePath) =>
139129
limit(async () => {
130+
const packageJSONPath = path.join(packagePath, "package.json");
140131
const packageJSON: Record<string, unknown> = await fse.readJSON(
141132
packageJSONPath
142133
);
134+
await applyESMModuleTransform(packagePath);
143135
await applyPackageJSONPresetConfig(packageJSONPath, packageJSON);
144136
})
145137
)

0 commit comments

Comments
 (0)