From 96b05af3ed2543e901b8e2b1601eefa90695acdd Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Tue, 15 Aug 2023 21:05:09 -0700 Subject: [PATCH] feat: support bun package manager (#7074) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michaƫl De Boey Co-authored-by: Mark Dalgleish --- .changeset/popular-trains-do.md | 6 ++++ docs/other-api/create-remix.md | 4 ++- .../__tests__/create-remix-test.ts | 33 +++++++++++++++++++ packages/create-remix/index.ts | 5 +-- .../remix-dev/cli/detectPackageManager.ts | 3 +- .../remix-dev/devServer_unstable/index.ts | 4 +++ 6 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 .changeset/popular-trains-do.md diff --git a/.changeset/popular-trains-do.md b/.changeset/popular-trains-do.md new file mode 100644 index 00000000000..e8f8bc9e18f --- /dev/null +++ b/.changeset/popular-trains-do.md @@ -0,0 +1,6 @@ +--- +"create-remix": minor +"@remix-run/dev": minor +--- + +Support bun package manager diff --git a/docs/other-api/create-remix.md b/docs/other-api/create-remix.md index 55cdabfb355..cd47ee3afbf 100644 --- a/docs/other-api/create-remix.md +++ b/docs/other-api/create-remix.md @@ -24,7 +24,7 @@ npx create-remix@latest --help ### Package managers -`create-remix` can also be invoked using the `create` command of various package managers, allowing you to choose between npm, Yarn and pnpm for managing the install process. +`create-remix` can also be invoked using various package managers, allowing you to choose between npm, Yarn, pnpm, and Bun for managing the install process. ```sh npm create remix@latest @@ -32,6 +32,8 @@ npm create remix@latest yarn create remix # or pnpm create remix +# or +bunx create-remix ``` ### `create-remix --template` diff --git a/packages/create-remix/__tests__/create-remix-test.ts b/packages/create-remix/__tests__/create-remix-test.ts index 0ef9f99b798..9a4f8e81abb 100644 --- a/packages/create-remix/__tests__/create-remix-test.ts +++ b/packages/create-remix/__tests__/create-remix-test.ts @@ -814,6 +814,39 @@ describe("create-remix CLI", () => { process.env.npm_config_user_agent = originalUserAgent; }); + it("recognizes when Bun was used to run the command", async () => { + let originalUserAgent = process.env.npm_config_user_agent; + process.env.npm_config_user_agent = + "bun/0.7.0 npm/? node/v14.17.0 linux x64"; + + let projectDir = getProjectDir("bun-create-from-user-agent"); + + let execa = require("execa"); + execa.mockImplementation(async () => {}); + + // Suppress terminal output + let stdoutMock = jest + .spyOn(process.stdout, "write") + .mockImplementation(() => true); + + await createRemix([ + projectDir, + "--template", + path.join(__dirname, "fixtures", "blank"), + "--no-git-init", + "--yes", + ]); + + stdoutMock.mockReset(); + + expect(execa).toHaveBeenCalledWith( + "bun", + expect.arrayContaining(["install"]), + expect.anything() + ); + process.env.npm_config_user_agent = originalUserAgent; + }); + it("supports specifying the package manager, regardless of user agent", async () => { let originalUserAgent = process.env.npm_config_user_agent; process.env.npm_config_user_agent = diff --git a/packages/create-remix/index.ts b/packages/create-remix/index.ts index bbbbd1cb5a7..bed4eb496b4 100644 --- a/packages/create-remix/index.ts +++ b/packages/create-remix/index.ts @@ -149,7 +149,7 @@ async function getContext(argv: string[]): Promise { noMotion, pkgManager: validatePackageManager( pkgManager ?? - // npm, pnpm and Yarn set the user agent environment variable that can be used + // npm, pnpm, Yarn, and Bun set the user agent environment variable that can be used // to determine which package manager ran the command. (process.env.npm_config_user_agent ?? "npm").split("/")[0] ), @@ -606,12 +606,13 @@ function isEmpty(dirPath: string) { return conflicts.length === 0; } -type PackageManager = "npm" | "yarn" | "pnpm"; +type PackageManager = "npm" | "yarn" | "pnpm" | "bun"; const packageManagerExecScript: Record = { npm: "npx", yarn: "yarn", pnpm: "pnpm exec", + bun: "bunx", }; function validatePackageManager(pkgManager: string): PackageManager { diff --git a/packages/remix-dev/cli/detectPackageManager.ts b/packages/remix-dev/cli/detectPackageManager.ts index f77f5c7bb5d..79b7c8277e8 100644 --- a/packages/remix-dev/cli/detectPackageManager.ts +++ b/packages/remix-dev/cli/detectPackageManager.ts @@ -1,4 +1,4 @@ -type PackageManager = "npm" | "pnpm" | "yarn"; +type PackageManager = "npm" | "pnpm" | "yarn" | "bun"; /** * Determine which package manager the user prefers. @@ -15,6 +15,7 @@ export const detectPackageManager = (): PackageManager | undefined => { if (pkgManager === "npm") return "npm"; if (pkgManager === "pnpm") return "pnpm"; if (pkgManager === "yarn") return "yarn"; + if (pkgManager === "bun") return "bun"; return undefined; } catch { return undefined; diff --git a/packages/remix-dev/devServer_unstable/index.ts b/packages/remix-dev/devServer_unstable/index.ts index 249a25e376d..e54047b43ef 100644 --- a/packages/remix-dev/devServer_unstable/index.ts +++ b/packages/remix-dev/devServer_unstable/index.ts @@ -31,6 +31,10 @@ let detectBin = async (): Promise => { let { stdout } = await execa(pkgManager, ["prefix"]); return path.join(stdout.trim(), "node_modules", ".bin"); } + if (pkgManager === "bun") { + let { stdout } = await execa(pkgManager, ["pm", "bin"]); + return stdout.trim(); + } let { stdout } = await execa(pkgManager, ["bin"]); return stdout.trim(); };