oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.45k stars 2.78k forks source link

Dynamic output paths for the entrypoints of Bun.build #6610

Open itsyoboieltr opened 1 year ago

itsyoboieltr commented 1 year ago

What is the problem this feature would solve?

It would be great if we could customize the output path for each entrypoint in Bun.build dynamically. I would suggest some kind of callback function for this, where we could do some pre-processing on the resolved path(s) before they are written on the disk. This would solve the problem, that currently the build either needs to have the same structure as the source code, or that it is needed to roll our own build script and manually loop over the files to customize the output path(s).

What is the feature you are proposing to solve the problem?

Callback function to modify the resolved path(s) before they are written on the disk. Maybe something like:

{
  beforeWriteFile: (file) => {
    return file;
  },
}

or

{
  afterBuild: (files) => {
    return files;
  },
}

Or any other API that would be general enough to allow for more flexibility in terms of the saved paths of the files.

What alternatives have you considered?

The alternative is doing everything manually, but this should cause some performance and dev exp loss.

import { glob } from 'glob';
import path from 'path';
import fs from 'fs/promises';

const outdir = './dist';

const entrypoints = await glob('src/**/index.@(ts|tsx)');

const result = await Bun.build({
  entrypoints,
  root: './src',
  splitting: true,
  minify: true,
});

try {
  await fs.access(outdir);
  await fs.rm(outdir, { recursive: true, force: true });
} catch (error: any) {
  if (error.code !== 'ENOENT') throw error;
}

for (const output of result.outputs) {
  const outputPath = output.path.replace(`stories${path.sep}`, '');
  await fs.mkdir(path.join(outdir, path.dirname(outputPath)), {
    recursive: true,
  });
  await Bun.write(path.join(outdir, outputPath), output);
}
ghost commented 3 months ago

+1. Only with FS operations inside a build.mjs script customizing the output of Bun.build to anything that isn't the same name as the entrypoint file is kind of a bummer, considering this shit can be done in ESBuild with almost no issues.