Skip to content

Commit

Permalink
--footer esbuild & rollup style! (#14396)
Browse files Browse the repository at this point in the history
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
  • Loading branch information
versecafe and Jarred-Sumner authored Oct 8, 2024
1 parent a234e06 commit 7996d06
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 9 deletions.
22 changes: 20 additions & 2 deletions docs/bundler/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ $ bun build ./index.tsx --outdir ./out --loader .png:dataurl --loader .txt:file

### `banner`

A banner to be added to the final bundle, this can be a directive like "use client" for react or a comment block such as a license for the code.
A banner to be added to the final bundle, this can be a directive like "use client" for react or a comment block such as a license for the code.

{% codetabs %}

Expand All @@ -1108,11 +1108,29 @@ await Bun.build({
$ bun build ./index.tsx --outdir ./out --banner "\"use client\";"
```

### `footer`

A footer to be added to the final bundle, this can be something like a comment block for a license or just a fun easter egg.

{% codetabs %}

```ts#JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
footer: '// built with love in SF'
})
```

```bash#CLI
$ bun build ./index.tsx --outdir ./out --footer="// built with love in SF"
```

{% /codetabs %}

### `experimentalCss`

Whether to enable *experimental* support for bundling CSS files. Defaults to `false`.
Whether to enable _experimental_ support for bundling CSS files. Defaults to `false`.

This supports bundling CSS files imported from JS, as well as CSS entrypoints.

Expand Down
12 changes: 6 additions & 6 deletions docs/bundler/vs-esbuild.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
---
- `--footer`
- `--footer`
- Only applies to js bundles
---
- `--certfile`
- n/a
- Not applicable
Expand Down Expand Up @@ -195,12 +201,6 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
---
- `--footer`
- n/a
- Not supported
---
- `--global-name`
- n/a
- Not applicable, Bun does not support `iife` output at this time
Expand Down
6 changes: 6 additions & 0 deletions packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,12 @@ declare module "bun" {
* Add a banner to the bundled code such as "use client";
*/
banner?: string;
/**
* Add a footer to the bundled code such as a comment block like
*
* `// made with bun!`
*/
footer?: string;

/**
* **Experimental**
Expand Down
7 changes: 7 additions & 0 deletions src/bun.js/api/JSBundler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub const JSBundler = struct {
format: options.Format = .esm,
bytecode: bool = false,
banner: OwnedString = OwnedString.initEmpty(bun.default_allocator),
footer: OwnedString = OwnedString.initEmpty(bun.default_allocator),
experimental_css: bool = false,

pub const List = bun.StringArrayHashMapUnmanaged(Config);
Expand Down Expand Up @@ -190,6 +191,12 @@ pub const JSBundler = struct {
try this.banner.appendSliceExact(slice.slice());
}


if (try config.getOptional(globalThis, "footer", ZigString.Slice)) |slice| {
defer slice.deinit();
try this.footer.appendSliceExact(slice.slice());
}

if (config.getTruthy(globalThis, "sourcemap")) |source_map_js| {
if (bun.FeatureFlags.breaking_changes_1_2 and config.isBoolean()) {
if (source_map_js == .true) {
Expand Down
14 changes: 13 additions & 1 deletion src/bundler/bundle_v2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,7 @@ pub const BundleV2 = struct {
this.linker.options.ignore_dce_annotations = bundler.options.ignore_dce_annotations;

this.linker.options.banner = bundler.options.banner;
this.linker.options.footer = bundler.options.footer;

this.linker.options.experimental_css = bundler.options.experimental_css;

Expand Down Expand Up @@ -1478,6 +1479,7 @@ pub const BundleV2 = struct {
bundler.options.ignore_dce_annotations = config.ignore_dce_annotations;
bundler.options.experimental_css = config.experimental_css;
bundler.options.banner = config.banner.toOwnedSlice();
bundler.options.footer = config.footer.toOwnedSlice();

bundler.configureLinker();
try bundler.configureDefines();
Expand Down Expand Up @@ -4602,6 +4604,7 @@ pub const LinkerContext = struct {
minify_syntax: bool = false,
minify_identifiers: bool = false,
banner: []const u8 = "",
footer: []const u8 = "",
experimental_css: bool = false,
source_maps: options.SourceMapOption = .none,
target: options.Target = .browser,
Expand Down Expand Up @@ -8977,7 +8980,16 @@ pub const LinkerContext = struct {
j.ensureNewlineAtEnd();
// TODO: maybeAppendLegalComments

// TODO: footer
if (c.options.footer.len > 0) {
if (newline_before_comment) {
j.pushStatic("\n");
line_offset.advance("\n");
}
j.pushStatic(ctx.c.options.footer);
line_offset.advance(ctx.c.options.footer);
j.pushStatic("\n");
line_offset.advance("\n");
}

chunk.intermediate_output = c.breakOutputIntoPieces(
worker.allocator,
Expand Down
6 changes: 6 additions & 0 deletions src/cli.zig
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ pub const Arguments = struct {
clap.parseParam("--outfile <STR> Write to a file") catch unreachable,
clap.parseParam("--sourcemap <STR>? Build with sourcemaps - 'linked', 'inline', 'external', or 'none'") catch unreachable,
clap.parseParam("--banner <STR> Add a banner to the bundled output such as \"use client\"; for a bundle being used with RSCs") catch unreachable,
clap.parseParam("--footer <STR> Add a footer to the bundled output such as // built with bun!") catch unreachable,
clap.parseParam("--format <STR> Specifies the module format to build to. Only \"esm\" is supported.") catch unreachable,
clap.parseParam("--root <STR> Root directory used for multiple entry points") catch unreachable,
clap.parseParam("--splitting Enable code splitting") catch unreachable,
Expand Down Expand Up @@ -783,6 +784,10 @@ pub const Arguments = struct {
ctx.bundler_options.banner = banner;
}

if (args.option("--footer")) |footer| {
ctx.bundler_options.footer = footer;
}

const experimental_css = args.flag("--experimental-css");
ctx.bundler_options.experimental_css = experimental_css;

Expand Down Expand Up @@ -1408,6 +1413,7 @@ pub const Command = struct {
output_format: options.Format = .esm,
bytecode: bool = false,
banner: []const u8 = "",
footer: []const u8 = "",
experimental_css: bool = false,
};

Expand Down
2 changes: 2 additions & 0 deletions src/cli/build_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub const BuildCommand = struct {
this_bundler.options.ignore_dce_annotations = ctx.bundler_options.ignore_dce_annotations;

this_bundler.options.banner = ctx.bundler_options.banner;
this_bundler.options.footer = ctx.bundler_options.footer;

this_bundler.options.experimental_css = ctx.bundler_options.experimental_css;

this_bundler.options.output_dir = ctx.bundler_options.outdir;
Expand Down
29 changes: 29 additions & 0 deletions test/bundler/bundler_footer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe } from "bun:test";
import { itBundled } from "./expectBundled";

describe("bundler", () => {
itBundled("footer/CommentFooter", {
footer: "// developed with love in SF",
files: {
"/a.js": `console.log("Hello, world!")`,
},
onAfterBundle(api) {
api.expectFile("out.js").toEndWith('// developed with love in SF"\n');
},
});
itBundled("footer/MultilineFooter", {
footer: `/**
* This is copyright of [...] ${new Date().getFullYear()}
* do not redistribute without consent of [...]
*/`,
files: {
"index.js": `console.log("Hello, world!")`,
},
onAfterBundle(api) {
api.expectFile("out.js").toEndWith(`/**
* This is copyright of [...] ${new Date().getFullYear()}
* do not redistribute without consent of [...]
*/\"\n`);
},
});
});
4 changes: 4 additions & 0 deletions test/bundler/expectBundled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export interface BundlerTestInput {
alias?: Record<string, string>;
assetNaming?: string;
banner?: string;
footer?: string;
define?: Record<string, string | number>;

/** Use for resolve custom conditions */
Expand Down Expand Up @@ -416,6 +417,7 @@ function expectBundled(
external,
packages,
files,
footer,
format,
globalName,
inject,
Expand Down Expand Up @@ -666,6 +668,7 @@ function expectBundled(
serverComponents && "--server-components",
outbase && `--root=${outbase}`,
banner && `--banner="${banner}"`, // TODO: --banner-css=*
footer && `--footer="${footer}"`,
ignoreDCEAnnotations && `--ignore-dce-annotations`,
emitDCEAnnotations && `--emit-dce-annotations`,
// inject && inject.map(x => ["--inject", path.join(root, x)]),
Expand Down Expand Up @@ -710,6 +713,7 @@ function expectBundled(
metafile && `--metafile=${metafile}`,
sourceMap && `--sourcemap=${sourceMap}`,
banner && `--banner:js=${banner}`,
footer && `--footer:js=${footer}`,
legalComments && `--legal-comments=${legalComments}`,
ignoreDCEAnnotations && `--ignore-annotations`,
splitting && `--splitting`,
Expand Down

0 comments on commit 7996d06

Please sign in to comment.