Skip to content

Commit

Permalink
feat: add assetsBase config to support serving assets from CDN
Browse files Browse the repository at this point in the history
refactor: rename `publicPath` option to `assetsBase`
  • Loading branch information
nilennoct committed Nov 12, 2024
1 parent d200f4e commit 0062073
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 24 deletions.
19 changes: 19 additions & 0 deletions docs/en/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- Type: `string`
- Default: `/assets/`

The base URL the site assets will be deployed at. You will need to set this if you plan to deploy your site assets to CDN. It is similar to `publicPath` in other module bundler.

The `assetsBase` is configured to `${base}assets/` by default. It should always start with a slash or a valid protocol, and always end with a slash.

::: warning
This option only takes effect in production mode.
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## Routing

### cleanUrls
Expand Down
19 changes: 19 additions & 0 deletions docs/es/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- Tipo: `string`
- Predeterminado: `/assets/`

La URL base donde se desplegarán los activos del sitio. Necesitarás configurar esto si planeas desplegar los activos de tu sitio en un CDN. Es similar a `publicPath` en otros empaquetadores de módulos.

El `assetsBase` se configura como `${base}assets/` por defecto. Siempre debe comenzar con una barra inclinada o un protocolo válido y siempre terminar con una barra inclinada.

::: warning
Esta opción solo tiene efecto en modo producción.
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## Roteamento {#routing}

### cleanUrls
Expand Down
19 changes: 19 additions & 0 deletions docs/ko/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- 타입: `string`
- 기본값: `/assets/`

사이트 에셋이 배포될 기본 URL입니다. 사이트 에셋을 CDN에 배포할 계획이라면 이 값을 설정해야 합니다. 이는 다른 모듈 번들러의 `publicPath`와 유사합니다.

`assetsBase`는 기본적으로 `${base}assets/`로 구성됩니다. 항상 슬래시로 시작하거나 유효한 프로토콜로 시작해야 하며, 항상 슬래시로 끝나야 합니다.

::: warning
이 옵션은 프로덕션 모드에서만 적용됩니다.
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## 라우팅 {#routing}

### cleanUrls
Expand Down
19 changes: 19 additions & 0 deletions docs/pt/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- Tipo: `string`
- Padrão: `/assets/`

A URL base onde os recursos do site serão implantados. Você precisará configurar isto se planeja implantar os recursos do seu site em uma CDN. É semelhante a `publicPath` em outros empacotadores de módulos.

O `assetsBase` é configurado como `${base}assets/` por padrão. Deve sempre começar com uma barra ou um protocolo válido, e sempre terminar com uma barra.

::: warning
Esta opção só tem efeito no modo de produção.
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## Roteamento {#routing}

### cleanUrls
Expand Down
19 changes: 19 additions & 0 deletions docs/ru/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- Тип: `string`
- По умолчанию: `/assets/`

Базовый URL, по которому будут размещены ресурсы сайта. Вам нужно будет установить это значение, если вы планируете размещать ресурсы вашего сайта на CDN. Это похоже на `publicPath` в других сборщиках модулей.

По умолчанию `assetsBase` настроен на `${base}assets/`. Оно всегда должно начинаться с косой черты или действительного протокола и всегда заканчиваться косой чертой.

::: warning
Этот параметр действует только в режиме производства.
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## Маршрутизация {#routing}

