Skip to content

Releases: oven-sh/bun

Bun v0.0.27

01 Oct 07:14
Compare
Choose a tag to compare

Features

Relay GraphQL client

You can now use Facebook's Relay GraphQL framework with Bun via bun-macro-relay.

bun-macro-relay implements the Bun equivalent of babel-plugin-relay.

Input:

const query = graphql`
  query Bacon {
  }
`;

Output:

import Bacon from '__generated__/Bacon.graphql';
const query = Bacon;

This macro is implemented entirely in TypeScript - not in native code. For install instructions, head over to bun-macro-relay.

Automatically remap macros

// Instead of having to change every import like this:
import { css } from "@emotion/react";

// To this:
import { css } from "macro:bun-macro-emotion-react";

// Now you don't have to change your code
import { css } from "@emotion/react";

note: @emotion/react is not implemented yet!

To use this, add this to your package.json (and remove the comments):

  "bun": {
    "macros": {
      // "react-relay" is the import path to rewrite
      "react-relay": {
       // rewrite the "graphql" import to instead point to "bun-macro-relay/bun-macro-relay.tsx"
        "graphql": "bun-macro-relay/bun-macro-relay.tsx"
      }
    }
  },

Remapping this way only applies to macros. To rewrite imports otherwise, Bun will read paths from tsconfig.json or jsconfig.json.

Bug fixes

  • Fix edgecase with cjs -> esm interop runtime code when the ESM export was marked as not extensible
  • Fix potential infinite loop on calling macros
  • Fix incorrect jsxDEV transform when source feature flag is off and a runtime error occurs in a component being rendered
  • Fix dead-code elimination edgecase with call expressions
  • Fix edgecase with parsing .env containing very short strings

More macro features

  • <import> lets you inject an import statement into a module. It accepts default, which is the default import alias and you can pass a namespace object where the object maps the import names to their names in the current file
  • <id> lets you reference an import (and eventually, other symbols too)
  • <inject> will insert each child element to the module scope. This currently only works with <import>, but it will work with other statements eventually.

Here's an example:

  const importStmt = (
    <import default="MyImportName" path="foo/bar" />
  );

  return (
    <>
      <inject>{importStmt}</inject>
      <id to={importStmt.namespace.MyImportName} />
    </>
  );

Bun v0.0.26

28 Sep 04:53
Compare
Choose a tag to compare

Features

Bun Macro

Bun Macros are a simple way to move code snippets from runtime to build-time.

Use them for:

  • Zero runtime CSS-in-JS (or a little runtime, up to you)
  • GraphQL parsing
  • Static data fetching without a library (similar to Next.js' getStaticProps but from any file instead of just pages)
  • you can come up with more use cases

This API (and implementation) is very new and I want to hear feedback on what to change.

How to use macros:

  • Any import that starts with macro: is imported as a macro. Macros can be npm packages, local files, or anything else resolvable. These imports are always removed from the final output.
  • Imports must be a named import, and are matched against call expressions (function calls) and template literals. JSX props may be added in a future release

Here's a quick example of using a macro:

// This import won't exist at runtime!
import { matchInFile } from "macro:./matchInFile";

export const IPAddresses = () => (
  <div>
    <h2>recent ip addresses</h2>
    <div className="Lines">
      {/* matchInFile gets inlined into an array at compile time */}
      {matchInFile("access.log", /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}/).map(
        (ipAddress, index) => (
          <div className="Line" key={index}>
            {ipAddress}
          </div>
        )
      )}
    </div>
  </div>
);

The transpiled output looks something like this:

export const IPAddresses = () => jsx("div", {
    children: [
      jsx("h2", {
        children: ["recent ip addresses"]
      }, undefined, true, {}, this),
      jsx("div", {
        className: "Lines",
        children: [[
          "98.210.28.6",
          "192.99.4.168",
           // ... rest of the array 
       ].map((ipAddress, index) => jsx("div", {
          className: "Line",
          children: [ipAddress]
        }, index, true, {}, this))]
      }, undefined, true, {}, this)
 // ...rest of code
    ]
});

There are a few examples of how to write macros in https://github.com/Jarred-Sumner/bun/tree/main/examples/macros, but I will write more docs once I'm a little more confident that the API isn't going to change. Once I write macros for Relay and Emotion, I'll have a better sense for if this API is good enough or if there are changes to make.

I might change the import prefix from macro: to bun: because it's shorter and slightly faster to check (one u32 instead of a u32 and then a u16)

Credits

Bun Macros are inspired by babel-plugin-macros, which was Sunil Pai's idea. They're also sort of similar to Zig's comptime feature.

Bun.js

  • Bun.readFileAsBytes and Bun.readFile now accept an array of paths to join. Both of these are valid:

Option A:

Bun.readFile(Bun.cwd + "file.txt");

Option B:

Bun.readFile([Bun.cwd, "./text/", "file.txt"]);

Unlike Node.js' path.join, it's an explicit array instead of arguments because someday, we might want to add extra options to this function.

