Skip to content

Commit

Permalink
Custom tsconfig path for the build command, default to `tsconfig.buil…
Browse files Browse the repository at this point in the history
…d.json` and fallback to `tsconfig.json` (#202)
  • Loading branch information
enisdenjo authored Mar 1, 2023
1 parent 1567b4d commit 2236863
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/proud-hairs-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'bob-the-bundler': major
---

Custom tsconfig path for the build command, default to `tsconfig.build.json` and fallback to
`tsconfig.json`.
24 changes: 20 additions & 4 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { presetFields, presetFieldsESM } from './bootstrap.js';

export const DIST_DIR = 'dist';

export const DEFAULT_TS_BUILD_CONFIG = 'tsconfig.build.json';

interface PackageInfo {
packagePath: string;
cwd: string;
Expand Down Expand Up @@ -65,10 +67,18 @@ function assertTypeScriptBuildResult(result: ExecaReturnValue) {
}
}

async function buildTypeScript(buildPath: string, options: { incremental?: boolean } = {}) {
async function buildTypeScript(
buildPath: string,
options: { cwd: string; tsconfig?: string; incremental?: boolean },
) {
let tsconfig = options.tsconfig;
if (!tsconfig && (await fse.exists(join(options.cwd, DEFAULT_TS_BUILD_CONFIG)))) {
tsconfig = join(options.cwd, DEFAULT_TS_BUILD_CONFIG);
}
assertTypeScriptBuildResult(
await execa('npx', [
'tsc',
...(tsconfig ? ['--project', tsconfig] : []),
...compilerOptionsToArgs(typeScriptCompilerOptions('esm')),
...(options.incremental ? ['--incremental'] : []),
'--outDir',
Expand All @@ -79,6 +89,7 @@ async function buildTypeScript(buildPath: string, options: { incremental?: boole
assertTypeScriptBuildResult(
await execa('npx', [
'tsc',
...(tsconfig ? ['--project', tsconfig] : []),
...compilerOptionsToArgs(typeScriptCompilerOptions('cjs')),
...(options.incremental ? ['--incremental'] : []),
'--outDir',
Expand All @@ -90,6 +101,7 @@ async function buildTypeScript(buildPath: string, options: { incremental?: boole
export const buildCommand = createCommand<
{},
{
tsconfig?: string;
incremental?: boolean;
}
>(api => {
Expand All @@ -100,13 +112,17 @@ export const buildCommand = createCommand<
describe: 'Build',
builder(yargs) {
return yargs.options({
tsconfig: {
describe: `Which tsconfig file to use when building TypeScript. By default bob will use ${DEFAULT_TS_BUILD_CONFIG} if it exists, otherwise the TSC's default.`,
type: 'string',
},
incremental: {
describe: 'Better performance by building only packages that had changes.',
type: 'boolean',
},
});
},
async handler({ incremental }) {
async handler({ tsconfig, incremental }) {
const cwd = process.cwd();
const rootPackageJSON = await getRootPackageJSON();
const workspaces = await getWorkspaces(rootPackageJSON);
Expand All @@ -118,7 +134,7 @@ export const buildCommand = createCommand<
if (!incremental) {
await fse.remove(buildPath);
}
await buildTypeScript(buildPath, { incremental });
await buildTypeScript(buildPath, { cwd, tsconfig, incremental });
const pkg = await fse.readJSON(resolve(cwd, 'package.json'));
const fullName: string = pkg.name;

Expand Down Expand Up @@ -155,7 +171,7 @@ export const buildCommand = createCommand<
if (!incremental) {
await fse.remove(bobBuildPath);
}
await buildTypeScript(bobBuildPath, { incremental });
await buildTypeScript(bobBuildPath, { cwd, tsconfig, incremental });

await Promise.all(
packageInfoList.map(({ cwd, pkg, fullName }) =>
Expand Down
1 change: 1 addition & 0 deletions test/__fixtures__/tsconfig-build-json/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello!
46 changes: 46 additions & 0 deletions test/__fixtures__/tsconfig-build-json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "tsconfig-build-json",
"type": "module",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"require": {
"types": "./dist/typings/index.d.cts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
},
"default": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./*": {
"require": {
"types": "./dist/typings/*.d.cts",
"default": "./dist/cjs/*.js"
},
"import": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
},
"default": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
}
},
"./package.json": "./package.json",
"./style.css": "./dist/esm/style.css"
},
"typings": "dist/typings/index.d.ts",
"publishConfig": {
"directory": "dist",
"access": "public"
},
"typescript": {
"definition": "dist/typings/index.d.ts"
}
}
3 changes: 3 additions & 0 deletions test/__fixtures__/tsconfig-build-json/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const hello = 1;

export default 'there';
7 changes: 7 additions & 0 deletions test/__fixtures__/tsconfig-build-json/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"declaration": false
}
}
8 changes: 8 additions & 0 deletions test/__fixtures__/tsconfig-build-json/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "ESNext",
"declaration": true,
"skipLibCheck": true,
"outDir": "dist"
}
}
81 changes: 81 additions & 0 deletions test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,84 @@ it('can build a monorepo pnpm project', async () => {
cwd: path.resolve(fixturesFolder, 'simple-monorepo-pnpm'),
});
});

it('can bundle a tsconfig-build-json project', async () => {
await fse.remove(path.resolve(fixturesFolder, 'tsconfig-build-json', 'dist'));

const result = await execa('node', [binaryFolder, 'build'], {
cwd: path.resolve(fixturesFolder, 'tsconfig-build-json'),
});
expect(result.exitCode).toEqual(0);

const baseDistPath = path.resolve(fixturesFolder, 'tsconfig-build-json', 'dist');
await expect(fse.readFile(path.resolve(baseDistPath, 'package.json'), 'utf8')).resolves
.toMatchInlineSnapshot(`
{
"name": "tsconfig-build-json",
"main": "cjs/index.js",
"module": "esm/index.js",
"typings": "typings/index.d.ts",
"typescript": {
"definition": "typings/index.d.ts"
},
"type": "module",
"exports": {
".": {
"require": {
"types": "./typings/index.d.cts",
"default": "./cjs/index.js"
},
"import": {
"types": "./typings/index.d.ts",
"default": "./esm/index.js"
},
"default": {
"types": "./typings/index.d.ts",
"default": "./esm/index.js"
}
},
"./*": {
"require": {
"types": "./typings/*.d.cts",
"default": "./cjs/*.js"
},
"import": {
"types": "./typings/*.d.ts",
"default": "./esm/*.js"
},
"default": {
"types": "./typings/*.d.ts",
"default": "./esm/*.js"
}
},
"./package.json": "./package.json",
"./style.css": "./esm/style.css"
}
}
`);
await expect(
fse.readFile(path.resolve(baseDistPath, 'README.md'), 'utf8'),
).resolves.toMatchInlineSnapshot('Hello!');
await expect(fse.readFile(path.resolve(baseDistPath, 'cjs', 'index.js'), 'utf8')).resolves
.toMatchInlineSnapshot(`
"use strict";
exports.__esModule = true;
exports.hello = void 0;
exports.hello = 1;
exports["default"] = 'there';
`);
await expect(fse.readFile(path.resolve(baseDistPath, 'esm', 'index.js'), 'utf8')).resolves
.toMatchInlineSnapshot(`
export var hello = 1;
export default 'there';
`);

// because the tsconfig.build.json has `declaration: false`
await expect(fse.stat(path.resolve(baseDistPath, 'typings', 'index.d.ts'))).rejects.toThrowError(
'ENOENT: no such file or directory',
);

await execa('node', [binaryFolder, 'check'], {
cwd: path.resolve(fixturesFolder, 'simple'),
});
});

0 comments on commit 2236863

Please sign in to comment.