Skip to content

Commit 59ead17

Browse files
authored
feat: remove the flag for building a single package (#70)
* feat: remove the flag for building a single package and instead derive it from the package.json * test: remove obsolete flag * chore: add integration test for monorepository * chore: add changeset
1 parent 4774d17 commit 59ead17

File tree

10 files changed

+245
-44
lines changed

10 files changed

+245
-44
lines changed

.changeset/tasty-bags-thank.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bob-the-bundler": minor
3+
---
4+
5+
remove the `--single` flag. The value is now derived from the `package.json` `workspaces` property. If your workspace is configured properly this is not a breaking change.

src/commands/build.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as rollup from "rollup";
2+
import * as fse from "fs-extra";
23
import generatePackageJson from "rollup-plugin-generate-package-json";
34
import { autoExternal } from "../rollup-plugins/auto-external";
45
import resolveNode from "@rollup/plugin-node-resolve";
@@ -31,33 +32,34 @@ interface PackageInfo {
3132
fullName: string;
3233
}
3334

34-
export const buildCommand = createCommand<
35-
{},
36-
{
37-
single?: boolean;
38-
}
39-
>((api) => {
35+
export const buildCommand = createCommand<{}, {}>((api) => {
4036
const { config, reporter } = api;
4137

4238
return {
4339
command: "build",
4440
describe: "Build",
4541
builder(yargs) {
46-
return yargs.options({
47-
single: {
48-
describe: "Single package (THE OPOSITE OF MONOREPO)",
49-
type: "boolean",
50-
},
51-
});
42+
return yargs.options({});
5243
},
53-
async handler(args) {
44+
async handler() {
5445
config.dists = config.dists || [
5546
{
5647
distDir: DIST_DIR,
5748
distPath: "",
5849
},
5950
];
60-
if (args.single) {
51+
52+
const [rootPackageJSONPath] = await globby("package.json", {
53+
cwd: process.cwd(),
54+
absolute: true,
55+
});
56+
const rootPackageJSON: Record<string, unknown> = await fse.readJSON(
57+
rootPackageJSONPath
58+
);
59+
const isSinglePackage =
60+
Array.isArray(rootPackageJSON.workspaces) === false;
61+
62+
if (isSinglePackage) {
6163
await buildSingle({ distDir: DIST_DIR });
6264
return;
6365
}

src/commands/runify.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import globby from "globby";
2+
import * as fse from "fs-extra";
23
import pLimit from "p-limit";
34
import fs from "fs-extra";
45
import { DepGraph } from "dependency-graph";
@@ -26,7 +27,6 @@ export const runifyCommand = createCommand<
2627
{},
2728
{
2829
tag?: string[];
29-
single?: boolean;
3030
}
3131
>((api) => {
3232
const { config, reporter } = api;
@@ -41,15 +41,20 @@ export const runifyCommand = createCommand<
4141
array: true,
4242
type: "string",
4343
},
44-
single: {
45-
describe: "Run only for the package in the current directory",
46-
type: "boolean",
47-
default: false,
48-
},
4944
});
5045
},
51-
async handler({ tag, single }) {
52-
if (single) {
46+
async handler({ tag }) {
47+
const [rootPackageJSONPath] = await globby("package.json", {
48+
cwd: process.cwd(),
49+
absolute: true,
50+
});
51+
const rootPackageJSON: Record<string, unknown> = await fse.readJSON(
52+
rootPackageJSONPath
53+
);
54+
const isSinglePackage =
55+
Array.isArray(rootPackageJSON.workspaces) === false;
56+
57+
if (isSinglePackage) {
5358
return runify(join(process.cwd(), "package.json"), config, reporter);
5459
}
5560

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "monorepo",
3+
"private": true,
4+
"workspaces": [
5+
"packages/*"
6+
]
7+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "a",
3+
"main": "dist/index.js",
4+
"module": "dist/index.mjs",
5+
"typings": "dist/index.d.ts",
6+
"typescript": {
7+
"definition": "dist/index.d.ts"
8+
},
9+
"exports": {
10+
".": {
11+
"require": "./dist/index.js",
12+
"import": "./dist/index.mjs"
13+
},
14+
"./*": {
15+
"require": "./dist/*.js",
16+
"import": "./dist/*.mjs"
17+
}
18+
},
19+
"buildOptions": {
20+
"input": "./src/index.ts"
21+
}
22+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const a = "WUP";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "b",
3+
"main": "dist/index.js",
4+
"module": "dist/index.mjs",
5+
"typings": "dist/index.d.ts",
6+
"typescript": {
7+
"definition": "dist/index.d.ts"
8+
},
9+
"exports": {
10+
".": {
11+
"require": "./dist/index.js",
12+
"import": "./dist/index.mjs"
13+
},
14+
"./*": {
15+
"require": "./dist/*.js",
16+
"import": "./dist/*.mjs"
17+
}
18+
},
19+
"buildOptions": {
20+
"input": "./src/index.ts"
21+
}
22+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const b = "SUP";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"outDir": "dist",
5+
"esModuleInterop": true,
6+
"allowSyntheticDefaultImports": true,
7+
"importHelpers": true,
8+
"experimentalDecorators": true,
9+
"module": "esnext",
10+
"target": "es2018",
11+
"lib": ["es6", "esnext", "es2015", "dom", "webworker"],
12+
"suppressImplicitAnyIndexErrors": true,
13+
"moduleResolution": "node",
14+
"emitDecoratorMetadata": true,
15+
"declaration": true,
16+
"noImplicitThis": true,
17+
"strict": true,
18+
"alwaysStrict": true,
19+
"noImplicitReturns": true,
20+
"noUnusedLocals": false,
21+
"resolveJsonModule": true,
22+
"skipLibCheck": true,
23+
"paths": {},
24+
"jsx": "preserve",
25+
"sourceMap": false,
26+
"inlineSourceMap": false
27+
},
28+
"include": ["packages"],
29+
"exclude": ["**/dist", "**/temp"]
30+
}

test/integration.spec.ts

Lines changed: 128 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,158 @@ const binaryFolder = path.join(__dirname, "..", "dist", "index.js");
77

88
it("can bundle a simple project", async () => {
99
await fse.remove(path.resolve(fixturesFolder, "simple", "dist"));
10-
const result = await execa("node", [binaryFolder, "build", "--single"], {
10+
const result = await execa("node", [binaryFolder, "build"], {
1111
cwd: path.resolve(fixturesFolder, "simple")
1212
});
1313
expect(result.exitCode).toEqual(0);
14-
const indexJsFilePath = path.resolve(
15-
fixturesFolder,
16-
"simple",
17-
"dist",
18-
"index.js"
14+
const baseDistPath = path.resolve(fixturesFolder, "simple", "dist");
15+
const indexJsFilePath = path.resolve(baseDistPath, "index.js");
16+
const indexMjsFilePath = path.resolve(baseDistPath, "index.mjs");
17+
const packageJsonFilePath = path.resolve(baseDistPath, "package.json");
18+
19+
expect(fse.readFileSync(indexJsFilePath, "utf8")).toMatchInlineSnapshot(`
20+
"'use strict';
21+
22+
Object.defineProperty(exports, '__esModule', { value: true });
23+
24+
var someNumber = 1;
25+
26+
exports.someNumber = someNumber;
27+
"
28+
`);
29+
expect(fse.readFileSync(indexMjsFilePath, "utf8")).toMatchInlineSnapshot(`
30+
"var someNumber = 1;
31+
32+
export { someNumber };
33+
"
34+
`);
35+
expect(fse.readFileSync(packageJsonFilePath, "utf8")).toMatchInlineSnapshot(`
36+
"{
37+
\\"name\\": \\"simple\\",
38+
\\"main\\": \\"index.js\\",
39+
\\"module\\": \\"index.mjs\\",
40+
\\"typings\\": \\"index.d.ts\\",
41+
\\"typescript\\": {
42+
\\"definition\\": \\"index.d.ts\\"
43+
},
44+
\\"exports\\": {
45+
\\".\\": {
46+
\\"require\\": \\"./index.js\\",
47+
\\"import\\": \\"./index.mjs\\"
48+
},
49+
\\"./*\\": {
50+
\\"require\\": \\"./*.js\\",
51+
\\"import\\": \\"./*.mjs\\"
52+
},
53+
\\"./package.json\\": \\"./package.json\\"
54+
}
55+
}
56+
"
57+
`);
58+
});
59+
60+
it("can build a monorepo project", async () => {
61+
await fse.remove(
62+
path.resolve(fixturesFolder, "simple-monorepo", "a", "dist")
1963
);
20-
const indexMjsFilePath = path.resolve(
64+
await fse.remove(
65+
path.resolve(fixturesFolder, "simple-monorepo", "b", "dist")
66+
);
67+
await execa("tsc", {
68+
cwd: path.resolve(fixturesFolder, "simple-monorepo")
69+
});
70+
const result = await execa("node", [binaryFolder, "build"], {
71+
cwd: path.resolve(fixturesFolder, "simple-monorepo")
72+
});
73+
expect(result.exitCode).toEqual(0);
74+
const baseDistAPath = path.resolve(
2175
fixturesFolder,
22-
"simple",
23-
"dist",
24-
"index.js"
76+
"simple-monorepo",
77+
"packages",
78+
"a",
79+
"dist"
2580
);
26-
const packageJsonFilePath = path.resolve(
81+
const baseDistBPath = path.resolve(
2782
fixturesFolder,
28-
"simple",
29-
"dist",
30-
"package.json"
83+
"simple-monorepo",
84+
"packages",
85+
"b",
86+
"dist"
3187
);
88+
const files = {
89+
a: {
90+
"index.js": path.resolve(baseDistAPath, "index.js"),
91+
"index.mjs": path.resolve(baseDistAPath, "index.mjs"),
92+
"package.json": path.resolve(baseDistAPath, "package.json")
93+
},
94+
b: {
95+
"index.js": path.resolve(baseDistBPath, "index.js"),
96+
"index.mjs": path.resolve(baseDistBPath, "index.mjs"),
97+
"package.json": path.resolve(baseDistBPath, "package.json")
98+
}
99+
};
32100

33-
expect(fse.readFileSync(indexJsFilePath, "utf8")).toMatchInlineSnapshot(`
101+
expect(fse.readFileSync(files.a["index.js"], "utf8")).toMatchInlineSnapshot(`
34102
"'use strict';
35103
36104
Object.defineProperty(exports, '__esModule', { value: true });
37105
38-
var someNumber = 1;
106+
const a = \\"WUP\\";
39107
40-
exports.someNumber = someNumber;
108+
exports.a = a;
41109
"
42110
`);
43-
expect(fse.readFileSync(indexMjsFilePath, "utf8")).toMatchInlineSnapshot(`
111+
expect(fse.readFileSync(files.a["index.mjs"], "utf8")).toMatchInlineSnapshot(`
112+
"const a = \\"WUP\\";
113+
114+
export { a };
115+
"
116+
`);
117+
expect(fse.readFileSync(files.a["package.json"], "utf8"))
118+
.toMatchInlineSnapshot(`
119+
"{
120+
\\"name\\": \\"a\\",
121+
\\"main\\": \\"index.js\\",
122+
\\"module\\": \\"index.mjs\\",
123+
\\"typings\\": \\"index.d.ts\\",
124+
\\"typescript\\": {
125+
\\"definition\\": \\"index.d.ts\\"
126+
},
127+
\\"exports\\": {
128+
\\".\\": {
129+
\\"require\\": \\"./index.js\\",
130+
\\"import\\": \\"./index.mjs\\"
131+
},
132+
\\"./*\\": {
133+
\\"require\\": \\"./*.js\\",
134+
\\"import\\": \\"./*.mjs\\"
135+
},
136+
\\"./package.json\\": \\"./package.json\\"
137+
}
138+
}
139+
"
140+
`);
141+
142+
expect(fse.readFileSync(files.b["index.js"], "utf8")).toMatchInlineSnapshot(`
44143
"'use strict';
45144
46145
Object.defineProperty(exports, '__esModule', { value: true });
47146
48-
var someNumber = 1;
147+
const b = \\"SUP\\";
49148
50-
exports.someNumber = someNumber;
149+
exports.b = b;
51150
"
52151
`);
53-
expect(fse.readFileSync(packageJsonFilePath, "utf8")).toMatchInlineSnapshot(`
152+
expect(fse.readFileSync(files.b["index.mjs"], "utf8")).toMatchInlineSnapshot(`
153+
"const b = \\"SUP\\";
154+
155+
export { b };
156+
"
157+
`);
158+
expect(fse.readFileSync(files.b["package.json"], "utf8"))
159+
.toMatchInlineSnapshot(`
54160
"{
55-
\\"name\\": \\"simple\\",
161+
\\"name\\": \\"b\\",
56162
\\"main\\": \\"index.js\\",
57163
\\"module\\": \\"index.mjs\\",
58164
\\"typings\\": \\"index.d.ts\\",

0 commit comments

Comments
 (0)