Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/tasty-bags-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bob-the-bundler": minor
---

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.
30 changes: 16 additions & 14 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as rollup from "rollup";
import * as fse from "fs-extra";
import generatePackageJson from "rollup-plugin-generate-package-json";
import { autoExternal } from "../rollup-plugins/auto-external";
import resolveNode from "@rollup/plugin-node-resolve";
Expand Down Expand Up @@ -31,33 +32,34 @@ interface PackageInfo {
fullName: string;
}

export const buildCommand = createCommand<
{},
{
single?: boolean;
}
>((api) => {
export const buildCommand = createCommand<{}, {}>((api) => {
const { config, reporter } = api;

return {
command: "build",
describe: "Build",
builder(yargs) {
return yargs.options({
single: {
describe: "Single package (THE OPOSITE OF MONOREPO)",
type: "boolean",
},
});
return yargs.options({});
},
async handler(args) {
async handler() {
config.dists = config.dists || [
{
distDir: DIST_DIR,
distPath: "",
},
];
if (args.single) {

const [rootPackageJSONPath] = await globby("package.json", {
cwd: process.cwd(),
absolute: true,
});
const rootPackageJSON: Record<string, unknown> = await fse.readJSON(
rootPackageJSONPath
);
const isSinglePackage =
Array.isArray(rootPackageJSON.workspaces) === false;

if (isSinglePackage) {
await buildSingle({ distDir: DIST_DIR });
return;
}
Expand Down
21 changes: 13 additions & 8 deletions src/commands/runify.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import globby from "globby";
import * as fse from "fs-extra";
import pLimit from "p-limit";
import fs from "fs-extra";
import { DepGraph } from "dependency-graph";
Expand Down Expand Up @@ -26,7 +27,6 @@ export const runifyCommand = createCommand<
{},
{
tag?: string[];
single?: boolean;
}
>((api) => {
const { config, reporter } = api;
Expand All @@ -41,15 +41,20 @@ export const runifyCommand = createCommand<
array: true,
type: "string",
},
single: {
describe: "Run only for the package in the current directory",
type: "boolean",
default: false,
},
});
},
async handler({ tag, single }) {
if (single) {
async handler({ tag }) {
const [rootPackageJSONPath] = await globby("package.json", {
cwd: process.cwd(),
absolute: true,
});
const rootPackageJSON: Record<string, unknown> = await fse.readJSON(
rootPackageJSONPath
);
const isSinglePackage =
Array.isArray(rootPackageJSON.workspaces) === false;

if (isSinglePackage) {
return runify(join(process.cwd(), "package.json"), config, reporter);
}

Expand Down
7 changes: 7 additions & 0 deletions test/__fixtures__/simple-monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "monorepo",
"private": true,
"workspaces": [
"packages/*"
]
}
22 changes: 22 additions & 0 deletions test/__fixtures__/simple-monorepo/packages/a/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "a",
"main": "dist/index.js",
"module": "dist/index.mjs",
"typings": "dist/index.d.ts",
"typescript": {
"definition": "dist/index.d.ts"
},
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./*": {
"require": "./dist/*.js",
"import": "./dist/*.mjs"
}
},
"buildOptions": {
"input": "./src/index.ts"
}
}
1 change: 1 addition & 0 deletions test/__fixtures__/simple-monorepo/packages/a/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a = "WUP";
22 changes: 22 additions & 0 deletions test/__fixtures__/simple-monorepo/packages/b/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "b",
"main": "dist/index.js",
"module": "dist/index.mjs",
"typings": "dist/index.d.ts",
"typescript": {
"definition": "dist/index.d.ts"
},
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./*": {
"require": "./dist/*.js",
"import": "./dist/*.mjs"
}
},
"buildOptions": {
"input": "./src/index.ts"
}
}
1 change: 1 addition & 0 deletions test/__fixtures__/simple-monorepo/packages/b/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const b = "SUP";
30 changes: 30 additions & 0 deletions test/__fixtures__/simple-monorepo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"importHelpers": true,
"experimentalDecorators": true,
"module": "esnext",
"target": "es2018",
"lib": ["es6", "esnext", "es2015", "dom", "webworker"],
"suppressImplicitAnyIndexErrors": true,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"declaration": true,
"noImplicitThis": true,
"strict": true,
"alwaysStrict": true,
"noImplicitReturns": true,
"noUnusedLocals": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"paths": {},
"jsx": "preserve",
"sourceMap": false,
"inlineSourceMap": false
},
"include": ["packages"],
"exclude": ["**/dist", "**/temp"]
}
150 changes: 128 additions & 22 deletions test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,158 @@ const binaryFolder = path.join(__dirname, "..", "dist", "index.js");

it("can bundle a simple project", async () => {
await fse.remove(path.resolve(fixturesFolder, "simple", "dist"));
const result = await execa("node", [binaryFolder, "build", "--single"], {
const result = await execa("node", [binaryFolder, "build"], {
cwd: path.resolve(fixturesFolder, "simple")
});
expect(result.exitCode).toEqual(0);
const indexJsFilePath = path.resolve(
fixturesFolder,
"simple",
"dist",
"index.js"
const baseDistPath = path.resolve(fixturesFolder, "simple", "dist");
const indexJsFilePath = path.resolve(baseDistPath, "index.js");
const indexMjsFilePath = path.resolve(baseDistPath, "index.mjs");
const packageJsonFilePath = path.resolve(baseDistPath, "package.json");

expect(fse.readFileSync(indexJsFilePath, "utf8")).toMatchInlineSnapshot(`
"'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var someNumber = 1;

exports.someNumber = someNumber;
"
`);
expect(fse.readFileSync(indexMjsFilePath, "utf8")).toMatchInlineSnapshot(`
"var someNumber = 1;

export { someNumber };
"
`);
expect(fse.readFileSync(packageJsonFilePath, "utf8")).toMatchInlineSnapshot(`
"{
\\"name\\": \\"simple\\",
\\"main\\": \\"index.js\\",
\\"module\\": \\"index.mjs\\",
\\"typings\\": \\"index.d.ts\\",
\\"typescript\\": {
\\"definition\\": \\"index.d.ts\\"
},
\\"exports\\": {
\\".\\": {
\\"require\\": \\"./index.js\\",
\\"import\\": \\"./index.mjs\\"
},
\\"./*\\": {
\\"require\\": \\"./*.js\\",
\\"import\\": \\"./*.mjs\\"
},
\\"./package.json\\": \\"./package.json\\"
}
}
"
`);
});

it("can build a monorepo project", async () => {
await fse.remove(
path.resolve(fixturesFolder, "simple-monorepo", "a", "dist")
);
const indexMjsFilePath = path.resolve(
await fse.remove(
path.resolve(fixturesFolder, "simple-monorepo", "b", "dist")
);
await execa("tsc", {
cwd: path.resolve(fixturesFolder, "simple-monorepo")
});
const result = await execa("node", [binaryFolder, "build"], {
cwd: path.resolve(fixturesFolder, "simple-monorepo")
});
expect(result.exitCode).toEqual(0);
const baseDistAPath = path.resolve(
fixturesFolder,
"simple",
"dist",
"index.js"
"simple-monorepo",
"packages",
"a",
"dist"
);
const packageJsonFilePath = path.resolve(
const baseDistBPath = path.resolve(
fixturesFolder,
"simple",
"dist",
"package.json"
"simple-monorepo",
"packages",
"b",
"dist"
);
const files = {
a: {
"index.js": path.resolve(baseDistAPath, "index.js"),
"index.mjs": path.resolve(baseDistAPath, "index.mjs"),
"package.json": path.resolve(baseDistAPath, "package.json")
},
b: {
"index.js": path.resolve(baseDistBPath, "index.js"),
"index.mjs": path.resolve(baseDistBPath, "index.mjs"),
"package.json": path.resolve(baseDistBPath, "package.json")
}
};

expect(fse.readFileSync(indexJsFilePath, "utf8")).toMatchInlineSnapshot(`
expect(fse.readFileSync(files.a["index.js"], "utf8")).toMatchInlineSnapshot(`
"'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var someNumber = 1;
const a = \\"WUP\\";

exports.someNumber = someNumber;
exports.a = a;
"
`);
expect(fse.readFileSync(indexMjsFilePath, "utf8")).toMatchInlineSnapshot(`
expect(fse.readFileSync(files.a["index.mjs"], "utf8")).toMatchInlineSnapshot(`
"const a = \\"WUP\\";

export { a };
"
`);
expect(fse.readFileSync(files.a["package.json"], "utf8"))
.toMatchInlineSnapshot(`
"{
\\"name\\": \\"a\\",
\\"main\\": \\"index.js\\",
\\"module\\": \\"index.mjs\\",
\\"typings\\": \\"index.d.ts\\",
\\"typescript\\": {
\\"definition\\": \\"index.d.ts\\"
},
\\"exports\\": {
\\".\\": {
\\"require\\": \\"./index.js\\",
\\"import\\": \\"./index.mjs\\"
},
\\"./*\\": {
\\"require\\": \\"./*.js\\",
\\"import\\": \\"./*.mjs\\"
},
\\"./package.json\\": \\"./package.json\\"
}
}
"
`);

expect(fse.readFileSync(files.b["index.js"], "utf8")).toMatchInlineSnapshot(`
"'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var someNumber = 1;
const b = \\"SUP\\";

exports.someNumber = someNumber;
exports.b = b;
"
`);
expect(fse.readFileSync(packageJsonFilePath, "utf8")).toMatchInlineSnapshot(`
expect(fse.readFileSync(files.b["index.mjs"], "utf8")).toMatchInlineSnapshot(`
"const b = \\"SUP\\";

export { b };
"
`);
expect(fse.readFileSync(files.b["package.json"], "utf8"))
.toMatchInlineSnapshot(`
"{
\\"name\\": \\"simple\\",
\\"name\\": \\"b\\",
\\"main\\": \\"index.js\\",
\\"module\\": \\"index.mjs\\",
\\"typings\\": \\"index.d.ts\\",
Expand Down