mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-09 04:22:07 +00:00
[remix] Install @vercel/remix-run-dev at build-time instead of using symlink (#9784)
Instead of including the fork `@remix-run/dev` package as a regular dependency of `@vercel/remix-builder`, install it at build-time by modifying the project's `package.json` file. The reasons for this are: * Avoids deprecation warnings from a few packages that currently exist on the `@remix-run/dev` package when installing Vercel CLI (those warnings already show up in the build logs anyways, so nothing new there). * Allows us to install a version as close as possible to the version specified in the user's `package.json` (similar to how we do when auto-injecting the `@vercel/remix` package). This will be especially important once Remix v2 is released, which will have breaking changes compared to v1. **Note:** `@vercel/remix-run-dev` is still a _dev_ dependency, so that we can use TypeScript types from it, as well as, at runtime, we use the version in the Builder's `package.json` to determine the maximum versions of `@vercel/remix-run-dev` and/or `@vercel/remix` which can safely be installed. Fixes #10027. Fixes #10222.
This commit is contained in:
5
.changeset/chatty-eyes-admire.md
Normal file
5
.changeset/chatty-eyes-admire.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@vercel/remix-builder': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Install `@vercel/remix-run-dev` at build-time instead of using symlink
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
"defaults"
|
"defaults"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.19.1",
|
|
||||||
"@vercel/build-utils": "6.8.2",
|
"@vercel/build-utils": "6.8.2",
|
||||||
"@vercel/nft": "0.22.5",
|
"@vercel/nft": "0.22.5",
|
||||||
"@vercel/static-config": "2.0.17",
|
"@vercel/static-config": "2.0.17",
|
||||||
@@ -29,6 +28,7 @@
|
|||||||
"ts-morph": "12.0.0"
|
"ts-morph": "12.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.19.1",
|
||||||
"@types/jest": "27.5.1",
|
"@types/jest": "27.5.1",
|
||||||
"@types/node": "14.18.33",
|
"@types/node": "14.18.33",
|
||||||
"@types/semver": "7.3.13"
|
"@types/semver": "7.3.13"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Project } from 'ts-morph';
|
import { Project } from 'ts-morph';
|
||||||
import { promises as fs } from 'fs';
|
import { readFileSync, promises as fs } from 'fs';
|
||||||
import { basename, dirname, extname, join, relative, sep } from 'path';
|
import { basename, dirname, extname, join, relative, sep } from 'path';
|
||||||
import {
|
import {
|
||||||
debug,
|
debug,
|
||||||
@@ -26,7 +26,6 @@ import type {
|
|||||||
PackageJson,
|
PackageJson,
|
||||||
BuildResultV2Typical,
|
BuildResultV2Typical,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
import type { AppConfig } from '@remix-run/dev/dist/config';
|
|
||||||
import type { ConfigRoute } from '@remix-run/dev/dist/config/routes';
|
import type { ConfigRoute } from '@remix-run/dev/dist/config/routes';
|
||||||
import type { BaseFunctionConfig } from '@vercel/static-config';
|
import type { BaseFunctionConfig } from '@vercel/static-config';
|
||||||
import {
|
import {
|
||||||
@@ -41,16 +40,22 @@ import {
|
|||||||
ResolvedEdgeRouteConfig,
|
ResolvedEdgeRouteConfig,
|
||||||
findEntry,
|
findEntry,
|
||||||
chdirAndReadConfig,
|
chdirAndReadConfig,
|
||||||
addDependency,
|
addDependencies,
|
||||||
|
resolveSemverMinMax,
|
||||||
ensureResolvable,
|
ensureResolvable,
|
||||||
|
isESM,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import semver from 'semver';
|
|
||||||
|
|
||||||
const _require: typeof require = eval('require');
|
interface ServerBundle {
|
||||||
|
serverBuildPath: string;
|
||||||
|
routes: string[];
|
||||||
|
}
|
||||||
|
|
||||||
const REMIX_RUN_DEV_PATH = dirname(
|
const remixBuilderPkg = JSON.parse(
|
||||||
_require.resolve('@remix-run/dev/package.json')
|
readFileSync(join(__dirname, '../package.json'), 'utf8')
|
||||||
);
|
);
|
||||||
|
const remixRunDevForkVersion =
|
||||||
|
remixBuilderPkg.devDependencies['@remix-run/dev'];
|
||||||
|
|
||||||
const DEFAULTS_PATH = join(__dirname, '../defaults');
|
const DEFAULTS_PATH = join(__dirname, '../defaults');
|
||||||
|
|
||||||
@@ -63,8 +68,17 @@ const nodeServerSrcPromise = fs.readFile(
|
|||||||
'utf-8'
|
'utf-8'
|
||||||
);
|
);
|
||||||
|
|
||||||
// This value is the minimum supported version for our fork of Remix
|
// Minimum supported version of the `@vercel/remix` package
|
||||||
const minimumSupportRemixVersion = '1.10.0';
|
const VERCEL_REMIX_MIN_VERSION = '1.10.0';
|
||||||
|
|
||||||
|
// Minimum supported version of the `@vercel/remix-run-dev` forked compiler
|
||||||
|
const REMIX_RUN_DEV_MIN_VERSION = '1.15.0';
|
||||||
|
|
||||||
|
// Maximum version of `@vercel/remix-run-dev` fork
|
||||||
|
// (and also `@vercel/remix` since they get published at the same time)
|
||||||
|
const REMIX_RUN_DEV_MAX_VERSION = remixRunDevForkVersion.slice(
|
||||||
|
remixRunDevForkVersion.lastIndexOf('@') + 1
|
||||||
|
);
|
||||||
|
|
||||||
export const build: BuildV2 = async ({
|
export const build: BuildV2 = async ({
|
||||||
entrypoint,
|
entrypoint,
|
||||||
@@ -133,18 +147,32 @@ export const build: BuildV2 = async ({
|
|||||||
repoRootPath,
|
repoRootPath,
|
||||||
'@remix-run/dev'
|
'@remix-run/dev'
|
||||||
);
|
);
|
||||||
|
const remixRunDevPkg = JSON.parse(
|
||||||
const remixVersion = JSON.parse(
|
readFileSync(join(remixRunDevPath, 'package.json'), 'utf8')
|
||||||
await fs.readFile(join(remixRunDevPath, 'package.json'), 'utf8')
|
);
|
||||||
).version;
|
const remixVersion = remixRunDevPkg.version;
|
||||||
|
|
||||||
const remixConfig = await chdirAndReadConfig(
|
const remixConfig = await chdirAndReadConfig(
|
||||||
|
remixRunDevPath,
|
||||||
entrypointFsDirname,
|
entrypointFsDirname,
|
||||||
packageJsonPath
|
packageJsonPath
|
||||||
);
|
);
|
||||||
const { serverEntryPoint, appDirectory } = remixConfig;
|
const { serverEntryPoint, appDirectory } = remixConfig;
|
||||||
const remixRoutes = Object.values(remixConfig.routes);
|
const remixRoutes = Object.values(remixConfig.routes);
|
||||||
|
|
||||||
|
const depsToAdd: string[] = [];
|
||||||
|
|
||||||
|
if (remixRunDevPkg.name !== '@vercel/remix-run-dev') {
|
||||||
|
const remixDevForkVersion = resolveSemverMinMax(
|
||||||
|
REMIX_RUN_DEV_MIN_VERSION,
|
||||||
|
REMIX_RUN_DEV_MAX_VERSION,
|
||||||
|
remixVersion
|
||||||
|
);
|
||||||
|
depsToAdd.push(
|
||||||
|
`@remix-run/dev@npm:@vercel/remix-run-dev@${remixDevForkVersion}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// `app/entry.server.tsx` and `app/entry.client.tsx` are optional in Remix,
|
// `app/entry.server.tsx` and `app/entry.client.tsx` are optional in Remix,
|
||||||
// so if either of those files are missing then add our own versions.
|
// so if either of those files are missing then add our own versions.
|
||||||
const userEntryServerFile = findEntry(appDirectory, 'entry.server');
|
const userEntryServerFile = findEntry(appDirectory, 'entry.server');
|
||||||
@@ -155,44 +183,27 @@ export const build: BuildV2 = async ({
|
|||||||
);
|
);
|
||||||
if (!pkg.dependencies['@vercel/remix']) {
|
if (!pkg.dependencies['@vercel/remix']) {
|
||||||
// Dependency version resolution logic
|
// Dependency version resolution logic
|
||||||
// 1. Users app is on 1.9.0 -> we install the 1.10.0 (minimum) version of our fork (`@vercel/remix`)
|
// 1. Users app is on 1.9.0 -> we install the 1.10.0 (minimum) version of `@vercel/remix`.
|
||||||
// 2. Users app is on 1.11.0 (a version greater than 1.10.0 and less than the latest version of the fork) -> we install the (matching) 1.11.0 version of `@vercel/remix`
|
// 2. Users app is on 1.11.0 (a version greater than 1.10.0 and less than the known max
|
||||||
// 3. Users app is on something greater than our latest version of the fork -> we install the latest version of our fork
|
// published version) -> we install the (matching) 1.11.0 version of `@vercel/remix`.
|
||||||
|
// 3. Users app is on something greater than our latest version of the fork -> we install
|
||||||
// remixVersion is the version of the `@remix-run/dev` package in the *users' app*
|
// the latest known published version of `@vercel/remix`.
|
||||||
const usersRemixVersion = semver.gt(
|
const vercelRemixVersion = resolveSemverMinMax(
|
||||||
remixVersion,
|
VERCEL_REMIX_MIN_VERSION,
|
||||||
minimumSupportRemixVersion
|
REMIX_RUN_DEV_MAX_VERSION,
|
||||||
)
|
remixVersion
|
||||||
? remixVersion
|
|
||||||
: minimumSupportRemixVersion;
|
|
||||||
|
|
||||||
// Prevent frozen lockfile rejections
|
|
||||||
const envForAddDep = { ...spawnOpts.env };
|
|
||||||
delete envForAddDep.CI;
|
|
||||||
delete envForAddDep.VERCEL;
|
|
||||||
delete envForAddDep.NOW_BUILDER;
|
|
||||||
await addDependency(
|
|
||||||
cliType,
|
|
||||||
[
|
|
||||||
`@vercel/remix@${
|
|
||||||
semver.gt(
|
|
||||||
usersRemixVersion,
|
|
||||||
require('@remix-run/dev/package.json').version
|
|
||||||
)
|
|
||||||
? 'latest'
|
|
||||||
: usersRemixVersion
|
|
||||||
}`,
|
|
||||||
],
|
|
||||||
{
|
|
||||||
...spawnOpts,
|
|
||||||
env: envForAddDep,
|
|
||||||
cwd: entrypointFsDirname,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
depsToAdd.push(`@vercel/remix@${vercelRemixVersion}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (depsToAdd.length) {
|
||||||
|
await addDependencies(cliType, depsToAdd, {
|
||||||
|
...spawnOpts,
|
||||||
|
cwd: entrypointFsDirname,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const userEntryClientFile = findEntry(
|
const userEntryClientFile = findEntry(
|
||||||
remixConfig.appDirectory,
|
remixConfig.appDirectory,
|
||||||
'entry.client'
|
'entry.client'
|
||||||
@@ -210,12 +221,8 @@ export const build: BuildV2 = async ({
|
|||||||
? `${remixConfigPath}.original${extname(remixConfigPath)}`
|
? `${remixConfigPath}.original${extname(remixConfigPath)}`
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const backupRemixRunDevPath = `${remixRunDevPath}.__vercel_backup`;
|
|
||||||
await fs.rename(remixRunDevPath, backupRemixRunDevPath);
|
|
||||||
await fs.symlink(REMIX_RUN_DEV_PATH, remixRunDevPath);
|
|
||||||
|
|
||||||
// These get populated inside the try/catch below
|
// These get populated inside the try/catch below
|
||||||
let serverBundles: AppConfig['serverBundles'];
|
let serverBundles: ServerBundle[];
|
||||||
const serverBundlesMap = new Map<string, ConfigRoute[]>();
|
const serverBundlesMap = new Map<string, ConfigRoute[]>();
|
||||||
const resolvedConfigsMap = new Map<ConfigRoute, ResolvedRouteConfig>();
|
const resolvedConfigsMap = new Map<ConfigRoute, ResolvedRouteConfig>();
|
||||||
|
|
||||||
@@ -273,16 +280,9 @@ export const build: BuildV2 = async ({
|
|||||||
if (remixConfigPath && renamedRemixConfigPath) {
|
if (remixConfigPath && renamedRemixConfigPath) {
|
||||||
await fs.rename(remixConfigPath, renamedRemixConfigPath);
|
await fs.rename(remixConfigPath, renamedRemixConfigPath);
|
||||||
|
|
||||||
// Figure out if the `remix.config` file is using ESM syntax
|
|
||||||
let isESM = false;
|
|
||||||
try {
|
|
||||||
_require(renamedRemixConfigPath);
|
|
||||||
} catch (err: any) {
|
|
||||||
isESM = err.code === 'ERR_REQUIRE_ESM';
|
|
||||||
}
|
|
||||||
|
|
||||||
let patchedConfig: string;
|
let patchedConfig: string;
|
||||||
if (isESM) {
|
// Figure out if the `remix.config` file is using ESM syntax
|
||||||
|
if (isESM(renamedRemixConfigPath)) {
|
||||||
patchedConfig = `import config from './${basename(
|
patchedConfig = `import config from './${basename(
|
||||||
renamedRemixConfigPath
|
renamedRemixConfigPath
|
||||||
)}';
|
)}';
|
||||||
@@ -340,10 +340,6 @@ module.exports = config;`;
|
|||||||
if (remixConfigWrapped && remixConfigPath && renamedRemixConfigPath) {
|
if (remixConfigWrapped && remixConfigPath && renamedRemixConfigPath) {
|
||||||
await fs.rename(renamedRemixConfigPath, remixConfigPath);
|
await fs.rename(renamedRemixConfigPath, remixConfigPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove `@remix-run/dev` symlink
|
|
||||||
await fs.unlink(remixRunDevPath);
|
|
||||||
await fs.rename(backupRemixRunDevPath, remixRunDevPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to happen before we run NFT to create the Node/Edge functions
|
// This needs to happen before we run NFT to create the Node/Edge functions
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { glob } from '@vercel/build-utils';
|
import { glob } from '@vercel/build-utils';
|
||||||
import { dirname, join, relative } from 'path';
|
import { dirname, join, relative } from 'path';
|
||||||
import { chdirAndReadConfig } from './utils';
|
import { _require, chdirAndReadConfig } from './utils';
|
||||||
import type { PrepareCache } from '@vercel/build-utils';
|
import type { PrepareCache } from '@vercel/build-utils';
|
||||||
|
|
||||||
export const prepareCache: PrepareCache = async ({
|
export const prepareCache: PrepareCache = async ({
|
||||||
@@ -12,7 +12,13 @@ export const prepareCache: PrepareCache = async ({
|
|||||||
const mountpoint = dirname(entrypoint);
|
const mountpoint = dirname(entrypoint);
|
||||||
const entrypointFsDirname = join(workPath, mountpoint);
|
const entrypointFsDirname = join(workPath, mountpoint);
|
||||||
const packageJsonPath = join(entrypointFsDirname, 'package.json');
|
const packageJsonPath = join(entrypointFsDirname, 'package.json');
|
||||||
|
const remixRunDevPath = dirname(
|
||||||
|
_require.resolve('@remix-run/dev/package.json', {
|
||||||
|
paths: [entrypointFsDirname],
|
||||||
|
})
|
||||||
|
);
|
||||||
const remixConfig = await chdirAndReadConfig(
|
const remixConfig = await chdirAndReadConfig(
|
||||||
|
remixRunDevPath,
|
||||||
entrypointFsDirname,
|
entrypointFsDirname,
|
||||||
packageJsonPath
|
packageJsonPath
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import semver from 'semver';
|
||||||
import { existsSync, promises as fs } from 'fs';
|
import { existsSync, promises as fs } from 'fs';
|
||||||
import { basename, dirname, join, relative, resolve, sep } from 'path';
|
import { basename, dirname, join, relative, resolve, sep } from 'path';
|
||||||
import { pathToRegexp, Key } from 'path-to-regexp';
|
import { pathToRegexp, Key } from 'path-to-regexp';
|
||||||
import { debug, spawnAsync } from '@vercel/build-utils';
|
import { debug, spawnAsync } from '@vercel/build-utils';
|
||||||
import { readConfig } from '@remix-run/dev/dist/config';
|
|
||||||
import { walkParentDirs } from '@vercel/build-utils';
|
import { walkParentDirs } from '@vercel/build-utils';
|
||||||
import type {
|
import type {
|
||||||
ConfigRoute,
|
ConfigRoute,
|
||||||
@@ -15,12 +15,15 @@ import type {
|
|||||||
SpawnOptionsExtended,
|
SpawnOptionsExtended,
|
||||||
} from '@vercel/build-utils/dist/fs/run-user-scripts';
|
} from '@vercel/build-utils/dist/fs/run-user-scripts';
|
||||||
|
|
||||||
|
export const _require: typeof require = eval('require');
|
||||||
|
|
||||||
export interface ResolvedNodeRouteConfig {
|
export interface ResolvedNodeRouteConfig {
|
||||||
runtime: 'nodejs';
|
runtime: 'nodejs';
|
||||||
regions?: string[];
|
regions?: string[];
|
||||||
maxDuration?: number;
|
maxDuration?: number;
|
||||||
memory?: number;
|
memory?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResolvedEdgeRouteConfig {
|
export interface ResolvedEdgeRouteConfig {
|
||||||
runtime: 'edge';
|
runtime: 'edge';
|
||||||
regions?: BaseFunctionConfig['regions'];
|
regions?: BaseFunctionConfig['regions'];
|
||||||
@@ -43,8 +46,6 @@ export interface ResolvedRoutePaths {
|
|||||||
rePath: string;
|
rePath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _require: typeof require = eval('require');
|
|
||||||
|
|
||||||
const SPLAT_PATH = '/:params*';
|
const SPLAT_PATH = '/:params*';
|
||||||
|
|
||||||
const entryExts = ['.js', '.jsx', '.ts', '.tsx'];
|
const entryExts = ['.js', '.jsx', '.ts', '.tsx'];
|
||||||
@@ -212,7 +213,14 @@ export function syncEnv(source: NodeJS.ProcessEnv, dest: NodeJS.ProcessEnv) {
|
|||||||
return () => syncEnv(originalDest, dest);
|
return () => syncEnv(originalDest, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function chdirAndReadConfig(dir: string, packageJsonPath: string) {
|
export async function chdirAndReadConfig(
|
||||||
|
remixRunDevPath: string,
|
||||||
|
dir: string,
|
||||||
|
packageJsonPath: string
|
||||||
|
) {
|
||||||
|
const { readConfig }: typeof import('@remix-run/dev/dist/config') =
|
||||||
|
await import(join(remixRunDevPath, 'dist/config.js'));
|
||||||
|
|
||||||
const originalCwd = process.cwd();
|
const originalCwd = process.cwd();
|
||||||
|
|
||||||
// As of Remix v1.14.0, reading the config may trigger adding
|
// As of Remix v1.14.0, reading the config may trigger adding
|
||||||
@@ -249,18 +257,22 @@ export async function chdirAndReadConfig(dir: string, packageJsonPath: string) {
|
|||||||
return remixConfig;
|
return remixConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddDependencyOptions extends SpawnOptionsExtended {
|
export interface AddDependenciesOptions extends SpawnOptionsExtended {
|
||||||
saveDev?: boolean;
|
saveDev?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs `npm i ${name}` / `pnpm i ${name}` / `yarn add ${name}`.
|
* Runs `npm i ${name}` / `pnpm i ${name}` / `yarn add ${name}`.
|
||||||
*/
|
*/
|
||||||
export function addDependency(
|
export function addDependencies(
|
||||||
cliType: CliType,
|
cliType: CliType,
|
||||||
names: string[],
|
names: string[],
|
||||||
opts: AddDependencyOptions = {}
|
opts: AddDependenciesOptions = {}
|
||||||
) {
|
) {
|
||||||
|
debug('Installing additional dependencies:');
|
||||||
|
for (const name of names) {
|
||||||
|
debug(` - ${name}`);
|
||||||
|
}
|
||||||
const args: string[] = [];
|
const args: string[] = [];
|
||||||
if (cliType === 'npm' || cliType === 'pnpm') {
|
if (cliType === 'npm' || cliType === 'pnpm') {
|
||||||
args.push('install');
|
args.push('install');
|
||||||
@@ -277,6 +289,15 @@ export function addDependency(
|
|||||||
return spawnAsync(cliType, args.concat(names), opts);
|
return spawnAsync(cliType, args.concat(names), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveSemverMinMax(
|
||||||
|
min: string,
|
||||||
|
max: string,
|
||||||
|
version: string
|
||||||
|
): string {
|
||||||
|
const floored = semver.intersects(version, `>= ${min}`) ? version : min;
|
||||||
|
return semver.intersects(floored, `<= ${max}`) ? floored : max;
|
||||||
|
}
|
||||||
|
|
||||||
export async function ensureResolvable(
|
export async function ensureResolvable(
|
||||||
start: string,
|
start: string,
|
||||||
base: string,
|
base: string,
|
||||||
@@ -369,3 +390,14 @@ async function ensureSymlink(
|
|||||||
await fs.symlink(relativeTarget, symlinkPath);
|
await fs.symlink(relativeTarget, symlinkPath);
|
||||||
debug(`Created symlink for "${pkgName}"`);
|
debug(`Created symlink for "${pkgName}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isESM(path: string): boolean {
|
||||||
|
// Figure out if the `remix.config` file is using ESM syntax
|
||||||
|
let isESM = false;
|
||||||
|
try {
|
||||||
|
_require(path);
|
||||||
|
} catch (err: any) {
|
||||||
|
isESM = err.code === 'ERR_REQUIRE_ESM';
|
||||||
|
}
|
||||||
|
return isESM;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,14 +10,14 @@
|
|||||||
"start": "remix-serve build"
|
"start": "remix-serve build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/node": "^1.7.4",
|
"@remix-run/node": "1.15.0",
|
||||||
"@remix-run/react": "^1.7.4",
|
"@remix-run/react": "1.15.0",
|
||||||
"@remix-run/serve": "^1.7.4",
|
"@remix-run/serve": "1.15.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@remix-run/dev": "^1.7.4",
|
"@remix-run/dev": "1.15.0",
|
||||||
"@types/react": "^17.0.45",
|
"@types/react": "^17.0.45",
|
||||||
"@types/react-dom": "^17.0.17",
|
"@types/react-dom": "^17.0.17",
|
||||||
"typescript": "^4.6.4"
|
"typescript": "^4.6.4"
|
||||||
|
|||||||
2433
packages/remix/test/fixtures/01-remix-basics/yarn.lock
vendored
2433
packages/remix/test/fixtures/01-remix-basics/yarn.lock
vendored
File diff suppressed because it is too large
Load Diff
@@ -10,13 +10,13 @@
|
|||||||
"start": "remix-serve build"
|
"start": "remix-serve build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/react": "1.5.0",
|
"@remix-run/react": "1.10.0",
|
||||||
"@remix-run/serve": "1.5.0",
|
"@remix-run/serve": "1.10.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@remix-run/dev": "1.5.0",
|
"@remix-run/dev": "1.10.0",
|
||||||
"@types/react": "^17.0.45",
|
"@types/react": "^17.0.45",
|
||||||
"@types/react-dom": "^17.0.17",
|
"@types/react-dom": "^17.0.17",
|
||||||
"typescript": "^4.6.4"
|
"typescript": "^4.6.4"
|
||||||
|
|||||||
4037
packages/remix/test/fixtures/03-with-pnpm/pnpm-lock.yaml
generated
vendored
4037
packages/remix/test/fixtures/03-with-pnpm/pnpm-lock.yaml
generated
vendored
File diff suppressed because it is too large
Load Diff
20
packages/remix/test/unit.resolve-semver-min-max.test.ts
vendored
Normal file
20
packages/remix/test/unit.resolve-semver-min-max.test.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { resolveSemverMinMax } from '../src/utils';
|
||||||
|
|
||||||
|
describe('resolveSemverMinMax()', () => {
|
||||||
|
it.each([
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '0.9.0', expected: '1.0.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '1.0.0', expected: '1.0.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '1.1.0', expected: '1.1.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '1.10.0', expected: '1.10.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '1.15.0', expected: '1.15.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '1.16.0', expected: '1.15.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '^1.12.0', expected: '^1.12.0' },
|
||||||
|
{ min: '1.0.0', max: '1.15.0', version: '0.x.x', expected: '1.0.0' },
|
||||||
|
])(
|
||||||
|
'Should return "$expected" for version "$version" (min=$min, max=$max)',
|
||||||
|
({ min, max, version, expected }) => {
|
||||||
|
const actual = resolveSemverMinMax(min, max, version);
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
996
pnpm-lock.yaml
generated
996
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
6
utils/update-remix-run-dev.js
vendored
6
utils/update-remix-run-dev.js
vendored
@@ -11,14 +11,13 @@ module.exports = async ({ github, context }, newVersion) => {
|
|||||||
const packagePath = path.join(repoRootPath, 'packages', 'remix');
|
const packagePath = path.join(repoRootPath, 'packages', 'remix');
|
||||||
const oldVersion = JSON.parse(
|
const oldVersion = JSON.parse(
|
||||||
fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8')
|
fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8')
|
||||||
).dependencies['@remix-run/dev'];
|
).devDependencies['@remix-run/dev'];
|
||||||
if (newVersion === '') {
|
if (newVersion === '') {
|
||||||
newVersion = execSync('npm view @vercel/remix-run-dev dist-tags.latest', {
|
newVersion = execSync('npm view @vercel/remix-run-dev dist-tags.latest', {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
newVersion = newVersion.trim();
|
newVersion = newVersion.trim();
|
||||||
const branch = `vercel-remix-run-dev-${newVersion.replaceAll('.', '-')}`;
|
|
||||||
|
|
||||||
if (oldVersion === newVersion) {
|
if (oldVersion === newVersion) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
@@ -28,6 +27,7 @@ module.exports = async ({ github, context }, newVersion) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const branch = `vercel-remix-run-dev-${newVersion.replaceAll('.', '-')}`;
|
||||||
if (
|
if (
|
||||||
execSync(`git ls-remote --heads origin ${branch}`, { encoding: 'utf-8' })
|
execSync(`git ls-remote --heads origin ${branch}`, { encoding: 'utf-8' })
|
||||||
.toString()
|
.toString()
|
||||||
@@ -39,7 +39,7 @@ module.exports = async ({ github, context }, newVersion) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execSync(
|
execSync(
|
||||||
`pnpm install @remix-run/dev@npm:@vercel/remix-run-dev@${newVersion} --save-exact --lockfile-only`,
|
`pnpm install @remix-run/dev@npm:@vercel/remix-run-dev@${newVersion} --save-exact --save-dev --lockfile-only`,
|
||||||
{ cwd: packagePath }
|
{ cwd: packagePath }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user