### cleanUrls {#cleanurls}
Expand Down
19 changes: 19 additions & 0 deletions docs/zh/reference/site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,25 @@ export default {
}
```

### assetsBase

- 类型: `string`
- 默认值: `/assets/`

站点资源将被部署的 base URL。如果您计划将站点资源部署到 CDN,则需要设置此项。它类似于其他模块打包器中的 `publicPath`

`assetsBase` 默认配置为 `${base}assets/`。它应该始终以斜杠或有效协议开头,并始终以斜杠结尾。

::: warning
此选项仅在生产模式下生效。
:::

```ts
export default {
assetsBase: 'https://cdn.example.com/assets/bar/'
}
```

## 路由 {#routing}

### cleanUrls
Expand Down
4 changes: 3 additions & 1 deletion src/client/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export function pathToFile(path: string) {
// /foo/bar.html -> ./foo_bar.md
if (inBrowser) {
const base = import.meta.env.BASE_URL
const assetsBase =
import.meta.env.VITE_VP_ASSETS_BASE ?? `${base}${__ASSETS_DIR__}/`
pagePath =
sanitizeFileName(
pagePath.slice(base.length).replace(/\//g, '_') || 'index'
Expand All @@ -61,7 +63,7 @@ export function pathToFile(path: string) {
pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()]
}
if (!pageHash) return null
pagePath = `${base}${__ASSETS_DIR__}/${pagePath}.${pageHash}.js`
pagePath = `${assetsBase}${pagePath}.${pageHash}.js`
} else {
// ssr build uses much simpler name mapping
pagePath = `./${sanitizeFileName(
Expand Down
21 changes: 18 additions & 3 deletions src/node/build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import pMap from 'p-map'
import { packageDirectorySync } from 'pkg-dir'
import { rimraf } from 'rimraf'
import type { BuildOptions, Rollup } from 'vite'
import { resolveConfig, type SiteConfig } from '../config'
import { normalizeBaseUrl, resolveConfig, type SiteConfig } from '../config'
import { clearCache } from '../markdownToVue'
import { slash, type HeadConfig } from '../shared'
import { deserializeFunctions, serializeFunctions } from '../utils/fnSerialize'
import {
getDefaultAssetsBase,
isDefaultAssetsBase,
normalizeAssetUrl
} from '../utils/assetsBase'
import { task } from '../utils/task'
import { bundle } from './bundle'
import { generateSitemap } from './generateSitemap'
Expand All @@ -30,8 +35,17 @@ export async function build(
const unlinkVue = linkVue()

if (buildOptions.base) {
siteConfig.site.base = buildOptions.base
const shouldUpdateAssetsBase = isDefaultAssetsBase(
siteConfig.site.base,
siteConfig.site.assetsBase
)

siteConfig.site.base = normalizeBaseUrl(buildOptions.base)
delete buildOptions.base

if (shouldUpdateAssetsBase) {
siteConfig.site.assetsBase = getDefaultAssetsBase(siteConfig.site.base)
}
}

if (buildOptions.mpa) {
Expand All @@ -44,6 +58,7 @@ export async function build(
delete buildOptions.outDir
}

process.env.VITE_VP_ASSETS_BASE = siteConfig.site.assetsBase
try {
const { clientResult, serverResult, pageToHashMap } = await bundle(
siteConfig,
Expand Down Expand Up @@ -77,7 +92,7 @@ export async function build(
.filter(
(chunk) => chunk.type === 'asset' && !chunk.fileName.endsWith('.css')
)
.map((asset) => siteConfig.site.base + asset.fileName)
.map((asset) => normalizeAssetUrl(siteConfig.site, asset.fileName))

// default theme special handling: inject font preload
// custom themes will need to use `transformHead` to inject this
Expand Down
19 changes: 19 additions & 0 deletions src/node/build/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { APP_PATH } from '../alias'
import type { SiteConfig } from '../config'
import { createVitePressPlugin } from '../plugin'
import { escapeRegExp, sanitizeFileName, slash } from '../shared'
import { normalizeAssetUrl } from '../utils/assetsBase'
import { task } from '../utils/task'
import { buildMPAClient } from './buildMPAClient'

Expand Down Expand Up @@ -83,6 +84,24 @@ export async function bundle(
ssr: {
noExternal: ['vitepress', '@docsearch/css']
},
experimental: {
renderBuiltUrl: (filename, type) => {
let result: string | undefined

if (type.type === 'asset') {
result = normalizeAssetUrl(config.site, filename)
}

if (config.vite?.experimental?.renderBuiltUrl) {
return (
config.vite.experimental.renderBuiltUrl(result ?? filename, type) ??
result
)
}

return result
}
},
build: {
...options,
emptyOutDir: true,
Expand Down
20 changes: 16 additions & 4 deletions src/node/build/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
type PageData,
type SSGContext
} from '../shared'
import { normalizeAssetUrl } from '../utils/assetsBase'

export async function renderPage(
render: (path: string) => Promise<SSGContext>,
Expand Down Expand Up @@ -72,7 +73,10 @@ export async function renderPage(
const title: string = createTitle(siteData, pageData)
const description: string = pageData.description || siteData.description
const stylesheetLink = cssChunk
? `<link rel="preload stylesheet" href="${siteData.base}${cssChunk.fileName}" as="style">`
? `<link rel="preload stylesheet" href="${normalizeAssetUrl(
siteData,
cssChunk.fileName
)}" as="style">`
: ''

let preloadLinks =
Expand Down Expand Up @@ -104,7 +108,9 @@ export async function renderPage(
{
rel,
// don't add base to external urls
href: (EXTERNAL_URL_RE.test(file) ? '' : siteData.base) + file
href: EXTERNAL_URL_RE.test(file)
? file
: normalizeAssetUrl(siteData, file)
}
])

Expand Down Expand Up @@ -148,7 +154,10 @@ export async function renderPage(
inlinedScript = `<script type="module">${matchingChunk.code}</script>`
fs.removeSync(path.resolve(config.outDir, matchingChunk.fileName))
} else {
inlinedScript = `<script type="module" src="${siteData.base}${matchingChunk.fileName}"></script>`
inlinedScript = `<script type="module" src="${normalizeAssetUrl(
siteData,
matchingChunk.fileName
)}"></script>`
}
}
}
Expand Down Expand Up @@ -176,7 +185,10 @@ export async function renderPage(
${metadataScript.inHead ? metadataScript.html : ''}
${
appChunk
? `<script type="module" src="${siteData.base}${appChunk.fileName}"></script>`
? `<script type="module" src="${normalizeAssetUrl(
siteData,
appChunk.fileName
)}"></script>`
: ''
}
${await renderHead(head)}
Expand Down
16 changes: 14 additions & 2 deletions src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
type SiteData
} from './shared'
import type { RawConfigExports, SiteConfig, UserConfig } from './siteConfig'
import { getDefaultAssetsBase, normalizeAssetsBase } from './utils/assetsBase'

export { resolvePages } from './plugins/dynamicRoutesPlugin'
export * from './siteConfig'
Expand Down Expand Up @@ -72,7 +73,7 @@ export async function resolveConfig(
prefix: '[vitepress]',
allowClearScreen: userConfig.vite?.clearScreen
})
const site = await resolveSiteData(root, userConfig)
const site = await resolveSiteData(root, userConfig, command, mode)
const srcDir = normalizePath(path.resolve(root, userConfig.srcDir || '.'))
const assetsDir = userConfig.assetsDir
? slash(userConfig.assetsDir).replace(/^\.?\/|\/$/g, '')
Expand Down Expand Up @@ -238,13 +239,20 @@ export async function resolveSiteData(
): Promise<SiteData> {
userConfig = userConfig || (await resolveUserConfig(root, command, mode))[0]

const base = userConfig.base ? normalizeBaseUrl(userConfig.base) : '/'
const assetsBase =
mode === 'production' && userConfig.assetsBase
? normalizeAssetsBase(userConfig.assetsBase)
: getDefaultAssetsBase(base)

return {
lang: userConfig.lang || 'en-US',
dir: userConfig.dir || 'ltr',
title: userConfig.title || 'VitePress',
titleTemplate: userConfig.titleTemplate,
description: userConfig.description || 'A VitePress site',
base: userConfig.base ? userConfig.base.replace(/([^/])$/, '$1/') : '/',
base,
assetsBase,
head: resolveSiteDataHead(userConfig),
router: {
prefetchLinks: userConfig.router?.prefetchLinks ?? true
Expand Down Expand Up @@ -300,3 +308,7 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {

return head
}

export function normalizeBaseUrl(baseUrl: string) {
return baseUrl.replace(/^([^/])/, '/$1').replace(/([^/])$/, '$1/')
}
Loading

0 comments on commit 0062073

Please sign in to comment.