How To Develop
Custom Vercel Runtime
01.10.2020
@xf3l1x
f3l1x.io
site
└── index.html
$ vercel
$ vercel
Vercel CLI 20.1.1
? Set up and deploy “~/2020-10-01-vercel-meetup/01-zero-config”? [Y/n] y
? Which scope do you want to deploy to? xorg
? Link to existing project? [y/N] n
? What’s your project’s name? 01-zero-config
? In which directory is your code located? ./
No framework detected. Default Project Settings:
- Build Command: `npm run vercel-build` or `npm run build`
- Output Directory: `public` if it exists, or `.`
- Development Command: None
? Want to override the settings? [y/N] n
🔗 Linked to xorg/01-zero-config (created .vercel and added it to .gitignore)
🔍 Inspect: https://vercel.com/xorg/01-zero-config/lvnj9dd0a [1s]
✅ Production: https://01-zero-config.vercel.app [copied to clipboard] [8s]
📝 Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
💡 To change the domain or build command, go to https://vercel.com/xorg/01-zero-config/settings
site
└── index.html
$ vercel
$ vercel
Vercel CLI 20.1.1
? Set up and deploy “~/2020-10-01-vercel-meetup/01-zero-config”? [Y/n] y
? Which scope do you want to deploy to? xorg
? Link to existing project? [y/N] n
? What’s your project’s name? 01-zero-config
? In which directory is your code located? ./
No framework detected. Default Project Settings:
- Build Command: `npm run vercel-build` or `npm run build`
- Output Directory: `public` if it exists, or `.`
- Development Command: None
? Want to override the settings? [y/N] n
🔗 Linked to xorg/01-zero-config (created .vercel and added it to .gitignore)
🔍 Inspect: https://vercel.com/xorg/01-zero-config/lvnj9dd0a [1s]
✅ Production: https://01-zero-config.vercel.app [copied to clipboard] [8s]
📝 Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
💡 To change the domain or build command, go to https://vercel.com/xorg/01-zero-config/settings
site
└── index.html
$ vercel
$ vercel
Vercel CLI 20.1.1
? Set up and deploy “~/2020-10-01-vercel-meetup/01-zero-config”? [Y/n] y
? Which scope do you want to deploy to? xorg
? Link to existing project? [y/N] n
? What’s your project’s name? 01-zero-config
? In which directory is your code located? ./
No framework detected. Default Project Settings:
- Build Command: `npm run vercel-build` or `npm run build`
- Output Directory: `public` if it exists, or `.`
- Development Command: None
? Want to override the settings? [y/N] n
🔗 Linked to xorg/01-zero-config (created .vercel and added it to .gitignore)
🔍 Inspect: https://vercel.com/xorg/01-zero-config/lvnj9dd0a [1s]
✅ Production: https://01-zero-config.vercel.app [copied to clipboard] [8s]
📝 Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
💡 To change the domain or build command, go to https://vercel.com/xorg/01-zero-config/settings
site
└── index.html
$ vercel
$ vercel
Vercel CLI 20.1.1
? Set up and deploy “~/2020-10-01-vercel-meetup/01-zero-config”? [Y/n] y
? Which scope do you want to deploy to? xorg
? Link to existing project? [y/N] n
? What’s your project’s name? 01-zero-config
? In which directory is your code located? ./
No framework detected. Default Project Settings:
- Build Command: `npm run vercel-build` or `npm run build`
- Output Directory: `public` if it exists, or `.`
- Development Command: None
? Want to override the settings? [y/N] n
🔗 Linked to xorg/01-zero-config (created .vercel and added it to .gitignore)
🔍 Inspect: https://vercel.com/xorg/01-zero-config/lvnj9dd0a [1s]
✅ Production: https://01-zero-config.vercel.app [copied to clipboard] [8s]
📝 Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
💡 To change the domain or build command, go to https://vercel.com/xorg/01-zero-config/settings
site
├── index.html
├── index.php
├── package.json
└── vercel.json
$ vercel
{
"builds": [
{ "src": "index.html", "use": "@vercel/static" },
{ "src": "package.json", "use": "@vercel/static-build" },
{ "src": "index.php", "use": "vercel-php" }
]
}
{ CODE }
{ CODE }
▲ RUNTIME
▲ BUILD PHASE
site
├── index.html
├── index.php
├── package.json
└── vercel.json
{
"builds": [{
"src": "index.html",
"use": "@vercel/static"
}]
}
$ vercel
builder1.build(ctx)
index.html dist/main.css dist/app.js
/api/users /api/comments
STATIC FILES
LAMBDAS
builderN.build(ctx)
Builders
@vercel/static
@vercel/static-build
@vercel/node
@vercel/go
@vercel/python
@vercel/ruby
officials
community
vercel-bash
vercel-deno
vercel-php
now-rust
vercel-sapper
@nuxtjs/vercel-builder
Builders
@vercel/static
@vercel/static-build
@vercel/node
@vercel/go
@vercel/python
@vercel/ruby
officials
community
vercel-bash
vercel-deno
vercel-php
now-rust
vercel-sapper
@nuxtjs/vercel-builder
MD → HTML
new stuff
challenge
learn sth
have fun
interface Runtime {
version: number;
build: (options: BuildOptions) => Promise<BuildResult>;
analyze?: (options: AnalyzeOptions) => Promise<string>;
prepareCache?: (options: PrepareCacheOptions) => Promise<CacheOutputs>;
shouldServe?: (options: ShouldServeOptions) => Promise<boolean>;
startDevServer?: (
options: StartDevServerOptions
) => Promise<StartDevServerResult>;
}
interface Runtime {
build: (options: BuildOptions) => Promise<BuildResult>;
}
[file structure]
runtime
├── src
│ └── index.ts
├── package.json
├── tsconfig.json
└── README.md
[package.json]
{
"name": "vercel-md",
"description": "Markdown Runtime for Vercel platform",
"version": "0.0.1",
"license": "MIT",
"main": "./dist/index.js",
"files": [
"dist"
],
"dependencies": {
"markdown-it": "^11.0.1"
},
"devDependencies": {
"@types/node": "^14.0.14",
"@vercel/build-utils": "^2.4.0",
"typescript": "^4.0.2"
}
}
[src/index.ts]
import { BuildOptions } from "@vercel/build-utils";
export async function build(options: BuildOptions): Promise<any> {
console.log(options);
};
site
├── index.md
└── vercel.json
[src/index.ts]
import { FileBlob, BuildOptions } from "@vercel/build-utils";
import markdownit from 'markdown-it';
export async function build({ files, entrypoint }: BuildOptions): Promise<any> {
const file = await FileBlob.fromStream({
stream: files[entrypoint].toStream(),
});
const md = new markdownit();
const result = new FileBlob({
data: md.render(file.data.toString())
});
const replacedEntrypoint = entrypoint.replace(/\.[^.]+$/, '.html');
return { [replacedEntrypoint]: result };
};
[src/index.ts]
import { FileBlob, BuildOptions } from "@vercel/build-utils";
import markdownit from 'markdown-it';
export async function build({ files, entrypoint }: BuildOptions): Promise<any> {
const file = await FileBlob.fromStream({
stream: files[entrypoint].toStream(),
});
const md = new markdownit();
const result = new FileBlob({
data: md.render(file.data.toString())
});
const replacedEntrypoint = entrypoint.replace(/\.[^.]+$/, '.html');
return { [replacedEntrypoint]: result };
};
[src/index.ts]
import { FileBlob, BuildOptions } from "@vercel/build-utils";
import markdownit from 'markdown-it';
export async function build({ files, entrypoint }: BuildOptions): Promise<any> {
const file = await FileBlob.fromStream({
stream: files[entrypoint].toStream(),
});
const md = new markdownit();
const result = new FileBlob({
data: md.render(file.data.toString())
});
const replacedEntrypoint = entrypoint.replace(/\.[^.]+$/, '.html');
return { [replacedEntrypoint]: result };
};
import { FileBlob, BuildOptions } from "@vercel/build-utils";
import markdownit from 'markdown-it';
export async function build({ files, entrypoint }: BuildOptions): Promise<any> {
const file = await FileBlob.fromStream({
stream: files[entrypoint].toStream(),
});
const md = new markdownit();
const result = new FileBlob({
data: md.render(file.data.toString())
});
const replacedEntrypoint = entrypoint.replace(/\.[^.]+$/, '.html');
return { [replacedEntrypoint]: result };
};
index.md → index.html
[src/index.ts]
[src/index.ts]
import { FileBlob, BuildOptions } from "@vercel/build-utils";
import markdownit from 'markdown-it';
export async function build({ files, entrypoint }: BuildOptions): Promise<any> {
const file = await FileBlob.fromStream({
stream: files[entrypoint].toStream(),
});
const md = new markdownit();
const result = new FileBlob({
data: md.render(file.data.toString())
});
const replacedEntrypoint = entrypoint.replace(/\.[^.]+$/, '.html');
return { [replacedEntrypoint]: result };
};
[publishing]
npm publish
{
"builds": [
{ "src": "*.md", "use": "vercel-md" }
]
}
speedup workflow
take challenges
explore & conquer
have fun
@xf3l1x
f3l1x.io