Skip to content

Commit

Permalink
fix: Skip inlining Git LFS placeholders (fix #9714) (#9795)
Browse files Browse the repository at this point in the history
  • Loading branch information
MajorBreakfast committed Aug 24, 2022
1 parent b2c0ee0 commit 9c7e43d
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
4 changes: 3 additions & 1 deletion docs/config/build-options.md
Expand Up @@ -53,8 +53,10 @@ Specify the directory to nest generated assets under (relative to `build.outDir`

Imported or referenced assets that are smaller than this threshold will be inlined as base64 URLs to avoid extra http requests. Set to `0` to disable inlining altogether.

Git LFS placeholders are automatically excluded from inlining because they do not contain the content of the file they represent.

::: tip Note
If you specify `build.lib`, `build.assetsInlineLimit` will be ignored and assets will always be inlined, regardless of file size.
If you specify `build.lib`, `build.assetsInlineLimit` will be ignored and assets will always be inlined, regardless of file size or being a Git LFS placeholder.
:::

## build.cssCodeSplit
Expand Down
2 changes: 2 additions & 0 deletions docs/guide/assets.md
Expand Up @@ -26,6 +26,8 @@ The behavior is similar to webpack's `file-loader`. The difference is that the i

- Assets smaller in bytes than the [`assetsInlineLimit` option](/config/build-options.md#build-assetsinlinelimit) will be inlined as base64 data URLs.

- Git LFS placeholders are automatically excluded from inlining because they do not contain the content of the file they represent. To get inlining, make sure to download the file contents via Git LFS before building.

### Explicit URL Imports

Assets that are not included in the internal list or in `assetsInclude`, can be explicitly imported as a URL using the `?url` suffix. This is useful, for example, to import [Houdini Paint Worklets](https://houdini.how/usage).
Expand Down
18 changes: 17 additions & 1 deletion packages/vite/src/node/plugins/asset.ts
@@ -1,6 +1,7 @@
import path from 'node:path'
import { parse as parseUrl } from 'node:url'
import fs, { promises as fsp } from 'node:fs'
import { Buffer } from 'node:buffer'
import * as mrmime from 'mrmime'
import type {
NormalizedOutputOptions,
Expand All @@ -10,6 +11,7 @@ import type {
RenderedChunk
} from 'rollup'
import MagicString from 'magic-string'
import colors from 'picocolors'
import { toOutputFilePathInString } from '../build'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
Expand Down Expand Up @@ -398,6 +400,13 @@ export function publicFileToBuiltUrl(
return `__VITE_PUBLIC_ASSET__${hash}__`
}

const GIT_LFS_PREFIX = Buffer.from('version https://git-lfs.github.com')
function isGitLfsPlaceholder(content: Buffer): boolean {
if (content.length < GIT_LFS_PREFIX.length) return false
// Check whether the content begins with the characteristic string of Git LFS placeholders
return GIT_LFS_PREFIX.compare(content, 0, GIT_LFS_PREFIX.length) === 0
}

/**
* Register an asset to be emitted as part of the bundle (if necessary)
* and returns the resolved public URL
Expand Down Expand Up @@ -426,8 +435,15 @@ async function fileToBuiltUrl(
config.build.lib ||
(!file.endsWith('.svg') &&
!file.endsWith('.html') &&
content.length < Number(config.build.assetsInlineLimit))
content.length < Number(config.build.assetsInlineLimit) &&
!isGitLfsPlaceholder(content))
) {
if (config.build.lib && isGitLfsPlaceholder(content)) {
config.logger.warn(
colors.yellow(`Inlined file ${id} was not downloaded via Git LFS`)
)
}

const mimeType = mrmime.lookup(file) ?? 'application/octet-stream'
// base64 inlined as a string
url = `data:${mimeType};base64,${content.toString('base64')}`
Expand Down

0 comments on commit 9c7e43d

Please sign in to comment.