diff options
author | 2023-10-12 23:05:20 -0700 | |
---|---|---|
committer | 2023-10-12 23:05:20 -0700 | |
commit | 4e678627532d04e16333047987ccd099922bb987 (patch) | |
tree | 88800fc9d5083d0e9243d5e5d4f4f8d0315db91a | |
parent | 584e6dd1c2240fd1767b7a7280e4695965f71237 (diff) | |
download | bun-4e678627532d04e16333047987ccd099922bb987.tar.gz bun-4e678627532d04e16333047987ccd099922bb987.tar.zst bun-4e678627532d04e16333047987ccd099922bb987.zip |
Add overrides/resolutions docs (#6476)
-rw-r--r-- | docs/cli/add.md | 155 | ||||
-rw-r--r-- | docs/cli/install.md | 285 | ||||
-rw-r--r-- | docs/cli/link.md | 46 | ||||
-rw-r--r-- | docs/cli/pm.md (renamed from docs/install/utilities.md) | 0 | ||||
-rw-r--r-- | docs/cli/remove.md | 5 | ||||
-rw-r--r-- | docs/cli/update.md | 9 | ||||
-rw-r--r-- | docs/install/lifecycle.md | 44 | ||||
-rw-r--r-- | docs/install/overrides.md | 73 | ||||
-rw-r--r-- | docs/nav.ts | 28 |
9 files changed, 429 insertions, 216 deletions
diff --git a/docs/cli/add.md b/docs/cli/add.md new file mode 100644 index 000000000..4b555d5a6 --- /dev/null +++ b/docs/cli/add.md @@ -0,0 +1,155 @@ +To add a particular package: + +```bash +$ bun add preact +``` + +To specify a version, version range, or tag: + +```bash +$ bun add zod@3.20.0 +$ bun add zod@^3.0.0 +$ bun add zod@latest +``` + +## `--dev` + +{% callout %} +**Alias** — `--development`, `-d`, `-D` +{% /callout %} + +To add a package as a dev dependency (`"devDependencies"`): + +```bash +$ bun add --dev @types/react +$ bun add -d @types/react +``` + +## `--optional` + +To add a package as an optional dependency (`"optionalDependencies"`): + +```bash +$ bun add --optional lodash +``` + +## `--exact` + +To add a package and pin to the resolved version, use `--exact`. This will resolve the version of the package and add it to your `package.json` with an exact version number instead of a version range. + +```bash +$ bun add react --exact +$ bun add react -E +``` + +This will add the following to your `package.json`: + +```jsonc +{ + "dependencies": { + // without --exact + "react": "^18.2.0", // this matches >= 18.2.0 < 19.0.0 + + // with --exact + "react": "18.2.0" // this matches only 18.2.0 exactly + } +} +``` + +To view a complete list of options for this command: + +```bash +$ bun add --help +``` + +## `--global` + +{% callout %} +**Note** — This would not modify package.json of your current project folder. +**Alias** - `bun add --global`, `bun add -g`, `bun install --global` and `bun install -g` +{% /callout %} + +To install a package globally, use the `-g`/`--global` flag. This will not modify the `package.json` of your current project. Typically this is used for installing command-line tools. + +```bash +$ bun add --global cowsay # or `bun add -g cowsay` +$ cowsay "Bun!" + ______ +< Bun! > + ------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +{% details summary="Configuring global installation behavior" %} + +```toml +[install] +# where `bun add --global` installs packages +globalDir = "~/.bun/install/global" + +# where globally-installed package bins are linked +globalBinDir = "~/.bun/bin" +``` + +{% /details %} + +## Trusted dependencies + +Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for installed dependencies, such as `postinstall`. These scripts represent a potential security risk, as they can execute arbitrary code on your machine. + +To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json. + +```json-diff + { + "name": "my-app", + "version": "1.0.0", ++ "trustedDependencies": ["my-trusted-package"] + } +``` + +Bun reads this field and will run lifecycle scripts for `my-trusted-package`. + +<!-- Bun maintains an allow-list of popular packages containing `postinstall` scripts that are known to be safe. To run lifecycle scripts for packages that aren't on this list, add the package to `trustedDependencies` in your package.json. --> + +## Git dependencies + +To add a dependency from a git repository: + +```bash +$ bun add git@github.com:moment/moment.git +``` + +Bun supports a variety of protocols, including [`github`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#github-urls), [`git`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#git-urls-as-dependencies), `git+ssh`, `git+https`, and many more. + +```json +{ + "dependencies": { + "dayjs": "git+https://github.com/iamkun/dayjs.git", + "lodash": "git+ssh://github.com/lodash/lodash.git#4.17.21", + "moment": "git@github.com:moment/moment.git", + "zod": "github:colinhacks/zod" + } +} +``` + +## Tarball dependencies + +A package name can correspond to a publicly hosted `.tgz` file. During installation, Bun will download and install the package from the specified tarball URL, rather than from the package registry. + +```sh +$ bun add zod@https://registry.npmjs.org/zod/-/zod-3.21.4.tgz +``` + +This will add the following line to your `package.json`: + +```json#package.json +{ + "dependencies": { + "zod": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz" + } +} +``` diff --git a/docs/cli/install.md b/docs/cli/install.md index 3a60fb054..63dbb1163 100644 --- a/docs/cli/install.md +++ b/docs/cli/install.md @@ -23,41 +23,19 @@ sudo apt install --install-recommends linux-generic-hwe-20.04 {% /details %} -## `bun install` - To install all dependencies of a project: ```bash $ bun install ``` -On Linux, `bun install` tends to install packages 20-100x faster than `npm install`. On macOS, it's more like 4-80x. - - - Running `bun install` will: - **Install** all `dependencies`, `devDependencies`, and `optionalDependencies`. Bun does not install `peerDependencies` by default. - **Run** your project's `{pre|post}install` and `{pre|post}prepare` scripts at the appropriate time. For security reasons Bun _does not execute_ lifecycle scripts of installed dependencies. - **Write** a `bun.lockb` lockfile to the project root. -To install in production mode (i.e. without `devDependencies` or `optionalDependencies`): - -```bash -$ bun install --production -``` - -To install with reproducible dependencies, use `--frozen-lockfile`. If your `package.json` disagrees with `bun.lockb`, Bun will exit with an error. This is useful for production builds and CI environments. - -```bash -$ bun install --frozen-lockfile -``` - -To perform a dry run (i.e. don't actually install anything): - -```bash -$ bun install --dry-run -``` +## Logging To modify logging verbosity: @@ -66,99 +44,59 @@ $ bun install --verbose # debug logging $ bun install --silent # no logging ``` -{% details summary="Configuring behavior" %} -The default behavior of `bun install` can be configured in `bunfig.toml`: - -```toml -[install] - -# whether to install optionalDependencies -optional = true - -# whether to install devDependencies -dev = true - -# whether to install peerDependencies -peer = false - -# equivalent to `--production` flag -production = false - -# equivalent to `--frozen-lockfile` flag -frozenLockfile = false - -# equivalent to `--dry-run` flag -dryRun = false -``` - -{% /details %} - -## `bun add` - -To add a particular package: - -```bash -$ bun add preact -``` +## Lifecycle scripts -To specify a version, version range, or tag: +Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts like `postinstall` for installed dependencies. Executing arbitrary scripts represents a potential security risk. -```bash -$ bun add zod@3.20.0 -$ bun add zod@^3.0.0 -$ bun add zod@latest -``` - -To add a package as a dev dependency (`"devDependencies"`): - -```bash -$ bun add --dev @types/react -$ bun add -d @types/react -``` - -To add a package as an optional dependency (`"optionalDependencies"`): +To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json. -```bash -$ bun add --optional lodash +```json-diff + { + "name": "my-app", + "version": "1.0.0", ++ "trustedDependencies": ["my-trusted-package"] + } ``` -To add a package and pin to the resolved version, use `--exact`. This will resolve the version of the package and add it to your `package.json` with an exact version number instead of a version range. +Then re-install the package. Bun will read this field and run lifecycle scripts for `my-trusted-package`. -```bash -$ bun add react --exact -``` +## Workspaces -This will add the following to your `package.json`: +Bun supports `"workspaces"` in package.json. For complete documentation refer to [Package manager > Workspaces](/docs/install/workspaces). -```jsonc +```json#package.json { + "name": "my-app", + "version": "1.0.0", + "workspaces": ["packages/*"], "dependencies": { - // without --exact - "react": "^18.2.0", // this matches >= 18.2.0 < 19.0.0 - - // with --exact - "react": "18.2.0" // this matches only 18.2.0 exactly + "preact": "^10.5.13" } } ``` -To view a complete list of options for this command: +## Overrides and resolutions -```bash -$ bun add --help -``` +Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies. Refer to [Package manager > Overrides and resolutions](/docs/install/overrides-and-resolutions) for complete documentation. -## `bun add --global` +```json-diff#package.json + { + "name": "my-app", + "dependencies": { + "foo": "^2.0.0" + }, ++ "overrides": { ++ "bar": "~4.4.0" ++ } + } +``` -{% callout %} -**Note** — This would not modify package.json of your current project folder. -**Alias** - `bun add --global`, `bun add -g`, `bun install --global` and `bun install -g` -{% /callout %} +## Global packages -To install a package globally, use the `-g`/`--global` flag. This will not modify the `package.json` of your current project. Typically this is used for installing command-line tools. +To install a package globally, use the `-g`/`--global` flag. Typically this is used for installing command-line tools. ```bash -$ bun add --global cowsay # or `bun add -g cowsay` +$ bun install --global cowsay # or `bun install -g cowsay` $ cowsay "Bun!" ______ < Bun! > @@ -170,154 +108,75 @@ $ cowsay "Bun!" || || ``` -{% details summary="Configuring global installation behavior" %} - -```toml -[install] -# where `bun install --global` installs packages -globalDir = "~/.bun/install/global" - -# where globally-installed package bins are linked -globalBinDir = "~/.bun/bin" -``` +## Production mode -{% /details %} - -## `bun remove` - -To remove a dependency: - -```bash -$ bun remove preact -``` - -## `bun update` - -To update all dependencies to the latest version _that's compatible with the version range specified in your `package.json`_: - -```sh -$ bun update -``` - -This will not edit your `package.json`. There's currently no command to force-update all dependencies to the latest version regardless version ranges. - -## `bun link` - -Use `bun link` in a local directory to register the current package as a "linkable" package. +To install in production mode (i.e. without `devDependencies` or `optionalDependencies`): ```bash -$ cd /path/to/cool-pkg -$ cat package.json -{ - "name": "cool-pkg", - "version": "1.0.0" -} -$ bun link -bun link v1.x (7416672e) -Success! Registered "cool-pkg" - -To use cool-pkg in a project, run: - bun link cool-pkg - -Or add it in dependencies in your package.json file: - "cool-pkg": "link:cool-pkg" +$ bun install --production ``` -This package can now be "linked" into other projects using `bun link cool-pkg`. This will create a symlink in the `node_modules` directory of the target project, pointing to the local directory. +For reproducible installs, use `--frozen-lockfile`. This will install the exact versions of each package specified in the lockfile. If your `package.json` disagrees with `bun.lockb`, Bun will exit with an error. The lockfile will not be updated. ```bash -$ cd /path/to/my-app -$ bun link cool-pkg -``` - -In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencies` field of your app's package.json with a special version specifier that tells Bun to load from the registered local directory instead of installing from `npm`: - -```json-diff - { - "name": "my-app", - "version": "1.0.0", - "dependencies": { -+ "cool-pkg": "link:cool-pkg" - } - } -``` - -## Trusted dependencies - -Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for installed dependencies, such as `postinstall`. These scripts represent a potential security risk, as they can execute arbitrary code on your machine. - -<!-- Bun maintains an allow-list of popular packages containing `postinstall` scripts that are known to be safe. To run lifecycle scripts for packages that aren't on this list, add the package to `trustedDependencies` in your package.json. --> - -To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json. - -<!-- ```json-diff - { - "name": "my-app", - "version": "1.0.0", -+ "trustedDependencies": { -+ "my-trusted-package": "*" -+ } - } -``` --> - -```json-diff - { - "name": "my-app", - "version": "1.0.0", -+ "trustedDependencies": ["my-trusted-package"] - } +$ bun install --frozen-lockfile ``` -Bun reads this field and will run lifecycle scripts for `my-trusted-package`. +For more information on Bun's binary lockfile `bun.lockb`, refer to [Package manager > Lockfile](/docs/install/lockfile). -<!-- If you specify a version range, Bun will only execute lifecycle scripts if the resolved package version matches the range. --> -<!-- -```json -{ - "name": "my-app", - "version": "1.0.0", - "trustedDependencies": { - "my-trusted-package": "^1.0.0" - } -} -``` --> +## Dry run -## Git dependencies - -To add a dependency from a git repository: +To perform a dry run (i.e. don't actually install anything): ```bash -$ bun install git@github.com:moment/moment.git +$ bun install --dry-run ``` -Bun supports a variety of protocols, including [`github`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#github-urls), [`git`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#git-urls-as-dependencies), `git+ssh`, `git+https`, and many more. +## Non-npm dependencies -```json +Bun supports installing dependencies from Git, GitHub, and local or remotely-hosted tarballs. For complete documentation refer to [Package manager > Git, GitHub, and tarball dependencies](/docs/cli/add). + +```json#package.json { "dependencies": { "dayjs": "git+https://github.com/iamkun/dayjs.git", "lodash": "git+ssh://github.com/lodash/lodash.git#4.17.21", "moment": "git@github.com:moment/moment.git", - "zod": "github:colinhacks/zod" + "zod": "github:colinhacks/zod", + "react": "https://registry.npmjs.org/react/-/react-18.2.0.tgz" } } ``` -## Tarball dependencies +## Configuration -A package name can correspond to a publicly hosted `.tgz` file. During `bun install`, Bun will download and install the package from the specified tarball URL, rather than from the package registry. +The default behavior of `bun install` can be configured in `bunfig.toml`. The default values are shown below. -```json#package.json -{ - "dependencies": { - "zod": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz" - } -} +```toml +[install] + +# whether to install optionalDependencies +optional = true + +# whether to install devDependencies +dev = true + +# whether to install peerDependencies +peer = false + +# equivalent to `--production` flag +production = false + +# equivalent to `--frozen-lockfile` flag +frozenLockfile = false + +# equivalent to `--dry-run` flag +dryRun = false ``` ## CI/CD -Looking to speed up your CI? Use the official `oven-sh/setup-bun` action to install `bun` in a GitHub Actions pipeline. +Looking to speed up your CI? Use the official [`oven-sh/setup-bun`](https://github.com/oven-sh/setup-bun) action to install `bun` in a GitHub Actions pipeline. ```yaml#.github/workflows/release.yml name: bun-types diff --git a/docs/cli/link.md b/docs/cli/link.md new file mode 100644 index 000000000..9adc73765 --- /dev/null +++ b/docs/cli/link.md @@ -0,0 +1,46 @@ +Use `bun link` in a local directory to register the current package as a "linkable" package. + +```bash +$ cd /path/to/cool-pkg +$ cat package.json +{ + "name": "cool-pkg", + "version": "1.0.0" +} +$ bun link +bun link v1.x (7416672e) +Success! Registered "cool-pkg" + +To use cool-pkg in a project, run: + bun link cool-pkg + +Or add it in dependencies in your package.json file: + "cool-pkg": "link:cool-pkg" +``` + +This package can now be "linked" into other projects using `bun link cool-pkg`. This will create a symlink in the `node_modules` directory of the target project, pointing to the local directory. + +```bash +$ cd /path/to/my-app +$ bun link cool-pkg +``` + +In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencies` field of your app's package.json with a special version specifier that tells Bun to load from the registered local directory instead of installing from `npm`: + +```json-diff + { + "name": "my-app", + "version": "1.0.0", + "dependencies": { ++ "cool-pkg": "link:cool-pkg" + } + } +``` + +To _unregister_ a local package, navigate to the package's root directory and run `bun unlink`. + +```bash +$ cd /path/to/cool-pkg +$ bun unlink +bun unlink v1.x (7416672e) +``` diff --git a/docs/install/utilities.md b/docs/cli/pm.md index 689f177d8..689f177d8 100644 --- a/docs/install/utilities.md +++ b/docs/cli/pm.md diff --git a/docs/cli/remove.md b/docs/cli/remove.md new file mode 100644 index 000000000..8054711d3 --- /dev/null +++ b/docs/cli/remove.md @@ -0,0 +1,5 @@ +To remove a dependency: + +```bash +$ bun remove ts-node +``` diff --git a/docs/cli/update.md b/docs/cli/update.md new file mode 100644 index 000000000..8ebfd6119 --- /dev/null +++ b/docs/cli/update.md @@ -0,0 +1,9 @@ +## `bun update` + +To update all dependencies to the latest version _that's compatible with the version range specified in your `package.json`_: + +```sh +$ bun update +``` + +This will not edit your `package.json`. There's currently no command to force-update all dependencies to the latest version regardless version ranges. diff --git a/docs/install/lifecycle.md b/docs/install/lifecycle.md new file mode 100644 index 000000000..035ead24d --- /dev/null +++ b/docs/install/lifecycle.md @@ -0,0 +1,44 @@ +Packages on `npm` can define _lifecycle scripts_ in their `package.json`. Some of the most common are below, but there are [many others](https://docs.npmjs.com/cli/v10/using-npm/scripts). + +- `preinstall`: Runs before the package is installed +- `postinstall`: Runs after the package is installed +- `preuninstall`: Runs before the package is uninstalled +- `prepublishOnly`: Runs before the package is published + +These scripts are arbitrary shell commands that the package manager is expected to read and execute at the appropriate time. But executing arbitrary scripts represents a potential security risk, so—unlike other `npm` clients—Bun does not execute arbitrary lifecycle scripts by default. + +## `postinstall` + +The `postinstall` script is particularly important. It's widely used to build or install platform-specific binaries for packages that are implemented as [native Node.js add-ons](https://nodejs.org/api/addons.html). For example, `node-sass` is a popular package that uses `postinstall` to build a native binary for Sass. + +```json +{ + "name": "my-app", + "version": "1.0.0", + "dependencies": { + "node-sass": "^6.0.1" + } +} +``` + +## `trustedDependencies` + +Instead of executing arbitrary scripts, Bun uses a "default-secure" approach. You can add certain packages to an allow list, and Bun will execute lifecycle scripts for those packages. To tell Bun to allow lifecycle scripts for a particular package, add the package name to `trustedDependencies` array in your `package.json`. + +```json-diff + { + "name": "my-app", + "version": "1.0.0", ++ "trustedDependencies": ["node-sass"] + } +``` + +Once added to `trustedDependencies`, install/re-install the package. Bun will read this field and run lifecycle scripts for `my-trusted-package`. + +## `--ignore-scripts` + +To disable lifecycle scripts for all packages, use the `--no-scripts` flag. + +```bash +$ bun install --no-scripts +``` diff --git a/docs/install/overrides.md b/docs/install/overrides.md new file mode 100644 index 000000000..60d9e2172 --- /dev/null +++ b/docs/install/overrides.md @@ -0,0 +1,73 @@ +Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies. Refer to [Package manager > Overrides and resolutions](/docs/install/overrides-and-resolutions) for complete documentation. + +```json-diff#package.json + { + "name": "my-app", + "dependencies": { + "foo": "^2.0.0" + }, ++ "overrides": { ++ "bar": "~4.4.0" ++ } + } +``` + +By default, Bun will install the latest version of all dependencies and metadependencies, according to the ranges specified in each package's `package.json`. Let's say you have a project with one dependency, `foo`, which in turn has a dependency on `bar`. This means `bar` is a _metadependency_ of our project. + +```json#package.json +{ + "name": "my-app", + "dependencies": { + "foo": "^2.0.0" + } +} +``` + +When you run `bun install`, Bun will install the latest versions of each package. + +``` +# tree layout of node_modules +node_modules +├── foo@1.2.3 +└── bar@4.5.6 +``` + +But what if a security vulnerability was introduced in `bar@4.5.6`? We may want a way to pin `bar` to an older version that doesn't have the vulerability. This is where `"overrides"`/`"resolutions"` come in. + +### `"overrides"` + +Add `bar` to the `"overrides"` field in `package.json`. Bun will defer to the specified version range when determining which version of `bar` to install, whether it's a dependency or a metadependency. + +{% callout %} +**Note** — Bun currently only supports top-level `"overrides"`. [Nested overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) are not supported. +{% /callout %} + +```json-diff#package.json + { + "name": "my-app", + "dependencies": { + "foo": "^2.0.0" + }, ++ "overrides": { ++ "bar": "~4.4.0" ++ } + } +``` + +### `"resolutions"` + +The syntax is similar for `"resolutions"`, which is Yarn's alternative to `"overrides"`. Bun supports this feature to make migration from Yarn easier. + +As with `"overrides"`, _nested resolutions_ are not currently supported. + +```json-diff#package.json + { + "name": "my-app", + "dependencies": { + "foo": "^2.0.0" + }, ++ "resolutions": { ++ "bar": "~4.4.0" ++ } + } +``` diff --git a/docs/nav.ts b/docs/nav.ts index 648aebfc0..ade4f0281 100644 --- a/docs/nav.ts +++ b/docs/nav.ts @@ -39,7 +39,7 @@ export default { description: "Install and configure type declarations for Bun's APIs", }), - divider("Scaffolding"), + divider("Templating"), page("cli/init", "`bun init`", { description: "Scaffold an empty Bun project.", }), @@ -152,6 +152,21 @@ export default { description: "Install all dependencies with `bun install`, or manage dependencies with `bun add` and `bun remove`.", }), + page("cli/add", "`bun add`", { + description: "Add dependencies to your project.", + }), + page("cli/remove", "`bun remove`", { + description: "Remove dependencies from your project.", + }), + page("cli/update", "`bun update`", { + description: "Update your project's dependencies.", + }), + page("cli/link", "`bun link`", { + description: "Install local packages as dependencies in your project.", + }), + page("cli/pm", "`bun pm`", { + description: "Install local packages as dependencies in your project.", + }), page("install/cache", "Global cache", { description: "Bun's package manager installs all packages into a shared global cache to avoid redundant re-downloads.", @@ -159,6 +174,10 @@ export default { page("install/workspaces", "Workspaces", { description: "Bun's package manager supports workspaces and mono-repo development workflows.", }), + page("install/lifecycle", "Lifecycle scripts", { + description: + "Bun's package manager installs all packages into a shared global cache to avoid redundant re-downloads.", + }), page("install/lockfile", "Lockfile", { description: "Bun's binary lockfile `bun.lockb` tracks your resolved dependency tree, making future installs fast and repeatable.", @@ -166,9 +185,12 @@ export default { page("install/registries", "Scopes and registries", { description: "How to configure private scopes and custom package registries.", }), - page("install/utilities", "Utilities", { - description: "Use `bun pm` to introspect your global module cache or project dependency tree.", + page("install/overrides", "Overrides and resolutions", { + description: "Specify version ranges for nested dependencies", }), + // page("install/utilities", "Utilities", { + // description: "Use `bun pm` to introspect your global module cache or project dependency tree.", + // }), divider("Bundler"), page("bundler", "`Bun.build`", { |