Bug fixes

  • Thanks @alexkuz for adding a check to the Makefile that necessary dependencies are installed prior to compiling Bun.
  • Fixed an occasional UTF-8 decoding bug in Response.text() (from fetch)
  • Fixed an edgecase in the URL parser where it would sometimes erroneously report the pathname as /
  • Fixed a typo in the error thrown when you pass a blank string to fetch
  • fetch now includes a User-Agent header by default. This is overridable, but it defaults to Bun.js v0.0.version-number

Bun v0.0.24

25 Sep 09:14
Compare
Choose a tag to compare

Bug fixes

  • Fix crash when both JSX automatic and JSX classic imports are automatically imported and unbundled
  • Fix lexing bug with the \f form feed character (used in Emotion & Styled Components)
  • Fix bug with resolving "browser" field in package.json. In some cases, it was resolving from the parent directory of the result instead of the browser scope.

Stability

  • Add integration test that checks styled-components renders successfully and no incorrect unicode characters are present in the style tag

Bun v0.0.23

25 Sep 07:49
Compare
Choose a tag to compare

Fix bug with JSX transform when using a key prop, a {...spread} prop and a callback function as a prop in the same element. Thank you @alexkuz for the repro

Bun v0.0.22

25 Sep 00:09
Compare
Choose a tag to compare

Features

  • Support resolving "exports" field in package.json. Webpack's guide does a great job explaining the "exports" field.
  • Add parsed lines of code counter to bun bun
  • Support importing files above the project root. HTTP Requests above the project root are allowlisted to specific file extensions to prevent common webserver security vulnerabilities like reading /etc/passwd. Absolute file path imports always start with abs:. The security questions aren't as relevant for localhost development, but still worth thinking about.
  • Support bundling symlinked workspace packages via bun bun. To use this, set "bun": { "alwaysBundle": ["packageName"] } in the project's package.json.
  • When bundling JSON, print the output as JSON.parse(jsonString) when the JSON is ASCII. JSON.parse is much faster for JavaScript engines to parse.

Bun.js

  • Implement console.time, console.timeEnd
  • Implement Bun.readFileBytes() to get a Uint8Array of the file's contents without copying.

Bug fixes

  • Fix handling when file metadata store exceeds statically allocated count (at time of writing, 16k)
  • Always log errors when generating node_modules.server.bun
  • Fix how error lines with strings are highlighted
  • Fix parsing/printing JavaScript unicode identifiers
  • Slightly improve .env loader string detection
  • More correct export default transform for bundled code
  • Fix a JavaScript simplification bug involving ternaries
  • Fix a JavaScript parsing bug with arrays in function arguments that have default values
  • Fix edgecase with bare imports inside .bun
  • Fix edgecase with whether to wrap arrow expressions in parentheses when printing
  • Fix edgecase when a bundled module with multiple-levels of nested exports have a boolean value for the default export
  • Globally define require() so that UMD modules which check for the existence of require() to determine if it's CommonJS use the CommonJS code path instead of the globalThis code path. This is not great.
  • Embed regeneratorRuntime so that modules which expect it to be a global work
  • Fix crash when loading JS fails really quickly

Misc

  • Begin adding integration tests with snapshots that run with HMR disabled & HMR enabled
  • Add comment explaining failed package.json parsing optimization
  • Elaborate on bun bun in the readme
  • Switch to UTF-8 for prefilled strings, remove eagerly loading identifier_name
  • Symlinks work but the readme wasn't updated
  • Add skeleton code for macros but do not execute them yet

Bun v0.0.21

18 Sep 01:38
Compare
Choose a tag to compare
  • Package.json

  • Slightly improve JSX decoding perf

  • Fix whitespace & emoji bug when parsing JSX

Bun v0.0.19

17 Sep 23:16
Compare
Choose a tag to compare

Fix lexer bug with UTF-16 strings (escaped) 

Bun v0.0.18

17 Sep 22:03
Compare
Choose a tag to compare
  • global -> globalThis
  • Fix symbol collision when using require unbundled to the same path multiple times

Bun v0.0.17

17 Sep 10:25
Compare
Choose a tag to compare
  • Colorize build/resolve errors and add a ^

  • Print absolute paths in log errors so that ctrl+click to open file in editor works (depending on terminal)

  • Delete some dead code

  • Always bold ^

  • When port is in use, auto-increment port number up to 10 times and then bail if all 10 are in use

  • Fix symbol name for cjs2esm

  • Help output should print command names

  • Add flag to dev server to disable HMR

  • Fix export * as from

  • Update options.zig

  • Do not attempt to HMR export {value} from, just assume it will be HMR'd (or not)

  • Fix bugs with ESM -> CJS when not bundled

  • Begin to add integration tests

  • Little more clarify readme

  • Add puppeteer to package.json

Bun v0.0.16

16 Sep 10:51
Compare
Choose a tag to compare
  • Switch to 0.0.x instead of 0.0.0-x to fix the npm install issue

  • write the version

  • Automatically rewrite TS import paths from .jsx? -> .tsx? when .jsx? is not found

    This was already partially implemented but it was returning filenames instead of absolute paths. This matches the behavior from microsoft/TypeScript#4595.