I noticed that the framework version was not being printed on deployments in a monorepo. Turns out the framework detection logic was happening at the root of the monorepo, instead of the project directory.
- Removes all the legacy `flags`
- Renames the new `variants` to `flags`
Neither the legacy flags, nor the new variants were exposed to anyone, except for the type in build-utils, so there shouldn't be any issues removing/renaming them.
### 🧐 What's in there?
With the recent release of [`@vercel/speed-insights`](https://vercel.com/docs/speed-insights/package) own package (like [`@vercel/analytics`](https://vercel.com/docs/analytics/package)), it's time to encourage users to migrate.
With the availability of `@vercel/speed-insights`, users will have to opt-in explicitly by installing the package. Their benefit is a better and fine-grained control of the reporting (in particular, per-application sample rate).
### ❗ Note to reviewers
I used `console.warn` and hope it will stands out in the build logs. I'm happy to use anything else if you have better suggestions.
There's also a deprecation warning in Next.js, which covers a related but slightly different case, when users explicitly pass analyticsId in their configuration. https://github.com/vercel/next.js/pull/60677
Enables the symlink optimization that currently exists for `Lambda`
instances, but now for `EdgeFunction` instances as well. This will be
particularly beneficial for Remix applications which use edge functions
for many routes, since they will now all be represented by the same
underling function in production.
---------
Co-authored-by: Sean Massa <EndangeredMassa@gmail.com>
Some of our tests take quite some time to run and occasionally timeout when accessing https://yarnpkg.com/. We decided to make sure there is a lockfile for this _and_ just move over to `npm`. Shifting the `packages/cli` fixtures over in this PR.
I possibly missed one but I changed the install commands in tests and ran
* pnpm test
* pnpm test-unit
* pnpm test-dev
* pnpm test-e2e
When the repo is linked to Vercel with `vc link --repo`, the `vc build` command should be invoked from the project subdirectory (otherwise the project selector is displayed). The output directory is at `<projectRoot>/.vercel/output` instead of at the repo root.
When a project has a `.npmrc` containing `use-node-version`, package managers (notably `pnpm`) will download the specified Node.js version. This is not the correct way as it can lead to `pnpm` downloading Node.js 18 or newer which depends on a version of GLIBC that is not present in the current AWS image. The proper way is to set the `"engines"` in the `package.json`.
<img width="468" alt="image" src="https://github.com/vercel/vercel/assets/97262/0974cf05-6a11-4d95-88e8-13affc4aad2a">
Discussion: https://github.com/orgs/vercel/discussions/2436
A few commands were still checking on `--cwd` explicitly, which is incorrect since the entrypoint file already handles the directory change.
The new `client.cwd` property is a helper to make writing tests easier. Tests no longer need to `chdir()` explicitly and then revert afterwards.
As reported https://github.com/vercel/vercel/discussions/9648, `vc build` does not honor the `--local-config <file>` option.
`vc build` will only load the `vercel.json` (or `now.json`) in the `workPath` which is based on the `rootDirctory`.
If `--local-config` is specified in the command line arguments, then it should take precedence.
This PR changes the way cron jobs are being created in the build output
API. This is my first time contributing here. If you see something
unusual, let me know.
✅ Good for review
Our goal is to:
- Allow creating cron jobs via the `crons` property of `vercel.json` for
end users
- Allow framework authors to create cron jobs on Vercel via the `crons`
property of the Build Output API configuration
---
As you can see, we removed the previous implementation where cron jobs
could be configured at the function code level (export const cron = ""),
on top of vercel.json `functions` property. Here's why:
- All frameworks would have to implement the configure at the function
code level
- Not all frameworks can easily map a path to a specific function
(example: SvelteKit) and would have to bail on bundling functions inside
the same lambda
- Configuring a path + scheduler provides a better mapping of what cron
jobs are as of today: API routes on a schedule and not functions on a
schedule
- Dynamic routes Cron Jobs will be supported:
/api/crons/sync-slack-team/230
- Query parameters will be supported support:
/api/crons/sync-slack-team/230?secret=32k13l2k13lk21 (= securing cron
jobs v0)
- 100% frameworks compatibility from day one
Next.js and other frameworks may choose to implement their own cron jobs
feature that will then need to be configured through the `crons`
property of `config.json` (build output API).
cc @timneutkens @Rich-Harris
Internal thread:
https://vercel.slack.com/archives/C04DWF5HB6K/p1676366892714349
1. `commandForIgnoringBuildStep` should be run at the project directory level not the monorepo root level
2. Simplifying the `installCommand` because doesn't need the relative root unless it is `npm`
This PR:
- updates `packages/frameworks` to have most supported frameworks specify which dependency version should reflect the overall framework version
- updates `packages/fs-detectors` to allow framework detection that returns the full `Framework` record instead of just the slug
- updates `packages/next` to return the detected Next.js version in the build result
- updates `packages/cli` to leverage these changes so that `vc build` can add `framework: { version: string; }` to `config.json` output
The result is that Build Output API and supported frameworks will return their framework version in the build result of `vc build` when possible, which is used by the build container when creating the deployment. The dashboard later retrieves this value to display in richer deployment outputs.
Supports:
- https://github.com/vercel/api/pull/15601
- https://github.com/vercel/front/pull/18319
---
With the related build container updates, we get to see Next.js version in the build output. You'll see this with BOA+Prebuilt or a normal deploy:
<img width="1228" alt="Screen Shot 2022-12-09 at 2 48 12 PM" src="https://user-images.githubusercontent.com/41545/206793639-f9cd3bdf-b822-45dd-9564-95b94994271d.png">
---
### The Path to this PR
I went through all the supported frameworks and figured out how to best determine their versions. For most of them, we can check a known dependency's installed version number.
We can get most of the way only checking npm. For a handful, we'd have to support Go/Ruby/Rust/Whatever dependencies.
I started with a more complex method signature to allow for later expansion without changing the signature. It looked like this, in practice:
```
async getVersion(dependencies: DependencyMap) => depedencies['next']
```
However, after checking all currently supported frameworks, I don't think this will end up being necessary. It also has the constraint that all dependencies have to be gathered and presented to the function even though it only needs to check for one or two. That's not a huge deal if we have them already where we need them, but we don't. We could use a variant here where this function does its own lookups, but this seemed unnecessary and would beg for duplication and small variances that could cause bugs.
Further, if we only look at `package.json`, we're going to either see a specific version of a version range. To be precise, we have to look at the installed version of the package. That means checking one of the various types of lockfiles that can exist or poking into node_modules.
If we poke into node_modules to detect the installed version, we introduce another point where Yarn 3 (default mode) will not be supported. If we read lockfiles, we have to potentially parse `npm`, `pnpm`, and `yarn` lockfiles.
If we use `npm ls <package-name>`, that also fails in Yarn 3 (default mode). We could accept that and go forward anyway, which would look like:
```
const args = `ls ${packageName} --depth=0 --json`.split(' ');
const { stdout } = await execa('npm', args, { cwd });
const regex = new RegExp(String.raw`${packageName}@([\.\d]+)`);
const matches = stdout.match(regex);
if (matches) {
return matches[1];
}
```
But it turns out there's a `--json` option! That's what I ended up using, for now.
We could explore the lockfile route more, but after some initial digging, it' non-trivial. There are 3 main lockfiles we'd want to check for (npm, pnpm, and yarn) and there are different lockfile versions that put necessary data in different places. I looked for existing tools that parse this, but I didn't find any. We could certainly go down this path, but the effort doesn't seem worth it when `npm ls` gets us really close.
---
### Follow-up Versioning
Now that we know how to determine version per framework, we can vary configuration by version. In a future PR, we could allow a given value to vary by version number:
```
name: (version) => {
if (semver.gt(version, '9.8.7')) {
return 'some-framework-2''
}
return 'some-framework';
}
```
However, it may still be easier to differentiate significant versions by adding multiple entries in the list.