Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions bench/glob/scan.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ const normalPattern = "*.ts";
const recursivePattern = "**/*.ts";
const nodeModulesPattern = "**/node_modules/**/*.js";
const multiLevelPattern = "node_modules/*/lib/*.js";
const crossingGroupPattern = "{node_modules/*/lib,src}/*.js";
// A name after the group: one lookup in each directory that the group ends at, as for the written-out patterns.
const crossingGroupThenNamePattern = "{node_modules/*,src}/package.json";
// A list joined into one group, longer than the 255 bytes that the matcher keeps a cache for.
const joinedList = Array.from({ length: 40 }, (_, i) => `node_modules/${"abcdefghij"[i % 10]}*/lib/*${i}.js`);
const joinedPattern = `{${joinedList.join(",")}}`;

const benchFdir = false;
const cwd = undefined;
Expand Down Expand Up @@ -137,6 +143,49 @@ group({ name: `sync multi-level pattern="${multiLevelPattern}"`, summary: true }
});
});

group({ name: `sync crossing-group pattern="${crossingGroupPattern}"`, summary: true }, () => {
bench("fast-glob", () => {
const entries = fg.globSync([crossingGroupPattern], fgOpts);
});

if (Glob)
bench("Bun.Glob", () => {
const entries = [...new Glob(crossingGroupPattern).scanSync(bunOpts)];
});
});

group({ name: `sync crossing-group pattern="${crossingGroupThenNamePattern}"`, summary: true }, () => {
bench("fast-glob", () => {
const entries = fg.globSync([crossingGroupThenNamePattern], fgOpts);
});

if (Glob) {
bench("Bun.Glob", () => {
const entries = [...new Glob(crossingGroupThenNamePattern).scanSync(bunOpts)];
});
bench("Bun.Glob, one scan for each alternative", () => {
const entries = ["node_modules/*/package.json", "src/package.json"].flatMap(pattern => [
...new Glob(pattern).scanSync(bunOpts),
]);
});
}
});

group({ name: `sync ${joinedList.length} patterns joined into one group`, summary: true }, () => {
bench("fast-glob", () => {
const entries = fg.globSync(joinedList, fgOpts);
});

if (Glob) {
bench("Bun.Glob", () => {
const entries = [...new Glob(joinedPattern).scanSync(bunOpts)];
});
bench("Bun.Glob, one scan for each pattern", () => {
const entries = joinedList.flatMap(pattern => [...new Glob(pattern).scanSync(bunOpts)]);
});
}
});

await run({
avg: true,
colors: false,
Expand Down
2 changes: 2 additions & 0 deletions docs/pm/workspaces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ The `"workspaces"` key in the root `package.json` lists the subdirectories to tr

A negative pattern removes what the globs match, wherever it is in the list. `!dir/**` removes `dir` and everything below it. A negative pattern does not remove a directory that is listed by its path. `bun run --filter` and `--workspaces` skip the excluded packages too.

A `{a,b}` group is one pattern, and an alternative can contain a `/`. `"{apps/web,packages/*}"` takes `apps/web` and every package in `packages`. List a path that leaves the root, such as `"../shared"`, as its own entry.

Each workspace has its own `package.json`. To reference another package in the monorepo, use a semver range or the workspace protocol (for example `workspace:*`) as the version in your `package.json`.

```json packages/pkg-a/package.json icon="file-json"
Expand Down
2 changes: 2 additions & 0 deletions docs/runtime/glob.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ glob.match("d.ts"); // => false

You can nest these patterns to any depth, and they can contain any of the other wildcards.

An alternative can contain a `/`. `src/{a,b/c}/index.ts` matches `src/a/index.ts` and `src/b/c/index.ts`, and `scan()` lists both.

### `{1..3}` - Match a range of numbers or letters

```ts
Expand Down
Loading
Loading