diff --git a/.changeset/wicked-students-obey.md b/.changeset/wicked-students-obey.md new file mode 100644 index 000000000..28fc5597d --- /dev/null +++ b/.changeset/wicked-students-obey.md @@ -0,0 +1,5 @@ +--- +'@vercel/remix-builder': patch +--- + +Improve hueristics for detecting Remix + Vite diff --git a/packages/remix/src/build.ts b/packages/remix/src/build.ts index f415c3ac0..592385ca9 100644 --- a/packages/remix/src/build.ts +++ b/packages/remix/src/build.ts @@ -1,9 +1,8 @@ import { build as buildVite } from './build-vite'; import { build as buildLegacy } from './build-legacy'; -import { findConfig } from './utils'; +import { isVite } from './utils'; import type { BuildV2 } from '@vercel/build-utils'; export const build: BuildV2 = opts => { - const isLegacy = findConfig(opts.workPath, 'remix.config'); - return isLegacy ? buildLegacy(opts) : buildVite(opts); + return isVite(opts.workPath) ? buildVite(opts) : buildLegacy(opts); }; diff --git a/packages/remix/src/utils.ts b/packages/remix/src/utils.ts index 2ae0ee3ce..ee6491e23 100644 --- a/packages/remix/src/utils.ts +++ b/packages/remix/src/utils.ts @@ -1,5 +1,5 @@ import semver from 'semver'; -import { existsSync, promises as fs } from 'fs'; +import { existsSync, readFileSync, promises as fs } from 'fs'; import { basename, dirname, join, relative, resolve, sep } from 'path'; import { pathToRegexp, Key } from 'path-to-regexp'; import { debug, type PackageJson } from '@vercel/build-utils'; @@ -420,3 +420,30 @@ export function logNftWarnings(warnings: Set, required?: string) { } } } + +export function isVite(dir: string): boolean { + const viteConfig = findConfig(dir, 'vite.config', ['.js', '.ts']); + if (!viteConfig) return false; + + const remixConfig = findConfig(dir, 'remix.config'); + if (!remixConfig) return true; + + // `remix.config` and `vite.config` exist, so check a couple other ways + + // Is `vite:build` found in the `package.json` "build" script? + const pkg: PackageJson = JSON.parse( + readFileSync(join(dir, 'package.json'), 'utf8') + ); + if (pkg.scripts?.build && /\bvite:build\b/.test(pkg.scripts.build)) { + return true; + } + + // Is `@remix-run/dev` package found in `vite.config`? + const viteConfigContents = readFileSync(viteConfig, 'utf8'); + if (/['"]@remix-run\/dev['"]/.test(viteConfigContents)) { + return true; + } + + // If none of those conditions matched, then treat it as a legacy project and print a warning + return false; +} diff --git a/packages/remix/test/fixtures-unit/by-build-command/package.json b/packages/remix/test/fixtures-unit/by-build-command/package.json new file mode 100644 index 000000000..c2aa423e5 --- /dev/null +++ b/packages/remix/test/fixtures-unit/by-build-command/package.json @@ -0,0 +1,5 @@ +{ + "scripts": { + "build": "remix vite:build" + } +} diff --git a/packages/remix/test/fixtures-unit/by-build-command/remix.config.js b/packages/remix/test/fixtures-unit/by-build-command/remix.config.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/remix/test/fixtures-unit/by-build-command/vite.config.ts b/packages/remix/test/fixtures-unit/by-build-command/vite.config.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/remix/test/fixtures-unit/by-vite-config-legacy/package.json b/packages/remix/test/fixtures-unit/by-vite-config-legacy/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/packages/remix/test/fixtures-unit/by-vite-config-legacy/package.json @@ -0,0 +1 @@ +{} diff --git a/packages/remix/test/fixtures-unit/by-vite-config-legacy/remix.config.js b/packages/remix/test/fixtures-unit/by-vite-config-legacy/remix.config.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/remix/test/fixtures-unit/by-vite-config-legacy/vite.config.ts b/packages/remix/test/fixtures-unit/by-vite-config-legacy/vite.config.ts new file mode 100644 index 000000000..849635752 --- /dev/null +++ b/packages/remix/test/fixtures-unit/by-vite-config-legacy/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig({ + plugins: [tsconfigPaths()], +}); diff --git a/packages/remix/test/fixtures-unit/by-vite-config/package.json b/packages/remix/test/fixtures-unit/by-vite-config/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/packages/remix/test/fixtures-unit/by-vite-config/package.json @@ -0,0 +1 @@ +{} diff --git a/packages/remix/test/fixtures-unit/by-vite-config/remix.config.js b/packages/remix/test/fixtures-unit/by-vite-config/remix.config.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/remix/test/fixtures-unit/by-vite-config/vite.config.ts b/packages/remix/test/fixtures-unit/by-vite-config/vite.config.ts new file mode 100644 index 000000000..a1fcb5a7b --- /dev/null +++ b/packages/remix/test/fixtures-unit/by-vite-config/vite.config.ts @@ -0,0 +1,7 @@ +import { vitePlugin as remix } from "@remix-run/dev"; +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig({ + plugins: [remix(), tsconfigPaths()], +}); diff --git a/packages/remix/test/fixtures-vite/01-no-preset/vercel.json b/packages/remix/test/fixtures-vite/01-no-preset/vercel.json deleted file mode 100644 index 724d0678a..000000000 --- a/packages/remix/test/fixtures-vite/01-no-preset/vercel.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "framework": "remix" -} diff --git a/packages/remix/test/fixtures-vite/02-interactive-remix-routing-v2/vercel.json b/packages/remix/test/fixtures-vite/02-interactive-remix-routing-v2/vercel.json deleted file mode 100644 index 724d0678a..000000000 --- a/packages/remix/test/fixtures-vite/02-interactive-remix-routing-v2/vercel.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "framework": "remix" -} diff --git a/packages/remix/test/unit.is-vite.test.ts b/packages/remix/test/unit.is-vite.test.ts new file mode 100644 index 000000000..477c61b17 --- /dev/null +++ b/packages/remix/test/unit.is-vite.test.ts @@ -0,0 +1,30 @@ +import { join } from 'path'; +import { readdirSync } from 'fs'; +import { isVite } from '../src/utils'; + +describe('isVite()', () => { + it.each([ + ...readdirSync(join(__dirname, 'fixtures-legacy')).map(name => ({ + name: join('fixtures-legacy', name), + expected: false, + })), + ...readdirSync(join(__dirname, 'fixtures-vite')).map(name => ({ + name: join('fixtures-vite', name), + expected: true, + })), + { + name: 'fixtures-unit/by-build-command', + expected: true, + }, + { + name: 'fixtures-unit/by-vite-config', + expected: true, + }, + { + name: 'fixtures-unit/by-vite-config-legacy', + expected: false, + }, + ])('should return `$expected` for "$name" route', ({ name, expected }) => { + expect(isVite(join(__dirname, name))).toEqual(expected); + }); +});